Create an approval request
/v1/requestsSubmits one proposed tool call. The provider derives instance identity from the credential. The response may already contain a terminal decision.
An idempotency key identifies one execution attempt. Repeating the same input with the same key returns the existing request in its current state. Reusing the key with different input returns an idempotency conflict. Keys are scoped to the authenticated instance and operation.
The provider must retain the request and key whilst the request is pending and for at least seven days (168 hours) after it becomes terminal, measured from decision.decided_at. If the request is retained longer, its key must be retained for the same period. For a request with a notification, retain both until at least 24 hours after delivery is acknowledged or retries end, if that is later. Submission retries do not extend retention.
Delivery is inherited from the instance and cannot be supplied on a request. Recording a terminal outcome and its notification must be durable together when delivery is configured, including immediate decisions. Replaying creation does not create another notification.
Instance Credential
An opaque credential bound to exactly one instance. Cannot manage instances.
Parameters
| Field | Type | Description |
|---|---|---|
Idempotency-Keyrequired | header · string | An opaque key for safely retrying this operation. Generate it before the first submission and reuse it only with the same input. See idempotency and retries and retention periods. |
Request body
application/json · required
The exact tool arguments. Their keys and nested JSON values retain their original spelling and types.
The agent's explanation, presented as a claim from the agent.
Runtime information observed by the adapter. Does not establish identity.
View complete schema and constraints
{
"type": "object",
"additionalProperties": false,
"required": [
"tool",
"arguments",
"timeout"
],
"properties": {
"tool": {
"$ref": "#/components/schemas/ToolName"
},
"arguments": {
"$ref": "#/components/schemas/ToolArguments"
},
"timeout": {
"$ref": "#/components/schemas/Duration"
},
"agent_reasoning": {
"$ref": "#/components/schemas/AgentReasoning"
},
"context": {
"$ref": "#/components/schemas/RuntimeContext"
}
}
}{
"tool": "issue_refund",
"arguments": {
"payment_id": "payment_123",
"amount": 4900,
"currency": "GBP"
},
"timeout": "30m"
}Responses
| Status | Meaning | Body |
|---|---|---|
200 | The request in its current state, including on an idempotent replay. | ApprovalRequest |
201 | The new request, pending or already terminal. | ApprovalRequest |
400 | The request is malformed or a field is invalid. Code invalid_webhook_url identifies an unsafe or malformed receiver URL. Code unsupported_delivery_type identifies an unsupported transport, including webhook when the provider supports only synchronous mode. | ErrorResponse |
401 | The credential is missing, expired, revoked or otherwise invalid. | ErrorResponse |
403 | The credential does not permit the operation or access to this resource. | ErrorResponse |
409 | The operation conflicts with existing state. Code idempotency_conflict means the key was used with different input. Code already_terminal means the request was approved, denied or expired before cancellation. Code instance_deleted means a provisioning replay refers to a deleted instance. | ErrorResponse |
429 | The caller must reduce its request rate. Respect Retry-After when present. | ErrorResponse |
500 | The provider could not complete the operation. This does not permit tool execution. | ErrorResponse |
503 | The provider is temporarily unable to serve the operation. | ErrorResponse |
200 response
| Header | Type | Description |
|---|---|---|
X-Request-IDrequired | header · Identifier | Identifies this HTTP exchange. Matches error.request_id on errors. |
The stored request and its current state. Pending requests have no decision. Terminal requests have a decision matching their status. Submitted fields are immutable. timeout remains the requested window; deadline_at records the window accepted by the provider for reaching a decision. An approved call must start before decision.expires_at.
The exact tool arguments. Their keys and nested JSON values retain their original spelling and types.
The agent's explanation, presented as a claim from the agent.
Runtime information observed by the adapter. Does not establish identity.
One of pending, approved, denied, expired, cancelled
An RFC 3339 timestamp in UTC, ending in Z.
An RFC 3339 timestamp in UTC, ending in Z.
The immutable outcome of a request. An approved decision includes a fixed expires_at set by the provider, later than decided_at. The adapter must start the approved call before expires_at. This limits when execution may start, not when it must finish. Reading or replaying the decision does not extend its validity. Passing expires_at does not change the recorded approved status into expired. Other outcomes have no expires_at.
Exactly one of these variants must match:
- status must be "pending".
- decision must be absent.
- decision is required.
- status must be "approved".
- decision.status must be "approved".
- decision is required.
- status must be "denied".
- decision.status must be "denied".
- decision is required.
- status must be "expired".
- decision.status must be "expired".
- decision is required.
- status must be "cancelled".
- decision.status must be "cancelled".
View complete schema and constraints
{
"type": "object",
"additionalProperties": false,
"description": "The stored request and its current state. Pending requests have no\ndecision. Terminal requests have a decision matching their status.\nSubmitted fields are immutable. timeout remains the requested window;\ndeadline_at records the window accepted by the provider for reaching a\ndecision. An approved call must start before decision.expires_at.\n",
"required": [
"id",
"tool",
"arguments",
"timeout",
"status",
"created_at",
"deadline_at"
],
"properties": {
"id": {
"$ref": "#/components/schemas/Identifier"
},
"tool": {
"$ref": "#/components/schemas/ToolName"
},
"arguments": {
"$ref": "#/components/schemas/ToolArguments"
},
"timeout": {
"$ref": "#/components/schemas/Duration"
},
"agent_reasoning": {
"$ref": "#/components/schemas/AgentReasoning"
},
"context": {
"$ref": "#/components/schemas/RuntimeContext"
},
"status": {
"$ref": "#/components/schemas/ApprovalStatus"
},
"created_at": {
"$ref": "#/components/schemas/Timestamp"
},
"deadline_at": {
"$ref": "#/components/schemas/Timestamp"
},
"decision": {
"$ref": "#/components/schemas/Decision"
}
},
"oneOf": [
{
"title": "Pending",
"properties": {
"status": {
"const": "pending"
},
"decision": false
}
},
{
"title": "Approved",
"required": [
"decision"
],
"properties": {
"status": {
"const": "approved"
},
"decision": {
"properties": {
"status": {
"const": "approved"
}
}
}
}
},
{
"title": "Denied",
"required": [
"decision"
],
"properties": {
"status": {
"const": "denied"
},
"decision": {
"properties": {
"status": {
"const": "denied"
}
}
}
}
},
{
"title": "Expired",
"required": [
"decision"
],
"properties": {
"status": {
"const": "expired"
},
"decision": {
"properties": {
"status": {
"const": "expired"
}
}
}
}
},
{
"title": "Cancelled",
"required": [
"decision"
],
"properties": {
"status": {
"const": "cancelled"
},
"decision": {
"properties": {
"status": {
"const": "cancelled"
}
}
}
}
}
]
}{
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"tool": "issue_refund",
"arguments": {
"payment_id": "payment_123",
"amount": 4900,
"currency": "GBP"
},
"timeout": "30m",
"status": "pending",
"created_at": "2026-09-16T12:00:00Z",
"deadline_at": "2026-09-16T12:30:00Z"
}{
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"tool": "issue_refund",
"arguments": {
"payment_id": "payment_123",
"amount": 4900,
"currency": "GBP"
},
"timeout": "30m",
"status": "approved",
"created_at": "2026-09-16T12:00:00Z",
"deadline_at": "2026-09-16T12:30:00Z",
"decision": {
"status": "approved",
"note": "The duplicate charge has been confirmed.",
"decided_at": "2026-09-16T12:02:00Z",
"expires_at": "2026-09-16T12:07:00Z"
}
}201 response
| Header | Type | Description |
|---|---|---|
X-Request-IDrequired | header · Identifier | Identifies this HTTP exchange. Matches error.request_id on errors. |
The stored request and its current state. Pending requests have no decision. Terminal requests have a decision matching their status. Submitted fields are immutable. timeout remains the requested window; deadline_at records the window accepted by the provider for reaching a decision. An approved call must start before decision.expires_at.
The exact tool arguments. Their keys and nested JSON values retain their original spelling and types.
The agent's explanation, presented as a claim from the agent.
Runtime information observed by the adapter. Does not establish identity.
One of pending, approved, denied, expired, cancelled
An RFC 3339 timestamp in UTC, ending in Z.
An RFC 3339 timestamp in UTC, ending in Z.
The immutable outcome of a request. An approved decision includes a fixed expires_at set by the provider, later than decided_at. The adapter must start the approved call before expires_at. This limits when execution may start, not when it must finish. Reading or replaying the decision does not extend its validity. Passing expires_at does not change the recorded approved status into expired. Other outcomes have no expires_at.
Exactly one of these variants must match:
- status must be "pending".
- decision must be absent.
- decision is required.
- status must be "approved".
- decision.status must be "approved".
- decision is required.
- status must be "denied".
- decision.status must be "denied".
- decision is required.
- status must be "expired".
- decision.status must be "expired".
- decision is required.
- status must be "cancelled".
- decision.status must be "cancelled".
View complete schema and constraints
{
"type": "object",
"additionalProperties": false,
"description": "The stored request and its current state. Pending requests have no\ndecision. Terminal requests have a decision matching their status.\nSubmitted fields are immutable. timeout remains the requested window;\ndeadline_at records the window accepted by the provider for reaching a\ndecision. An approved call must start before decision.expires_at.\n",
"required": [
"id",
"tool",
"arguments",
"timeout",
"status",
"created_at",
"deadline_at"
],
"properties": {
"id": {
"$ref": "#/components/schemas/Identifier"
},
"tool": {
"$ref": "#/components/schemas/ToolName"
},
"arguments": {
"$ref": "#/components/schemas/ToolArguments"
},
"timeout": {
"$ref": "#/components/schemas/Duration"
},
"agent_reasoning": {
"$ref": "#/components/schemas/AgentReasoning"
},
"context": {
"$ref": "#/components/schemas/RuntimeContext"
},
"status": {
"$ref": "#/components/schemas/ApprovalStatus"
},
"created_at": {
"$ref": "#/components/schemas/Timestamp"
},
"deadline_at": {
"$ref": "#/components/schemas/Timestamp"
},
"decision": {
"$ref": "#/components/schemas/Decision"
}
},
"oneOf": [
{
"title": "Pending",
"properties": {
"status": {
"const": "pending"
},
"decision": false
}
},
{
"title": "Approved",
"required": [
"decision"
],
"properties": {
"status": {
"const": "approved"
},
"decision": {
"properties": {
"status": {
"const": "approved"
}
}
}
}
},
{
"title": "Denied",
"required": [
"decision"
],
"properties": {
"status": {
"const": "denied"
},
"decision": {
"properties": {
"status": {
"const": "denied"
}
}
}
}
},
{
"title": "Expired",
"required": [
"decision"
],
"properties": {
"status": {
"const": "expired"
},
"decision": {
"properties": {
"status": {
"const": "expired"
}
}
}
}
},
{
"title": "Cancelled",
"required": [
"decision"
],
"properties": {
"status": {
"const": "cancelled"
},
"decision": {
"properties": {
"status": {
"const": "cancelled"
}
}
}
}
}
]
}{
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"tool": "issue_refund",
"arguments": {
"payment_id": "payment_123",
"amount": 4900,
"currency": "GBP"
},
"timeout": "30m",
"status": "pending",
"created_at": "2026-09-16T12:00:00Z",
"deadline_at": "2026-09-16T12:30:00Z"
}{
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"tool": "issue_refund",
"arguments": {
"payment_id": "payment_123",
"amount": 4900,
"currency": "GBP"
},
"timeout": "30m",
"status": "approved",
"created_at": "2026-09-16T12:00:00Z",
"deadline_at": "2026-09-16T12:30:00Z",
"decision": {
"status": "approved",
"note": "The duplicate charge has been confirmed.",
"decided_at": "2026-09-16T12:02:00Z",
"expires_at": "2026-09-16T12:07:00Z"
}
}Error and retry response headers
400
| Header | Type | Description |
|---|---|---|
X-Request-IDrequired | header · Identifier | Identifies this HTTP exchange. Matches error.request_id on errors. |
401
| Header | Type | Description |
|---|---|---|
X-Request-IDrequired | header · Identifier | Identifies this HTTP exchange. Matches error.request_id on errors. |
403
| Header | Type | Description |
|---|---|---|
X-Request-IDrequired | header · Identifier | Identifies this HTTP exchange. Matches error.request_id on errors. |
409
| Header | Type | Description |
|---|---|---|
X-Request-IDrequired | header · Identifier | Identifies this HTTP exchange. Matches error.request_id on errors. |
429
| Header | Type | Description |
|---|---|---|
X-Request-IDrequired | header · Identifier | Identifies this HTTP exchange. Matches error.request_id on errors. |
Retry-After | header · string | The delay before retrying, in seconds or as an HTTP date. |
500
| Header | Type | Description |
|---|---|---|
X-Request-IDrequired | header · Identifier | Identifies this HTTP exchange. Matches error.request_id on errors. |
503
| Header | Type | Description |
|---|---|---|
X-Request-IDrequired | header · Identifier | Identifies this HTTP exchange. Matches error.request_id on errors. |
Retry-After | header · string | The delay before retrying, in seconds or as an HTTP date. |
Retrieve an approval request
/v1/requests/{id}Returns the current request. With wait, holds the response until the request becomes terminal or the wait ends. A completed wait can return a pending request. Polling does not extend the approval deadline.
Instance Credential
An opaque credential bound to exactly one instance. Cannot manage instances.
Parameters
| Field | Type | Description |
|---|---|---|
idrequired | path · Identifier | The approval request's provider-assigned ID. |
wait | query · Duration | How long to wait for a terminal state. Capped at 30 seconds. Omitting this parameter returns immediately. |
Responses
| Status | Meaning | Body |
|---|---|---|
200 | The request in its current state, including on an idempotent replay. | ApprovalRequest |
400 | The request is malformed or a field is invalid. Code invalid_webhook_url identifies an unsafe or malformed receiver URL. Code unsupported_delivery_type identifies an unsupported transport, including webhook when the provider supports only synchronous mode. | ErrorResponse |
401 | The credential is missing, expired, revoked or otherwise invalid. | ErrorResponse |
403 | The credential does not permit the operation or access to this resource. | ErrorResponse |
404 | The resource is unavailable to the caller. | ErrorResponse |
429 | The caller must reduce its request rate. Respect Retry-After when present. | ErrorResponse |
500 | The provider could not complete the operation. This does not permit tool execution. | ErrorResponse |
503 | The provider is temporarily unable to serve the operation. | ErrorResponse |
200 response
| Header | Type | Description |
|---|---|---|
X-Request-IDrequired | header · Identifier | Identifies this HTTP exchange. Matches error.request_id on errors. |
The stored request and its current state. Pending requests have no decision. Terminal requests have a decision matching their status. Submitted fields are immutable. timeout remains the requested window; deadline_at records the window accepted by the provider for reaching a decision. An approved call must start before decision.expires_at.
The exact tool arguments. Their keys and nested JSON values retain their original spelling and types.
The agent's explanation, presented as a claim from the agent.
Runtime information observed by the adapter. Does not establish identity.
One of pending, approved, denied, expired, cancelled
An RFC 3339 timestamp in UTC, ending in Z.
An RFC 3339 timestamp in UTC, ending in Z.
The immutable outcome of a request. An approved decision includes a fixed expires_at set by the provider, later than decided_at. The adapter must start the approved call before expires_at. This limits when execution may start, not when it must finish. Reading or replaying the decision does not extend its validity. Passing expires_at does not change the recorded approved status into expired. Other outcomes have no expires_at.
Exactly one of these variants must match:
- status must be "pending".
- decision must be absent.
- decision is required.
- status must be "approved".
- decision.status must be "approved".
- decision is required.
- status must be "denied".
- decision.status must be "denied".
- decision is required.
- status must be "expired".
- decision.status must be "expired".
- decision is required.
- status must be "cancelled".
- decision.status must be "cancelled".
View complete schema and constraints
{
"type": "object",
"additionalProperties": false,
"description": "The stored request and its current state. Pending requests have no\ndecision. Terminal requests have a decision matching their status.\nSubmitted fields are immutable. timeout remains the requested window;\ndeadline_at records the window accepted by the provider for reaching a\ndecision. An approved call must start before decision.expires_at.\n",
"required": [
"id",
"tool",
"arguments",
"timeout",
"status",
"created_at",
"deadline_at"
],
"properties": {
"id": {
"$ref": "#/components/schemas/Identifier"
},
"tool": {
"$ref": "#/components/schemas/ToolName"
},
"arguments": {
"$ref": "#/components/schemas/ToolArguments"
},
"timeout": {
"$ref": "#/components/schemas/Duration"
},
"agent_reasoning": {
"$ref": "#/components/schemas/AgentReasoning"
},
"context": {
"$ref": "#/components/schemas/RuntimeContext"
},
"status": {
"$ref": "#/components/schemas/ApprovalStatus"
},
"created_at": {
"$ref": "#/components/schemas/Timestamp"
},
"deadline_at": {
"$ref": "#/components/schemas/Timestamp"
},
"decision": {
"$ref": "#/components/schemas/Decision"
}
},
"oneOf": [
{
"title": "Pending",
"properties": {
"status": {
"const": "pending"
},
"decision": false
}
},
{
"title": "Approved",
"required": [
"decision"
],
"properties": {
"status": {
"const": "approved"
},
"decision": {
"properties": {
"status": {
"const": "approved"
}
}
}
}
},
{
"title": "Denied",
"required": [
"decision"
],
"properties": {
"status": {
"const": "denied"
},
"decision": {
"properties": {
"status": {
"const": "denied"
}
}
}
}
},
{
"title": "Expired",
"required": [
"decision"
],
"properties": {
"status": {
"const": "expired"
},
"decision": {
"properties": {
"status": {
"const": "expired"
}
}
}
}
},
{
"title": "Cancelled",
"required": [
"decision"
],
"properties": {
"status": {
"const": "cancelled"
},
"decision": {
"properties": {
"status": {
"const": "cancelled"
}
}
}
}
}
]
}{
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"tool": "issue_refund",
"arguments": {
"payment_id": "payment_123",
"amount": 4900,
"currency": "GBP"
},
"timeout": "30m",
"status": "pending",
"created_at": "2026-09-16T12:00:00Z",
"deadline_at": "2026-09-16T12:30:00Z"
}{
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"tool": "issue_refund",
"arguments": {
"payment_id": "payment_123",
"amount": 4900,
"currency": "GBP"
},
"timeout": "30m",
"status": "approved",
"created_at": "2026-09-16T12:00:00Z",
"deadline_at": "2026-09-16T12:30:00Z",
"decision": {
"status": "approved",
"note": "The duplicate charge has been confirmed.",
"decided_at": "2026-09-16T12:02:00Z",
"expires_at": "2026-09-16T12:07:00Z"
}
}Error and retry response headers
400
| Header | Type | Description |
|---|---|---|
X-Request-IDrequired | header · Identifier | Identifies this HTTP exchange. Matches error.request_id on errors. |
401
| Header | Type | Description |
|---|---|---|
X-Request-IDrequired | header · Identifier | Identifies this HTTP exchange. Matches error.request_id on errors. |
403
| Header | Type | Description |
|---|---|---|
X-Request-IDrequired | header · Identifier | Identifies this HTTP exchange. Matches error.request_id on errors. |
404
| Header | Type | Description |
|---|---|---|
X-Request-IDrequired | header · Identifier | Identifies this HTTP exchange. Matches error.request_id on errors. |
429
| Header | Type | Description |
|---|---|---|
X-Request-IDrequired | header · Identifier | Identifies this HTTP exchange. Matches error.request_id on errors. |
Retry-After | header · string | The delay before retrying, in seconds or as an HTTP date. |
500
| Header | Type | Description |
|---|---|---|
X-Request-IDrequired | header · Identifier | Identifies this HTTP exchange. Matches error.request_id on errors. |
503
| Header | Type | Description |
|---|---|---|
X-Request-IDrequired | header · Identifier | Identifies this HTTP exchange. Matches error.request_id on errors. |
Retry-After | header · string | The delay before retrying, in seconds or as an HTTP date. |
Cancel an approval request
/v1/requests/{id}Withdraws a pending request. Only its creating instance may call this operation. Deleting the instance also cancels its pending requests. Repeating cancellation returns the same cancelled request. No idempotency key is needed. An approved, denied or expired request is unchanged and returns 409 with code already_terminal. Cancellation ends active long polls.
Instance Credential
An opaque credential bound to exactly one instance. Cannot manage instances.
Parameters
| Field | Type | Description |
|---|---|---|
idrequired | path · Identifier | The approval request's provider-assigned ID. |
Responses
| Status | Meaning | Body |
|---|---|---|
200 | The cancelled request, including on repeated cancellation. | CancelledApprovalRequest |
401 | The credential is missing, expired, revoked or otherwise invalid. | ErrorResponse |
403 | The credential does not permit the operation or access to this resource. | ErrorResponse |
404 | The resource is unavailable to the caller. | ErrorResponse |
409 | The operation conflicts with existing state. Code idempotency_conflict means the key was used with different input. Code already_terminal means the request was approved, denied or expired before cancellation. Code instance_deleted means a provisioning replay refers to a deleted instance. | ErrorResponse |
429 | The caller must reduce its request rate. Respect Retry-After when present. | ErrorResponse |
500 | The provider could not complete the operation. This does not permit tool execution. | ErrorResponse |
503 | The provider is temporarily unable to serve the operation. | ErrorResponse |
200 response
| Header | Type | Description |
|---|---|---|
X-Request-IDrequired | header · Identifier | Identifies this HTTP exchange. Matches error.request_id on errors. |
The exact tool arguments. Their keys and nested JSON values retain their original spelling and types.
The agent's explanation, presented as a claim from the agent.
Runtime information observed by the adapter. Does not establish identity.
An RFC 3339 timestamp in UTC, ending in Z.
An RFC 3339 timestamp in UTC, ending in Z.
The immutable outcome of a request. An approved decision includes a fixed expires_at set by the provider, later than decided_at. The adapter must start the approved call before expires_at. This limits when execution may start, not when it must finish. Reading or replaying the decision does not extend its validity. Passing expires_at does not change the recorded approved status into expired. Other outcomes have no expires_at.
View complete schema and constraints
{
"allOf": [
{
"$ref": "#/components/schemas/ApprovalRequest"
},
{
"type": "object",
"properties": {
"status": {
"const": "cancelled"
}
}
}
]
}{
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"tool": "issue_refund",
"arguments": {
"payment_id": "payment_123",
"amount": 4900,
"currency": "GBP"
},
"timeout": "30m",
"status": "cancelled",
"created_at": "2026-09-16T12:00:00Z",
"deadline_at": "2026-09-16T12:30:00Z",
"decision": {
"status": "cancelled",
"decided_at": "2026-09-16T12:02:00Z"
}
}Error and retry response headers
401
| Header | Type | Description |
|---|---|---|
X-Request-IDrequired | header · Identifier | Identifies this HTTP exchange. Matches error.request_id on errors. |
403
| Header | Type | Description |
|---|---|---|
X-Request-IDrequired | header · Identifier | Identifies this HTTP exchange. Matches error.request_id on errors. |
404
| Header | Type | Description |
|---|---|---|
X-Request-IDrequired | header · Identifier | Identifies this HTTP exchange. Matches error.request_id on errors. |
409
| Header | Type | Description |
|---|---|---|
X-Request-IDrequired | header · Identifier | Identifies this HTTP exchange. Matches error.request_id on errors. |
429
| Header | Type | Description |
|---|---|---|
X-Request-IDrequired | header · Identifier | Identifies this HTTP exchange. Matches error.request_id on errors. |
Retry-After | header · string | The delay before retrying, in seconds or as an HTTP date. |
500
| Header | Type | Description |
|---|---|---|
X-Request-IDrequired | header · Identifier | Identifies this HTTP exchange. Matches error.request_id on errors. |
503
| Header | Type | Description |
|---|---|---|
X-Request-IDrequired | header · Identifier | Identifies this HTTP exchange. Matches error.request_id on errors. |
Retry-After | header · string | The delay before retrying, in seconds or as an HTTP date. |