Core API

Requests API reference for AI agent approvals

Learn how to create, inspect, and cancel Contro1 requests for approvals, clarifications, and escalations.

The Requests API is the core surface agents use to ask humans for approval, clarification, or escalation in production.

Key takeaways

  • Three interaction types cover most cases: approval (approve/reject + comment), yes_no, and free_text.
  • required_role narrows who can claim a request; metadata rides through to the callback for correlation.
  • risk_level, policy_trigger, policy_context, approval_comment_required, and approval_requirements are optional decision-context fields for audit-ready oversight and policy-engine integrations.
  • external_request_id gives you idempotency - the same key never creates two requests.
  • Keep the question short and decisive; put evidence in context.

Request fields that matter most

  • type defines the interaction model: yes_no, free_text, or approval
  • question is the direct decision prompt shown to the operator
  • context gives the supporting facts a human needs to answer quickly
  • required_role narrows who can claim or answer the request
  • metadata returns workflow correlation data in the callback
  • risk_level, policy_trigger, policy_context, and approval_requirements explain why this human decision is required
  • external_request_id is the idempotency key - retries with the same value return the original request
  • correlation_id groups related requests and audit records into one case timeline

Base URL

Use the API host for runtime traffic. The canonical base URL is https://api.contro1.com/api/centcom/v1.

The marketing site remains at https://contro1.com, but production create/get/delete calls should target api.contro1.com.

Operational guidance

Keep the question short and decisive.

Put policy detail, transaction facts, or execution context in the context field so the operator can understand the risk without opening another system.

Send policy_trigger when your own policy logic decides a human must review. Send policy_context when any policy source, risk service, rules engine, or framework tells you why review is required. This can be Microsoft AGT, OPA, Cedar, a homegrown risk classifier, a YAML rule file, or simple application code.

Contro1 records the policy evidence, routes the human decision, enforces reviewer comment rules, and returns the signed outcome. It does not need to own your policy logic.

For US AI governance programs, these optional fields help preserve NIST-style risk management evidence without moving impact assessments, bias testing, notices, or legal classification into Contro1.

Treat timeouts as real outcomes. An unanswered request is not an approval - it is a decision your workflow must still handle.

Policy context is not Microsoft-only

policy_context is a general evidence envelope for the reason a human was required. Use it with any system that evaluates risk or policy before the agent acts.

If you do not run a formal policy engine yet, you can still send a source such as custom_rules, finance_service, support_risk_classifier, internal_policy, opa, cedar, or workflow_guard. The important part is that future auditors can see which rule, version, and reason caused the human review.

custom-policy-context.json
{
  "risk_level": "high",
  "policy_trigger": "Vendor transfers above $10,000 require finance approval.",
  "policy_context": {
    "source": "custom_rules",
    "policy_name": "finance-transfer-controls",
    "rule_id": "vendor-transfer-over-10000",
    "rule_reason": "Vendor transfers above $10,000 require finance approval.",
    "policy_version": "git:8f42c1a",
    "enforcement": "require_approval"
  },
  "approval_comment_required": true
}

Decision context fields

Decision context fields are optional. Existing clients can ignore them, and low-risk audit-only actions should still use logAction instead of creating an approval request.

Use them when the customer runtime already decided a human must review the action. This makes the request easier to audit without moving policy logic into Contro1.

The same fields also fit governance evidence: risk_level maps to risk classification, policy_trigger explains why review was required, policy_context preserves the policy source and rule, approval_requirements captures expected reviewers, and correlation_id/case_id connects records to a broader case or AI use case inventory.

  • risk_level: customer-assessed risk: low, medium, high, or critical
  • policy_trigger: short human-readable policy reason, such as "Payments above $10,000 require finance approval"
  • policy_context: policy source, policy name, rule id, rule reason, version, and enforcement mode from an external policy engine
  • approval_comment_required: require a reviewer comment even when the risk level is not high or critical
  • approval_requirements: expected approval count and roles for audit context
  • approval_policy: optional enforced quorum, role, separation-of-duties, and fail-closed behavior
  • decision_context.reviewer_mappings: optional evidence of requested external roles, mapped reviewers, fallback reviewers, and mapping warnings
  • reason/comment: required on high or critical risk approval responses, when approval_comment_required is true, and on every rejection

Control Map preview

Before creating a request, agents can call POST /api/centcom/v1/requests/control-map with the same approval policy shape to preview whether routing is currently satisfiable.

Control Map returns known departments, requested external role mappings, unmapped roles, on-shift capacity, fallback reviewers, and warnings such as insufficient distinct approvers.

Use this to tell admins exactly what is missing: for example, CFO is not mapped yet, or two-person approval cannot be satisfied with the current shift.

If a real request is sent with an unknown external role, Contro1 still has an admin fallback: admins see a routing setup popup that asks which organization members should receive that role. Once the admin saves the mapping, future requests for that role route automatically.

A single member can hold multiple internal roles in the database, and the external role mapping popup can map multiple external roles to the same person. Separation-of-duties still checks for distinct approvers when the policy requires it.

control-map-request.json
{
  "type": "approval",
  "question": "Preview routing for invoice transfer",
  "context": "Do not create a request yet.",
  "approval_policy": {
    "mode": "threshold",
    "required_approvals": 2,
    "required_roles": ["finance", "cfo"],
    "separation_of_duties": true
  },
  "approval_requirements": {
    "required_approvals": 2,
    "must_include_roles": ["cfo"]
  }
}

Response fields

Create and get responses include both the operational state machine and protocol adapter fields so SDKs can consume one shape across runtimes.

routing_source explains where routing came from. api_key_default means the request used the default routing configured for the API key in Settings -> APIs & Webhooks unless the request body supplied an override.

  • state is the internal lifecycle state, such as queued, assigned, viewed, callback_pending, callback_delivered, or closed
  • status is the protocol-friendly outcome, such as pending, approved, denied, cancelled, or timed_out
  • request_type maps the request into the protocol model: approval, input, decision, or review
  • continuation_mode describes how the caller resumes: decision or instruction
  • structured_response contains the operator decision payload
  • risk_level, policy_trigger, policy_context, approval_comment_required, and decision_context are returned when they were supplied on the request
  • protocol_response is the canonical Contro1 Integration Protocol response, included for SDK and connector adapters

Cases and audit records

Use external_request_id for one external action and idempotency. Use correlation_id (shown in the dashboard as Case ID) for the broader business case. Use in_reply_to when a new request or audit record directly follows a prior Contro1 item.

Every request and audit record that shares a correlation_id appears together in one case timeline. In the UI, a single-item case shows the Case ID; multi-item cases show an Open case button.

Use audit records for actions that do not need a human before execution, but still need durable evidence in the same timeline.

Audit records and cases reference

Frequently asked questions

What is the difference between approval and yes_no?

approval is better for higher-risk actions because it supports approve or reject semantics and a comment, while yes_no is better for simpler binary prompts.

Should every action become an approval request?

No. If the agent is already authorized to act, use logAction or POST /audit-records. Create a request only when a human must decide before the workflow continues.

Should I always use required_role?

Use it whenever the decision has ownership boundaries, such as HR, finance, security, or management approvals.

How do I stop the same request from being created twice?

Send a stable external_request_id. Retries that reuse the same value return the original request instead of creating a new one.

Can I cancel a request in flight?

Yes. Call DELETE /api/centcom/v1/requests/{id} - the operator view closes and your callback receives a cancelled status.