GitHub

API reference

Schemas

The objects, types and constraints defined by the OpenAPI contract.

Identifier

uuid

View complete schema and constraints
json
{
  "type": "string",
  "format": "uuid"
}

Timestamp

An RFC 3339 timestamp in UTC, ending in Z.

date-time

View complete schema and constraints
json
{
  "type": "string",
  "format": "date-time",
  "pattern": "Z$",
  "description": "An RFC 3339 timestamp in UTC, ending in Z.",
  "examples": [
    "2026-09-16T12:00:00Z"
  ]
}

Duration

A positive whole number of seconds, minutes or hours, with its unit.

string

View complete schema and constraints
json
{
  "type": "string",
  "pattern": "^[1-9][0-9]*(s|m|h)$",
  "description": "A positive whole number of seconds, minutes or hours, with its unit.",
  "examples": [
    "30s",
    "30m",
    "24h"
  ]
}

ToolName

The name identifying the intercepted tool.

string

View complete schema and constraints
json
{
  "type": "string",
  "minLength": 1,
  "description": "The name identifying the intercepted tool.",
  "examples": [
    "issue_refund"
  ]
}

ToolArguments

The exact tool arguments. Their keys and nested JSON values retain their original spelling and types.

object

View complete schema and constraints
json
{
  "type": "object",
  "additionalProperties": true,
  "description": "The exact tool arguments. Their keys and nested JSON values retain their original spelling and types."
}

AgentReasoning

The agent's explanation, presented as a claim from the agent.

string

View complete schema and constraints
json
{
  "type": "string",
  "description": "The agent's explanation, presented as a claim from the agent."
}

RuntimeContext

Runtime information observed by the adapter. Does not establish identity.

object

View complete schema and constraints
json
{
  "type": "object",
  "additionalProperties": true,
  "description": "Runtime information observed by the adapter. Does not establish identity."
}

CreateApprovalRequest

toolToolNamerequired

The name identifying the intercepted tool.

The exact tool arguments. Their keys and nested JSON values retain their original spelling and types.

A positive whole number of seconds, minutes or hours, with its unit.

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
json
{
  "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"
    }
  }
}

ApprovalStatus

string

View complete schema and constraints
json
{
  "type": "string",
  "enum": [
    "pending",
    "approved",
    "denied",
    "expired",
    "cancelled"
  ]
}

DecisionStatus

string

View complete schema and constraints
json
{
  "type": "string",
  "enum": [
    "approved",
    "denied",
    "expired",
    "cancelled"
  ]
}

Decision

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.

One of approved, denied, expired, cancelled

notestring

Additional information. Does not change the approved arguments or authorize other calls.

An RFC 3339 timestamp in UTC, ending in Z.

Required for approved decisions and absent for other outcomes. At or after this time, the adapter must not start the call using this approval. The provider chooses the validity period. A new execution attempt after expiry requires a new approval request and idempotency key.

Exactly one of these variants must match:

Approval
  • expires_at is required.
  • status must be "approved".
Other outcome
  • status must be one of "denied", "expired", "cancelled".
  • expires_at must be absent.
View complete schema and constraints
json
{
  "type": "object",
  "additionalProperties": false,
  "description": "The immutable outcome of a request. An approved decision includes a fixed\nexpires_at set by the provider, later than decided_at. The adapter must\nstart the approved call before expires_at. This limits when execution may\nstart, not when it must finish. Reading or replaying the decision does not\nextend its validity. Passing expires_at does not change the recorded\napproved status into expired. Other outcomes have no expires_at.\n",
  "required": [
    "status",
    "decided_at"
  ],
  "properties": {
    "status": {
      "$ref": "#/components/schemas/DecisionStatus"
    },
    "note": {
      "type": "string",
      "description": "Additional information. Does not change the approved arguments or authorize other calls."
    },
    "decided_at": {
      "$ref": "#/components/schemas/Timestamp"
    },
    "expires_at": {
      "$ref": "#/components/schemas/Timestamp",
      "description": "Required for approved decisions and absent for other outcomes.\nAt or after this time, the adapter must not start the call using this\napproval. The provider chooses the validity period. A new execution\nattempt after expiry requires a new approval request and idempotency key.\n"
    }
  },
  "oneOf": [
    {
      "title": "Approval",
      "required": [
        "expires_at"
      ],
      "properties": {
        "status": {
          "const": "approved"
        }
      }
    },
    {
      "title": "Other outcome",
      "properties": {
        "status": {
          "enum": [
            "denied",
            "expired",
            "cancelled"
          ]
        },
        "expires_at": false
      }
    }
  ]
}

ApprovalRequest

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.

idIdentifierrequired
toolToolNamerequired

The name identifying the intercepted tool.

The exact tool arguments. Their keys and nested JSON values retain their original spelling and types.

A positive whole number of seconds, minutes or hours, with its unit.

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.

decisionDecisionconditional

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:

Pending
  • status must be "pending".
  • decision must be absent.
Approved
  • decision is required.
  • status must be "approved".
  • decision.status must be "approved".
Denied
  • decision is required.
  • status must be "denied".
  • decision.status must be "denied".
Expired
  • decision is required.
  • status must be "expired".
  • decision.status must be "expired".
Cancelled
  • decision is required.
  • status must be "cancelled".
  • decision.status must be "cancelled".
View complete schema and constraints
json
{
  "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"
            }
          }
        }
      }
    }
  ]
}

CancelledApprovalRequest

idIdentifierrequired
toolToolNamerequired

The name identifying the intercepted tool.

The exact tool arguments. Their keys and nested JSON values retain their original spelling and types.

A positive whole number of seconds, minutes or hours, with its unit.

The agent's explanation, presented as a claim from the agent.

Runtime information observed by the adapter. Does not establish identity.

status"cancelled"required

An RFC 3339 timestamp in UTC, ending in Z.

An RFC 3339 timestamp in UTC, ending in Z.

decisionDecisionconditional

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
json
{
  "allOf": [
    {
      "$ref": "#/components/schemas/ApprovalRequest"
    },
    {
      "type": "object",
      "properties": {
        "status": {
          "const": "cancelled"
        }
      }
    }
  ]
}

ProvisionInstanceRequest

Submit an empty object when neither a name nor delivery is supplied.

A recognisable name for the instance. The provider assigns one if omitted.

A complete proposed delivery configuration. Both initial setup and replacement require receiver verification. Only webhook delivery is defined. The event is independent of the transport. Registration and delivery must be rate limited per provisioning account and destination across instances, including aggregate host and address limits. Bound concurrency and request and response sizes. Document the provider's limits and apply them to verification and retries too.

View complete schema and constraints
json
{
  "type": "object",
  "additionalProperties": false,
  "description": "Submit an empty object when neither a name nor delivery is supplied.",
  "properties": {
    "instance_name": {
      "type": "string",
      "minLength": 1,
      "description": "A recognisable name for the instance. The provider assigns one if omitted.",
      "examples": [
        "codex-chris-laptop"
      ]
    },
    "delivery": {
      "$ref": "#/components/schemas/WebhookDeliveryInput"
    }
  }
}

UpdateInstanceRequest

Omit to keep delivery unchanged, replace with a complete object, or use null to remove it.

View complete schema and constraints
json
{
  "type": "object",
  "additionalProperties": false,
  "minProperties": 1,
  "properties": {
    "instance_name": {
      "type": "string",
      "minLength": 1
    },
    "delivery": {
      "description": "Omit to keep delivery unchanged, replace with a complete object, or use null to remove it.",
      "oneOf": [
        {
          "$ref": "#/components/schemas/WebhookDeliveryInput"
        },
        {
          "type": "null"
        }
      ]
    }
  }
}

WebhookURL

The exact HTTPS receiver URL. Userinfo and fragments are forbidden. The provider must validate syntax and destination addresses before every connection, including verification and retries. Reject loopback, private, link-local, metadata and other non-public addresses, including IPv6. DNS changes must not bypass these checks. Do not follow redirects.

uri

View complete schema and constraints
json
{
  "type": "string",
  "format": "uri",
  "pattern": "^https://[^/?#@\\s]+([/?][^#\\s]*)?$",
  "description": "The exact HTTPS receiver URL. Userinfo and fragments are forbidden.\nThe provider must validate syntax and destination addresses before every\nconnection, including verification and retries. Reject loopback, private,\nlink-local, metadata and other non-public addresses, including IPv6.\nDNS changes must not bypass these checks. Do not follow redirects.\n"
}

WebhookSigningSecret

Standard Webhooks secret containing exactly 32 cryptographically random bytes, encoded as canonical padded base64 and prefixed with whsec_. Generated by the provisioner and installed on the receiver before the request. Use a separate secret per instance; never reuse an API credential. The secret is never returned in a response or exposed to the agent.

string

View complete schema and constraints
json
{
  "type": "string",
  "writeOnly": true,
  "pattern": "^whsec_[A-Za-z0-9+/]{42}[AEIMQUYcgkosw048]=$",
  "description": "Standard Webhooks secret containing exactly 32 cryptographically random\nbytes, encoded as canonical padded base64 and prefixed with whsec_.\nGenerated by the provisioner and installed on the receiver before the\nrequest. Use a separate secret per instance; never reuse an API credential.\nThe secret is never returned in a response or exposed to the agent.\n"
}

WebhookRegistrationID

A provisioner-generated UUID identifying an expected configuration on the receiver before the provider assigns an instance ID. Install its association with the signing secret on the receiver before provisioning or updating. Reuse it on retries of the same submission; generate a new value for a replacement configuration. It is a lookup hint, not a secret or proof of authenticity. The provider echoes it in verification messages.

Identifier

View complete schema and constraints
json
{
  "allOf": [
    {
      "$ref": "#/components/schemas/Identifier"
    }
  ],
  "description": "A provisioner-generated UUID identifying an expected configuration on\nthe receiver before the provider assigns an instance ID. Install its\nassociation with the signing secret on the receiver before provisioning\nor updating. Reuse it on retries of the same submission; generate a new\nvalue for a replacement configuration. It is a lookup hint, not a secret\nor proof of authenticity. The provider echoes it in verification messages.\n"
}

WebhookDeliveryInput

A complete proposed delivery configuration. Both initial setup and replacement require receiver verification. Only webhook delivery is defined. The event is independent of the transport. Registration and delivery must be rate limited per provisioning account and destination across instances, including aggregate host and address limits. Bound concurrency and request and response sizes. Document the provider's limits and apply them to verification and retries too.

type"webhook"required

The exact HTTPS receiver URL. Userinfo and fragments are forbidden. The provider must validate syntax and destination addresses before every connection, including verification and retries. Reject loopback, private, link-local, metadata and other non-public addresses, including IPv6. DNS changes must not bypass these checks. Do not follow redirects.

A provisioner-generated UUID identifying an expected configuration on the receiver before the provider assigns an instance ID. Install its association with the signing secret on the receiver before provisioning or updating. Reuse it on retries of the same submission; generate a new value for a replacement configuration. It is a lookup hint, not a secret or proof of authenticity. The provider echoes it in verification messages.

Standard Webhooks secret containing exactly 32 cryptographically random bytes, encoded as canonical padded base64 and prefixed with whsec_. Generated by the provisioner and installed on the receiver before the request. Use a separate secret per instance; never reuse an API credential. The secret is never returned in a response or exposed to the agent.

View complete schema and constraints
json
{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "type",
    "url",
    "registration_id",
    "signing_secret"
  ],
  "description": "A complete proposed delivery configuration. Both initial setup and\nreplacement require receiver verification. Only webhook delivery is\ndefined. The event is independent of the transport.\nRegistration and delivery must be rate limited per provisioning account\nand destination across instances, including aggregate host and address\nlimits. Bound concurrency and request and response sizes. Document the\nprovider's limits and apply them to verification and retries too.\n",
  "properties": {
    "type": {
      "type": "string",
      "const": "webhook"
    },
    "url": {
      "$ref": "#/components/schemas/WebhookURL"
    },
    "registration_id": {
      "$ref": "#/components/schemas/WebhookRegistrationID"
    },
    "signing_secret": {
      "$ref": "#/components/schemas/WebhookSigningSecret"
    }
  }
}

WebhookDelivery

The active verified configuration. Never contains the signing secret.

type"webhook"required

The exact HTTPS receiver URL. Userinfo and fragments are forbidden. The provider must validate syntax and destination addresses before every connection, including verification and retries. Reject loopback, private, link-local, metadata and other non-public addresses, including IPv6. DNS changes must not bypass these checks. Do not follow redirects.

A provisioner-generated UUID identifying an expected configuration on the receiver before the provider assigns an instance ID. Install its association with the signing secret on the receiver before provisioning or updating. Reuse it on retries of the same submission; generate a new value for a replacement configuration. It is a lookup hint, not a secret or proof of authenticity. The provider echoes it in verification messages.

View complete schema and constraints
json
{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "type",
    "url",
    "registration_id"
  ],
  "description": "The active verified configuration. Never contains the signing secret.",
  "properties": {
    "type": {
      "type": "string",
      "const": "webhook"
    },
    "url": {
      "$ref": "#/components/schemas/WebhookURL"
    },
    "registration_id": {
      "$ref": "#/components/schemas/WebhookRegistrationID"
    }
  }
}

Instance

idIdentifierrequired
namestringrequired

The name assigned by the provider. A name is not proof of identity.

Absent when no receiver is configured. Instance reads never return credentials or signing secrets.

View complete schema and constraints
json
{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "id",
    "name"
  ],
  "properties": {
    "id": {
      "$ref": "#/components/schemas/Identifier"
    },
    "name": {
      "type": "string",
      "minLength": 1,
      "description": "The name assigned by the provider. A name is not proof of identity."
    },
    "delivery": {
      "$ref": "#/components/schemas/WebhookDelivery",
      "description": "Absent when no receiver is configured. Instance reads never return credentials or signing secrets."
    }
  }
}

IssuedCredential

tokenstringrequired

The opaque bearer credential bound to the returned instance. Treat as a secret.

When the credential expires. Absent if no expiry is scheduled. Revocation may occur earlier.

View complete schema and constraints
json
{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "token"
  ],
  "properties": {
    "token": {
      "type": "string",
      "minLength": 1,
      "description": "The opaque bearer credential bound to the returned instance. Treat as a secret."
    },
    "expires_at": {
      "$ref": "#/components/schemas/Timestamp",
      "description": "When the credential expires. Absent if no expiry is scheduled. Revocation may occur earlier."
    }
  }
}

ProvisionInstanceResponse

View complete schema and constraints
json
{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "instance",
    "credential"
  ],
  "properties": {
    "instance": {
      "$ref": "#/components/schemas/Instance"
    },
    "credential": {
      "$ref": "#/components/schemas/IssuedCredential"
    }
  }
}

RequestResolvedEvent

A transport-independent notification of a terminal request, generated for approved, denied, expired and cancelled outcomes. created_at equals decision.decided_at. The provider creates one immutable event per request that becomes terminal whilst delivery is configured, except during instance deletion. It contains no decision, tool arguments or credentials. Fetch the authoritative request through the authenticated API.

idIdentifierrequired
type"request.resolved"required

An RFC 3339 timestamp in UTC, ending in Z.

View complete schema and constraints
json
{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "id",
    "type",
    "instance_id",
    "request_id",
    "created_at"
  ],
  "description": "A transport-independent notification of a terminal request, generated\nfor approved, denied, expired and cancelled outcomes. created_at equals\ndecision.decided_at. The provider creates one immutable event per request\nthat becomes terminal whilst delivery is configured, except during\ninstance deletion. It contains no decision, tool arguments or credentials.\nFetch the authoritative request through the authenticated API.\n",
  "properties": {
    "id": {
      "$ref": "#/components/schemas/Identifier"
    },
    "type": {
      "type": "string",
      "const": "request.resolved"
    },
    "instance_id": {
      "$ref": "#/components/schemas/Identifier"
    },
    "request_id": {
      "$ref": "#/components/schemas/Identifier"
    },
    "created_at": {
      "$ref": "#/components/schemas/Timestamp"
    }
  }
}

WebhookVerification

idIdentifierrequired
type"webhook.verification"required

A provisioner-generated UUID identifying an expected configuration on the receiver before the provider assigns an instance ID. Install its association with the signing secret on the receiver before provisioning or updating. Reuse it on retries of the same submission; generate a new value for a replacement configuration. It is a lookup hint, not a secret or proof of authenticity. The provider echoes it in verification messages.

An RFC 3339 timestamp in UTC, ending in Z.

A fresh unpredictable UUID challenge bound to this configuration attempt.

View complete schema and constraints
json
{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "id",
    "type",
    "registration_id",
    "instance_id",
    "created_at",
    "challenge"
  ],
  "properties": {
    "id": {
      "$ref": "#/components/schemas/Identifier"
    },
    "type": {
      "type": "string",
      "const": "webhook.verification"
    },
    "registration_id": {
      "$ref": "#/components/schemas/WebhookRegistrationID"
    },
    "instance_id": {
      "$ref": "#/components/schemas/Identifier"
    },
    "created_at": {
      "$ref": "#/components/schemas/Timestamp"
    },
    "challenge": {
      "$ref": "#/components/schemas/Identifier",
      "description": "A fresh unpredictable UUID challenge bound to this configuration attempt."
    }
  }
}

WebhookVerificationResponse

The exact challenge from the verified, expected registration message.

View complete schema and constraints
json
{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "challenge"
  ],
  "properties": {
    "challenge": {
      "$ref": "#/components/schemas/Identifier",
      "description": "The exact challenge from the verified, expected registration message."
    }
  }
}

ErrorType

string

View complete schema and constraints
json
{
  "type": "string",
  "enum": [
    "invalid_request",
    "authentication",
    "authorization",
    "not_found",
    "conflict",
    "rate_limit",
    "dependency",
    "internal"
  ]
}

Error

One of invalid_request, authentication, authorization, not_found, conflict, rate_limit, dependency, internal

codestringrequired

A machine-readable reason, such as idempotency_conflict or already_terminal.

messagestringrequired

A safe explanation without credentials, stack traces or internal details.

paramstring

The invalid input field, when applicable.

View complete schema and constraints
json
{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "type",
    "code",
    "message",
    "request_id"
  ],
  "properties": {
    "type": {
      "$ref": "#/components/schemas/ErrorType"
    },
    "code": {
      "type": "string",
      "pattern": "^[a-z][a-z0-9]*(_[a-z0-9]+)*$",
      "description": "A machine-readable reason, such as idempotency_conflict or already_terminal."
    },
    "message": {
      "type": "string",
      "minLength": 1,
      "description": "A safe explanation without credentials, stack traces or internal details."
    },
    "param": {
      "type": "string",
      "minLength": 1,
      "description": "The invalid input field, when applicable."
    },
    "request_id": {
      "$ref": "#/components/schemas/Identifier"
    }
  }
}

ErrorResponse

errorErrorrequired
View complete schema and constraints
json
{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "error"
  ],
  "properties": {
    "error": {
      "$ref": "#/components/schemas/Error"
    }
  }
}