{ "components": { "schemas": { "APIReference": { "description": "Identifies a target API — the strict (all-required) variant.\n\nUsed in responses and as the canonical identity tuple.", "examples": [ { "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" } ], "properties": { "name": { "description": "Name of the API within the vendor.", "examples": [ "stripe" ], "title": "Name", "type": "string" }, "vendor": { "description": "Vendor of the API (for example `stripe.com`).", "examples": [ "stripe.com" ], "title": "Vendor", "type": "string" }, "version": { "description": "Version of the API.", "examples": [ "2024-04-10" ], "title": "Version", "type": "string" } }, "required": [ "vendor", "name", "version" ], "title": "APIReference", "type": "object" }, "APIReferenceRequest": { "description": "Relaxed variant for request bodies where partial identification is allowed.", "examples": [ { "catalog_api_id": "stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" } ], "properties": { "catalog_api_id": { "anyOf": [ { "maxLength": 255, "type": "string" }, { "type": "null" } ], "description": "Catalog identity of the API (`domain[/sub-api]`, for example `nytimes.com/article_search`), when known; used for display only, not for matching.", "examples": [ "stripe.com" ], "title": "Catalog Api Id" }, "name": { "default": "", "description": "Name of the API within the vendor; empty to cover every API of the vendor.", "examples": [ "stripe" ], "title": "Name", "type": "string" }, "vendor": { "description": "Vendor of the API (for example `stripe.com`).", "examples": [ "stripe.com" ], "title": "Vendor", "type": "string" }, "version": { "default": "", "description": "Version of the API; empty to cover every version.", "examples": [ "2024-04-10" ], "title": "Version", "type": "string" } }, "required": [ "vendor" ], "title": "APIReferenceRequest", "type": "object" }, "ActorListResponse": { "description": "Paginated list of actors.", "examples": [ { "data": [ { "active": true, "actor_type": "user", "created_at": "2026-01-15T09:30:00Z", "id": "usr_6968b3987ee4c3ec0b4ee3b9", "name": "Ada Lovelace" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } ], "properties": { "data": { "description": "The page of actors.", "examples": [ [ { "active": true, "actor_type": "user", "created_at": "2026-01-15T09:30:00Z", "id": "usr_6968b3987ee4c3ec0b4ee3b9", "name": "Ada Lovelace" } ] ], "items": { "$ref": "#/components/schemas/ActorSummaryResponse" }, "title": "Data", "type": "array" }, "has_more": { "description": "Whether more results exist after this page.", "examples": [ true ], "title": "Has More", "type": "boolean" }, "next_cursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Cursor for the next page; null when there are no more results.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Next Cursor" } }, "required": [ "data", "has_more" ], "title": "ActorListResponse", "type": "object" }, "ActorLookupEntryResponse": { "description": "Display fields of one actor resolved by id.", "examples": [ { "active": true, "actor_type": "user", "id": "usr_6968b3987ee4c3ec0b4ee3b9", "name": "Ada Lovelace" } ], "properties": { "active": { "description": "False for a disabled user or a non-active agent.", "examples": [ true ], "title": "Active", "type": "boolean" }, "actor_type": { "$ref": "#/components/schemas/ActorType", "description": "Whether the actor is a user or an agent.", "examples": [ "user" ] }, "id": { "description": "Actor id (`usr_…` or `agnt_…`).", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "Id", "type": "string" }, "name": { "description": "Display name: a user's full name or an agent's name.", "examples": [ "Ada Lovelace" ], "title": "Name", "type": "string" } }, "required": [ "id", "actor_type", "name", "active" ], "title": "ActorLookupEntryResponse", "type": "object" }, "ActorLookupResponse": { "description": "Actors resolved by id; ids that match no actor are omitted.", "examples": [ { "data": [ { "active": true, "actor_type": "user", "id": "usr_2abc", "name": "Ada Lovelace" } ] } ], "properties": { "data": { "description": "The resolved actors; ids that match no visible actor are omitted.", "examples": [ [ { "active": true, "actor_type": "user", "id": "usr_6968b3987ee4c3ec0b4ee3b9", "name": "Ada Lovelace" } ] ], "items": { "$ref": "#/components/schemas/ActorLookupEntryResponse" }, "title": "Data", "type": "array" } }, "required": [ "data" ], "title": "ActorLookupResponse", "type": "object" }, "ActorSummaryResponse": { "description": "Single actor entry in the actors list.", "examples": [ { "active": true, "actor_type": "user", "created_at": "2026-01-15T09:30:00Z", "id": "usr_6968b3987ee4c3ec0b4ee3b9", "name": "Ada Lovelace" } ], "properties": { "active": { "description": "False for a disabled user or a non-active agent.", "examples": [ true ], "title": "Active", "type": "boolean" }, "actor_type": { "$ref": "#/components/schemas/ActorType", "examples": [ "user" ] }, "created_at": { "description": "When the actor was created (RFC 3339).", "examples": [ "2026-01-15T09:30:00Z" ], "format": "date-time", "title": "Created At", "type": "string" }, "id": { "description": "Actor id (`usr_…` or `agnt_…`).", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "Id", "type": "string" }, "name": { "description": "Display name: a user's full name or an agent's name.", "examples": [ "Ada Lovelace" ], "title": "Name", "type": "string" } }, "required": [ "id", "actor_type", "name", "active", "created_at" ], "title": "ActorSummaryResponse", "type": "object" }, "ActorType": { "description": "Type of authenticated actor: a human user or an agent.\n\nHistorical records may carry older actor-type values that are no longer\nissued; treat unrecognised values as opaque labels.", "enum": [ "user", "agent" ], "title": "ActorType", "type": "string" }, "AgentCreateRequest": { "additionalProperties": false, "description": "Request body for creating an agent manually.", "examples": [ { "description": "Reconciles Stripe invoices against the ledger every night.", "name": "invoice-reconciler", "permissions": [ "apis:read", "capabilities:execute" ] } ], "properties": { "description": { "anyOf": [ { "maxLength": 1024, "type": "string" }, { "type": "null" } ], "description": "Optional free-text description of the agent.", "examples": [ "Reconciles Stripe invoices against the ledger every night." ], "title": "Description" }, "name": { "description": "Human-readable name of the agent.", "examples": [ "invoice-reconciler" ], "maxLength": 255, "minLength": 1, "title": "Name", "type": "string" }, "permissions": { "anyOf": [ { "items": { "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9_:./-]+$", "type": "string" }, "maxItems": 100, "type": "array" }, { "type": "null" } ], "description": "Permissions to grant the agent; each must be grantable by the caller. Omit to grant the default agent permission set.", "examples": [ [ "apis:read", "capabilities:execute" ] ], "title": "Permissions" } }, "required": [ "name" ], "title": "AgentCreateRequest", "type": "object" }, "AgentListResponse": { "description": "List of agents.", "examples": [ { "data": [ { "approved_at": "2026-01-15T09:45:00Z", "approved_by": "usr_6968b3987ee4c3ec0b4ee3b9", "created_at": "2026-01-15T09:30:00Z", "denial_reason": "Requested permissions exceed the agent's stated purpose.", "denied_by": "usr_6968b3987ee4c3ec0b4ee3b9", "description": "Reconciles Stripe invoices against the ledger every night.", "has_api_key": true, "id": "agnt_6968b3984d1c238dbe7e2e29", "name": "invoice-reconciler", "owner_id": "usr_6968b3987ee4c3ec0b4ee3b9", "parent_agent_id": "agnt_6968b3984d1c238dbe7e2e29", "registered_by": "usr_6968b3987ee4c3ec0b4ee3b9", "status": "active" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } ], "properties": { "data": { "description": "The page of agents.", "examples": [ [ { "approved_at": "2026-01-15T09:45:00Z", "approved_by": "usr_6968b3987ee4c3ec0b4ee3b9", "created_at": "2026-01-15T09:30:00Z", "denial_reason": "Requested permissions exceed the agent's stated purpose.", "denied_by": "usr_6968b3987ee4c3ec0b4ee3b9", "description": "Reconciles Stripe invoices against the ledger every night.", "has_api_key": true, "id": "agnt_6968b3984d1c238dbe7e2e29", "name": "invoice-reconciler", "owner_id": "usr_6968b3987ee4c3ec0b4ee3b9", "parent_agent_id": "agnt_6968b3984d1c238dbe7e2e29", "registered_by": "usr_6968b3987ee4c3ec0b4ee3b9", "status": "active" } ] ], "items": { "$ref": "#/components/schemas/AgentResponse" }, "title": "Data", "type": "array" }, "has_more": { "description": "Whether more results exist after this page.", "examples": [ true ], "title": "Has More", "type": "boolean" }, "next_cursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Cursor for the next page; null when there are no more results.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Next Cursor" } }, "required": [ "data", "has_more" ], "title": "AgentListResponse", "type": "object" }, "AgentPatchRequest": { "description": "Request body for partially updating an agent.", "examples": [ { "description": "Reconciles Stripe invoices against the ledger every night.", "name": "invoice-reconciler", "owner_id": "usr_6968b3987ee4c3ec0b4ee3b9" } ], "properties": { "description": { "anyOf": [ { "maxLength": 1024, "type": "string" }, { "type": "null" } ], "description": "New description for the agent.", "examples": [ "Reconciles Stripe invoices against the ledger every night." ], "title": "Description" }, "name": { "anyOf": [ { "maxLength": 255, "minLength": 1, "type": "string" }, { "type": "null" } ], "description": "New name for the agent.", "examples": [ "invoice-reconciler" ], "title": "Name" }, "owner_id": { "anyOf": [ { "maxLength": 255, "minLength": 1, "type": "string" }, { "type": "null" } ], "description": "ID of the user to transfer ownership to; `org:admin` only.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "Owner Id" } }, "title": "AgentPatchRequest", "type": "object" }, "AgentPermissionsRequest": { "additionalProperties": false, "description": "Request body for replacing an agent's permissions.", "examples": [ { "permissions": [ "apis:read", "capabilities:execute" ] } ], "properties": { "permissions": { "description": "The full set of permissions the agent should hold.", "examples": [ [ "apis:read", "capabilities:execute" ] ], "items": { "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9_:./-]+$", "type": "string" }, "maxItems": 100, "title": "Permissions", "type": "array" } }, "required": [ "permissions" ], "title": "AgentPermissionsRequest", "type": "object" }, "AgentPermissionsResponse": { "description": "Response containing an agent's current permissions.", "examples": [ { "permissions": [ "apis:read", "capabilities:execute" ] } ], "properties": { "permissions": { "description": "Permissions currently granted to the agent.", "examples": [ [ "apis:read", "capabilities:execute" ] ], "items": { "type": "string" }, "title": "Permissions", "type": "array" } }, "required": [ "permissions" ], "title": "AgentPermissionsResponse", "type": "object" }, "AgentResponse": { "description": "Agent representation in API responses.", "examples": [ { "approved_at": "2026-01-15T09:45:00Z", "approved_by": "usr_6968b3987ee4c3ec0b4ee3b9", "created_at": "2026-01-15T09:30:00Z", "denial_reason": "Requested permissions exceed the agent's stated purpose.", "denied_by": "usr_6968b3987ee4c3ec0b4ee3b9", "description": "Reconciles Stripe invoices against the ledger every night.", "has_api_key": true, "id": "agnt_6968b3984d1c238dbe7e2e29", "name": "invoice-reconciler", "owner_id": "usr_6968b3987ee4c3ec0b4ee3b9", "parent_agent_id": "agnt_6968b3984d1c238dbe7e2e29", "registered_by": "usr_6968b3987ee4c3ec0b4ee3b9", "status": "active" } ], "properties": { "approved_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "When the agent was approved (RFC 3339); null if not approved.", "examples": [ "2026-01-15T09:45:00Z" ], "title": "Approved At" }, "approved_by": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the user who approved the agent; null if not approved.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "Approved By" }, "created_at": { "description": "When the agent was created (RFC 3339).", "examples": [ "2026-01-15T09:30:00Z" ], "format": "date-time", "title": "Created At", "type": "string" }, "denial_reason": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Reason given when the agent was denied; null if not denied.", "examples": [ "Requested permissions exceed the agent's stated purpose." ], "title": "Denial Reason" }, "denied_by": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the actor that denied the agent; null if not denied.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "Denied By" }, "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Free-text description of the agent; null if not set.", "examples": [ "Reconciles Stripe invoices against the ledger every night." ], "title": "Description" }, "has_api_key": { "default": false, "description": "Whether the agent currently has an active API key; only populated by `GET /agents/{agent_id}`, and false in other responses.", "examples": [ true ], "title": "Has Api Key", "type": "boolean" }, "id": { "description": "Unique ID of the agent.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Id", "type": "string" }, "name": { "description": "Human-readable name of the agent.", "examples": [ "invoice-reconciler" ], "title": "Name", "type": "string" }, "owner_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the user who owns the agent; null for an unclaimed self-registration.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "Owner Id" }, "parent_agent_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the parent agent; null when the agent has no parent.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Parent Agent Id" }, "registered_by": { "description": "ID of the actor that registered the agent, or `self` for a self-registration.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "Registered By", "type": "string" }, "status": { "description": "Lifecycle status of the agent: `pending`, `active`, `rejected`, `disabled` or `archived`.", "examples": [ "active" ], "title": "Status", "type": "string" } }, "required": [ "id", "name", "registered_by", "status", "created_at" ], "title": "AgentResponse", "type": "object" }, "ApiImportLinksResponse": { "description": "Hypermedia links for an import response.", "examples": [ { "self": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb" } ], "properties": { "self": { "description": "URL of the import job to poll for progress.", "examples": [ "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb" ], "title": "Self", "type": "string" } }, "required": [ "self" ], "title": "ApiImportLinksResponse", "type": "object" }, "ApiImportRequest": { "description": "Wrapper for a batch of import sources.", "examples": [ { "sources": [ { "api_name": "stripe", "submitted_by": "usr_6968b3987ee4c3ec0b4ee3b9", "type": "url", "url": "https://raw.githubusercontent.com/jentic/jentic-public-apis/main/apis/openapi/stripe.com/main/2024-04-10/openapi.json", "vendor": "stripe.com", "version": "2024-04-10" } ] } ], "properties": { "sources": { "description": "Documents to import, between 1 and 100 per request.", "examples": [ [ { "api_name": "stripe", "submitted_by": "usr_6968b3987ee4c3ec0b4ee3b9", "type": "url", "url": "https://raw.githubusercontent.com/jentic/jentic-public-apis/main/apis/openapi/stripe.com/main/2024-04-10/openapi.json", "vendor": "stripe.com", "version": "2024-04-10" } ] ], "items": { "discriminator": { "mapping": { "inline": "#/components/schemas/ApiSourceInline", "url": "#/components/schemas/ApiSourceUrl" }, "propertyName": "type" }, "oneOf": [ { "$ref": "#/components/schemas/ApiSourceUrl" }, { "$ref": "#/components/schemas/ApiSourceInline" } ] }, "maxItems": 100, "minItems": 1, "title": "Sources", "type": "array" } }, "required": [ "sources" ], "title": "ApiImportRequest", "type": "object" }, "ApiImportResponse": { "description": "Acknowledgement payload for an asynchronous import job.", "examples": [ { "_links": { "self": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb" }, "job_id": "job_6968b3985e8c9902207afaeb", "status": "queued" } ], "properties": { "_links": { "$ref": "#/components/schemas/ApiImportLinksResponse", "examples": [ { "self": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb" } ] }, "job_id": { "description": "ID of the import job.", "examples": [ "job_6968b3985e8c9902207afaeb" ], "title": "Job Id", "type": "string" }, "status": { "description": "Status of the job when accepted; `queued`.", "examples": [ "queued" ], "title": "Status", "type": "string" } }, "required": [ "job_id", "status", "_links" ], "title": "ApiImportResponse", "type": "object" }, "ApiInfoResponse": { "description": "API identification information.", "examples": [ { "host": "api.stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" } ], "properties": { "host": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Upstream host called; null if unknown.", "examples": [ "api.stripe.com" ], "title": "Host" }, "name": { "description": "Name of the API that was called.", "examples": [ "stripe" ], "title": "Name", "type": "string" }, "vendor": { "description": "Vendor of the API that was called.", "examples": [ "stripe.com" ], "title": "Vendor", "type": "string" }, "version": { "description": "Version of the API that was called.", "examples": [ "2024-04-10" ], "title": "Version", "type": "string" } }, "required": [ "vendor", "name", "version" ], "title": "ApiInfoResponse", "type": "object" }, "ApiKeyConfirmSessionRequest": { "additionalProperties": false, "description": "Confirm a ``manual_api_key`` session with the API key to store.", "examples": [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "digest": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae", "expected_agent_id": "agnt_6968b3984d1c238dbe7e2e29", "key": "example-secret", "kind": "api_key", "permission_rules": [ { "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] } ], "properties": { "agent_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Agent to bind when the session has none; ignored if the session already has one.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id" }, "digest": { "description": "Review digest echoed from the review data; a mismatch is 409 review_stale.", "examples": [ "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae" ], "maxLength": 64, "minLength": 1, "title": "Digest", "type": "string" }, "expected_agent_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Agent ID from the review the approver saw; a mismatch is 409 review_stale.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Expected Agent Id" }, "key": { "description": "API key to store; write-only.", "examples": [ "example-secret" ], "format": "password", "maxLength": 8192, "minLength": 1, "title": "Key", "type": "string", "writeOnly": true, "x-sensitive": true }, "kind": { "const": "api_key", "description": "Confirm variant; always `api_key`.", "examples": [ "api_key" ], "title": "Kind", "type": "string" }, "permission_rules": { "description": "Permission rules to bind for the agent (at most 100).", "examples": [ [ { "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] ], "items": { "$ref": "#/components/schemas/PermissionRuleSchema" }, "maxItems": 100, "title": "Permission Rules", "type": "array" } }, "required": [ "permission_rules", "digest", "kind", "key" ], "title": "ApiKeyConfirmSessionRequest", "type": "object" }, "ApiKeyCreateRequest": { "description": "Create request for api_key credentials.", "examples": [ { "api": { "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "field_name": "Authorization", "key": "sk_live_…", "location": "header", "name": "Stripe live key", "provider": "static", "type": "api_key" } ], "properties": { "api": { "$ref": "#/components/schemas/APIReferenceRequest", "description": "Loose (vendor, name, version) API identity tuple.", "examples": [ { "catalog_api_id": "stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" } ] }, "field_name": { "description": "Header or query-parameter name carrying the key.", "examples": [ "Authorization" ], "title": "Field Name", "type": "string" }, "key": { "description": "The API key secret. Stored encrypted; never returned after create.", "examples": [ "example-secret" ], "title": "Key", "type": "string", "x-sensitive": true }, "location": { "$ref": "#/components/schemas/CredentialLocation", "description": "Where to inject the key on upstream calls.", "examples": [ "header" ] }, "name": { "description": "Human-readable label for the credential.", "examples": [ "Stripe live key" ], "title": "Name", "type": "string" }, "provider": { "default": "static", "description": "Credential provider; 'static' for stored secrets.", "examples": [ "static" ], "title": "Provider", "type": "string" }, "runtime_config": { "anyOf": [ { "$ref": "#/components/schemas/RuntimeConfig" }, { "type": "null" } ], "description": "Per-upstream-call overrides; reserved and not currently applied.", "examples": [ { "headers": { "Stripe-Version": "2024-04-10" }, "query_params": { "locale": "en-GB" } } ] }, "server_variables": { "anyOf": [ { "additionalProperties": { "type": "string" }, "type": "object" }, { "type": "null" } ], "description": "OpenAPI server-variable values for URL template substitution (at most 20).", "examples": [ { "region": "eu" } ], "title": "Server Variables" }, "type": { "const": "api_key", "description": "Credential type; always `api_key`.", "examples": [ "api_key" ], "title": "Type", "type": "string" } }, "required": [ "type", "name", "api", "key", "location", "field_name" ], "title": "ApiKeyCreateRequest", "type": "object" }, "ApiKeyHistoryEntryResponse": { "description": "A single event in the API key audit trail.", "examples": [ { "action": "rotate", "actor_id": "usr_6968b3987ee4c3ec0b4ee3b9", "id": "aud_6968b3984275d71e90f7f09f", "occurred_at": "2026-01-20T14:00:00Z", "reason": "api_key_rotated" } ], "properties": { "action": { "description": "Audited action, for example `rotate` or `revoke`.", "examples": [ "rotate" ], "title": "Action", "type": "string" }, "actor_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the actor that performed the action.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "Actor Id" }, "id": { "description": "Unique ID of the audit entry.", "examples": [ "aud_6968b3984275d71e90f7f09f" ], "title": "Id", "type": "string" }, "occurred_at": { "description": "When the action occurred (RFC 3339).", "examples": [ "2026-01-20T14:00:00Z" ], "format": "date-time", "title": "Occurred At", "type": "string" }, "reason": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Structured reason: `api_key_rotated` or `api_key_revoked`.", "examples": [ "api_key_rotated" ], "title": "Reason" } }, "required": [ "id", "action", "occurred_at" ], "title": "ApiKeyHistoryEntryResponse", "type": "object" }, "ApiKeyHistoryResponse": { "description": "Audit trail of API key operations.", "examples": [ { "data": [ { "action": "rotate", "actor_id": "usr_6968b3987ee4c3ec0b4ee3b9", "id": "aud_6968b3984275d71e90f7f09f", "occurred_at": "2026-01-20T14:00:00Z", "reason": "api_key_rotated" } ] } ], "properties": { "data": { "description": "API key events, newest first.", "examples": [ [ { "action": "rotate", "actor_id": "usr_6968b3987ee4c3ec0b4ee3b9", "id": "aud_6968b3984275d71e90f7f09f", "occurred_at": "2026-01-20T14:00:00Z", "reason": "api_key_rotated" } ] ], "items": { "$ref": "#/components/schemas/ApiKeyHistoryEntryResponse" }, "title": "Data", "type": "array" } }, "required": [ "data" ], "title": "ApiKeyHistoryResponse", "type": "object" }, "ApiKeyInfoResponse": { "description": "API key metadata — retrievable even after revocation.", "examples": [ { "created_at": "2026-01-15T09:30:00Z", "created_by": "usr_6968b3987ee4c3ec0b4ee3b9", "id": "agc_6968b398c1d2e3f4a5b6c7d8", "rotated_at": "2026-01-20T14:00:00Z", "status": "active" } ], "properties": { "created_at": { "description": "When the API key was first created (RFC 3339).", "examples": [ "2026-01-15T09:30:00Z" ], "format": "date-time", "title": "Created At", "type": "string" }, "created_by": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the actor that created the API key.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "Created By" }, "id": { "description": "Unique ID of the API key record.", "examples": [ "agc_6968b398c1d2e3f4a5b6c7d8" ], "title": "Id", "type": "string" }, "rotated_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "When the API key was last rotated (RFC 3339); null if never rotated.", "examples": [ "2026-01-20T14:00:00Z" ], "title": "Rotated At" }, "status": { "description": "Key status: `active`, or `revoked` once revoked.", "examples": [ "active" ], "title": "Status", "type": "string" } }, "required": [ "id", "status", "created_at" ], "title": "ApiKeyInfoResponse", "type": "object" }, "ApiKeyResponse": { "description": "Response containing a plaintext API key (shown once).", "examples": [ { "key": "jak_example-secret" } ], "properties": { "key": { "description": "The plaintext API key; shown only once, store it securely.", "examples": [ "jak_example-secret" ], "title": "Key", "type": "string" } }, "required": [ "key" ], "title": "ApiKeyResponse", "type": "object" }, "ApiKeyUpdateRequest": { "description": "Update request for api_key credentials.", "examples": [ { "active": true, "field_name": "Authorization", "key": "example-secret", "location": "header", "name": "Stripe live key", "runtime_config": { "headers": { "Stripe-Version": "2024-04-10" }, "query_params": { "locale": "en-GB" } }, "server_variables": { "region": "eu" }, "type": "api_key" } ], "properties": { "active": { "anyOf": [ { "type": "boolean" }, { "type": "null" } ], "description": "Enable or disable the credential for injection; omit to leave unchanged.", "examples": [ true ], "title": "Active" }, "field_name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Immutable after create. Accepted for backward compatibility; if provided it must equal the stored value, otherwise the request is rejected. Recreate the credential to change the parameter name.", "examples": [ "Authorization" ], "title": "Field Name" }, "key": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Replacement API key; omit to leave unchanged.", "examples": [ "example-secret" ], "title": "Key", "x-sensitive": true }, "location": { "anyOf": [ { "$ref": "#/components/schemas/CredentialLocation" }, { "type": "null" } ], "description": "Immutable after create. Accepted for backward compatibility; if provided it must equal the stored value, otherwise the request is rejected. Recreate the credential to change the injection binding.", "examples": [ "header" ] }, "name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "New label for the credential; omit to leave unchanged.", "examples": [ "Stripe live key" ], "title": "Name" }, "runtime_config": { "anyOf": [ { "$ref": "#/components/schemas/RuntimeConfig" }, { "type": "null" } ], "description": "Per-upstream-call overrides; reserved and not currently applied.", "examples": [ { "headers": { "Stripe-Version": "2024-04-10" }, "query_params": { "locale": "en-GB" } } ] }, "server_variables": { "anyOf": [ { "additionalProperties": { "type": "string" }, "type": "object" }, { "type": "null" } ], "description": "Replacement OpenAPI server-variable values; omit to leave unchanged.", "examples": [ { "region": "eu" } ], "title": "Server Variables" }, "type": { "const": "api_key", "description": "Credential type; always `api_key`.", "examples": [ "api_key" ], "title": "Type", "type": "string" } }, "required": [ "type" ], "title": "ApiKeyUpdateRequest", "type": "object" }, "ApiLinksResponse": { "description": "Hypermedia links for a (local) API resource.", "examples": [ { "current_revision": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/revisions/3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "revisions": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/revisions", "self": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10" } ], "properties": { "current_revision": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "URL of the API's current revision; null when it has no live revision.", "examples": [ "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/revisions/3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" ], "title": "Current Revision" }, "revisions": { "description": "URL of the API's revision list.", "examples": [ "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/revisions" ], "title": "Revisions", "type": "string" }, "self": { "description": "URL of this API.", "examples": [ "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10" ], "title": "Self", "type": "string" } }, "required": [ "self", "revisions" ], "title": "ApiLinksResponse", "type": "object" }, "ApiListResponse": { "description": "Cursor-paginated list of APIs.", "examples": [ { "data": [ { "_links": { "current_revision": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/revisions/3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "revisions": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/revisions", "self": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10" }, "api": { "host": "api.stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "catalog_api_id": "stripe.com", "created_at": "2026-01-10T08:00:00Z", "current_revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "description": "Online payments platform: charges, customers, subscriptions and payouts.", "display_name": "Stripe", "icon_url": "https://stripe.com/favicon.ico", "operation_count": 412, "origin": "catalog", "revision_count": 2, "security_schemes": [ "http" ], "source_url": "https://raw.githubusercontent.com/jentic/jentic-public-apis/main/apis/openapi/stripe.com/main/2024-04-10/openapi.json", "update_available": false, "updated_at": "2026-01-15T09:30:00Z" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } ], "properties": { "data": { "description": "The page of APIs.", "examples": [ [ { "_links": { "current_revision": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/revisions/3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "revisions": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/revisions", "self": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10" }, "api": { "host": "api.stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "catalog_api_id": "stripe.com", "created_at": "2026-01-10T08:00:00Z", "current_revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "description": "Online payments platform: charges, customers, subscriptions and payouts.", "display_name": "Stripe", "icon_url": "https://stripe.com/favicon.ico", "operation_count": 412, "origin": "catalog", "revision_count": 2, "security_schemes": [ "http" ], "source_url": "https://raw.githubusercontent.com/jentic/jentic-public-apis/main/apis/openapi/stripe.com/main/2024-04-10/openapi.json", "update_available": false, "updated_at": "2026-01-15T09:30:00Z" } ] ], "items": { "$ref": "#/components/schemas/ApiResponse" }, "title": "Data", "type": "array" }, "has_more": { "description": "Whether more results exist after this page.", "examples": [ true ], "title": "Has More", "type": "boolean" }, "next_cursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Cursor for the next page; null when there are no more results.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Next Cursor" } }, "required": [ "data", "has_more" ], "title": "ApiListResponse", "type": "object" }, "ApiReferenceResponse": { "description": "Core API identifier triple plus derived host.", "examples": [ { "host": "api.stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" } ], "properties": { "host": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Host the API is served from, derived from its spec; null if it declares none.", "examples": [ "api.stripe.com" ], "title": "Host" }, "name": { "description": "Registry name of the API.", "examples": [ "stripe" ], "title": "Name", "type": "string" }, "vendor": { "description": "Registry vendor of the API.", "examples": [ "stripe.com" ], "title": "Vendor", "type": "string" }, "version": { "description": "Registry version of the API.", "examples": [ "2024-04-10" ], "title": "Version", "type": "string" } }, "required": [ "vendor", "name", "version", "host" ], "title": "ApiReferenceResponse", "type": "object" }, "ApiResponse": { "description": "Full API aggregate response.\n\n``GET /apis`` is the local registry — every item is an API imported into\nthis deployment. The public catalog of importable-but-not-yet-imported APIs\nis a separate surface (``GET /catalog``); the two are not blended.", "examples": [ { "_links": { "current_revision": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/revisions/3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "revisions": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/revisions", "self": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10" }, "api": { "host": "api.stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "catalog_api_id": "stripe.com", "created_at": "2026-01-10T08:00:00Z", "current_revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "description": "Online payments platform: charges, customers, subscriptions and payouts.", "display_name": "Stripe", "icon_url": "https://stripe.com/favicon.ico", "operation_count": 412, "origin": "catalog", "revision_count": 2, "security_schemes": [ "http" ], "source_url": "https://raw.githubusercontent.com/jentic/jentic-public-apis/main/apis/openapi/stripe.com/main/2024-04-10/openapi.json", "update_available": false, "updated_at": "2026-01-15T09:30:00Z" } ], "properties": { "_links": { "$ref": "#/components/schemas/ApiLinksResponse", "examples": [ { "current_revision": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/revisions/3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "revisions": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/revisions", "self": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10" } ] }, "api": { "$ref": "#/components/schemas/ApiReferenceResponse", "examples": [ { "host": "api.stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" } ] }, "catalog_api_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Catalog identity the API was imported from (`domain[/sub-api]`, for example `nytimes.com/article_search`); null for manual imports.", "examples": [ "stripe.com" ], "title": "Catalog Api Id" }, "created_at": { "description": "When the API was created (RFC 3339).", "examples": [ "2026-01-10T08:00:00Z" ], "format": "date-time", "title": "Created At", "type": "string" }, "current_revision_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the revision the API currently serves; null when it has no live revision.", "examples": [ "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" ], "title": "Current Revision Id" }, "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Free-text description of the API; null if not set.", "examples": [ "Online payments platform: charges, customers, subscriptions and payouts." ], "title": "Description" }, "display_name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Human-readable name to show for the API; null if not set.", "examples": [ "Stripe" ], "title": "Display Name" }, "icon_url": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "URL of an icon image for the API; null if not set.", "examples": [ "https://stripe.com/favicon.ico" ], "title": "Icon Url" }, "operation_count": { "description": "Number of operations the API exposes.", "examples": [ 412 ], "title": "Operation Count", "type": "integer" }, "origin": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Provenance of the current revision: `catalog` (imported from the public catalog), `overlay` (materialized from a confirmed overlay), or null (manual import).", "examples": [ "catalog" ], "title": "Origin" }, "revision_count": { "description": "Number of revisions recorded for the API.", "examples": [ 2 ], "title": "Revision Count", "type": "integer" }, "security_schemes": { "description": "Distinct security scheme types declared by the current revision.", "examples": [ [ "http" ] ], "items": { "type": "string" }, "title": "Security Schemes", "type": "array" }, "source_url": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Upstream spec URL backing the current revision, when known (catalog linkage).", "examples": [ "https://raw.githubusercontent.com/jentic/jentic-public-apis/main/apis/openapi/stripe.com/main/2024-04-10/openapi.json" ], "title": "Source Url" }, "update_available": { "default": false, "description": "Whether the upstream spec at `source_url` has a notified update this API hasn't adopted yet (Flow-3). Re-importing clears it.", "examples": [ false ], "title": "Update Available", "type": "boolean" }, "updated_at": { "description": "When the API was last updated (RFC 3339); equals `created_at` if never updated.", "examples": [ "2026-01-15T09:30:00Z" ], "format": "date-time", "title": "Updated At", "type": "string" } }, "required": [ "api", "catalog_api_id", "display_name", "description", "icon_url", "current_revision_id", "revision_count", "operation_count", "security_schemes", "created_at", "updated_at", "_links" ], "title": "ApiResponse", "type": "object" }, "ApiSourceInline": { "description": "Import source carrying raw OpenAPI/Arazzo content inline.", "examples": [ { "api_name": "stripe", "content": "{\"openapi\": \"3.1.0\", \"info\": {\"title\": \"Stripe API\", \"version\": \"2024-04-10\"}, \"paths\": {}}", "filename": "openapi.json", "submitted_by": "usr_6968b3987ee4c3ec0b4ee3b9", "type": "inline", "vendor": "stripe.com", "version": "2024-04-10" } ], "properties": { "api_name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Name to register the API under; taken from the document title when omitted.", "examples": [ "stripe" ], "title": "Api Name" }, "content": { "description": "Raw OpenAPI or Arazzo document as a JSON or YAML string.", "examples": [ "{\"openapi\": \"3.1.0\", \"info\": {\"title\": \"Stripe API\", \"version\": \"2024-04-10\"}, \"paths\": {}}" ], "title": "Content", "type": "string" }, "filename": { "description": "File name of the submitted document.", "examples": [ "openapi.json" ], "title": "Filename", "type": "string" }, "submitted_by": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Who the resulting revision is attributed to; defaults to the caller.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "Submitted By" }, "type": { "const": "inline", "description": "Source kind; always `inline` for this variant.", "examples": [ "inline" ], "title": "Type", "type": "string" }, "vendor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Vendor to register the API under; taken from the document when omitted.", "examples": [ "stripe.com" ], "title": "Vendor" }, "version": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Version to register the API under; taken from the document when omitted.", "examples": [ "2024-04-10" ], "title": "Version" } }, "required": [ "type", "content", "filename" ], "title": "ApiSourceInline", "type": "object" }, "ApiSourceUrl": { "description": "Import source pointing at a fetchable URL.", "examples": [ { "api_name": "stripe", "submitted_by": "usr_6968b3987ee4c3ec0b4ee3b9", "type": "url", "url": "https://raw.githubusercontent.com/jentic/jentic-public-apis/main/apis/openapi/stripe.com/main/2024-04-10/openapi.json", "vendor": "stripe.com", "version": "2024-04-10" } ], "properties": { "api_name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Name to register the API under; taken from the document title when omitted.", "examples": [ "stripe" ], "title": "Api Name" }, "submitted_by": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Who the resulting revision is attributed to; defaults to the caller.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "Submitted By" }, "type": { "const": "url", "description": "Source kind; always `url` for this variant.", "examples": [ "url" ], "title": "Type", "type": "string" }, "url": { "description": "URL the OpenAPI or Arazzo document is fetched from.", "examples": [ "https://raw.githubusercontent.com/jentic/jentic-public-apis/main/apis/openapi/stripe.com/main/2024-04-10/openapi.json" ], "format": "uri", "maxLength": 2083, "minLength": 1, "title": "Url", "type": "string" }, "vendor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Vendor to register the API under; taken from the document when omitted.", "examples": [ "stripe.com" ], "title": "Vendor" }, "version": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Version to register the API under; taken from the document when omitted.", "examples": [ "2024-04-10" ], "title": "Version" } }, "required": [ "type", "url" ], "title": "ApiSourceUrl", "type": "object" }, "ApiTargetRequest": { "additionalProperties": false, "description": "A registry API identity to connect a credential for.", "examples": [ { "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" } ], "properties": { "name": { "description": "API name", "examples": [ "stripe" ], "maxLength": 100, "minLength": 1, "title": "Name", "type": "string" }, "vendor": { "description": "API vendor (e.g. 'stripe-com')", "examples": [ "stripe.com" ], "maxLength": 100, "minLength": 1, "title": "Vendor", "type": "string" }, "version": { "description": "API version", "examples": [ "2024-04-10" ], "maxLength": 100, "minLength": 1, "title": "Version", "type": "string" } }, "required": [ "vendor", "name", "version" ], "title": "ApiTargetRequest", "type": "object" }, "ApiUpdateRequest": { "additionalProperties": false, "description": "Partial update payload for an API's presentation fields.", "examples": [ { "description": "Online payments platform: charges, customers, subscriptions and payouts.", "display_name": "Stripe", "icon_url": "https://stripe.com/favicon.ico" } ], "properties": { "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Free-text description of the API; null clears it.", "examples": [ "Online payments platform: charges, customers, subscriptions and payouts." ], "title": "Description" }, "display_name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Human-readable name to show for the API; null clears it.", "examples": [ "Stripe" ], "title": "Display Name" }, "icon_url": { "anyOf": [ { "format": "uri", "maxLength": 2083, "minLength": 1, "type": "string" }, { "type": "null" } ], "description": "URL of an icon image for the API; null clears it.", "examples": [ "https://stripe.com/favicon.ico" ], "title": "Icon Url" } }, "title": "ApiUpdateRequest", "type": "object" }, "AuditListResponse": { "description": "Paginated list of audit entries.", "examples": [ { "data": [ { "action": "update", "actor_id": "usr_6968b3987ee4c3ec0b4ee3b9", "actor_session_id": "5f0c2a9e-3b7d-4c1a-9e8f-2d6b4a1c7e30", "actor_type": "user", "after": { "active": true, "name": "Stripe production key" }, "before": { "active": true, "name": "Stripe test key" }, "diff": { "added": {}, "modified": { "name": { "new": "Stripe production key", "old": "Stripe test key" } }, "removed": {} }, "id": "aud_6968b3984275d71e90f7f09f", "ip_address": "203.0.113.42", "job_id": "job_6968b3985e8c9902207afaeb", "occurred_at": "2026-01-15T09:30:00Z", "origin": "dashboard", "reason": "Rotated to the production key", "request_id": "req_6968b3984d1c238d", "target_id": "cred_6968b39855d91a3561684b32", "target_parent_id": "agnt_6968b3984d1c238dbe7e2e29", "target_type": "credential", "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_5) AppleWebKit/605.1.15" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } ], "properties": { "data": { "description": "The page of audit entries.", "examples": [ [ { "action": "update", "actor_id": "usr_6968b3987ee4c3ec0b4ee3b9", "actor_session_id": "5f0c2a9e-3b7d-4c1a-9e8f-2d6b4a1c7e30", "actor_type": "user", "after": { "active": true, "name": "Stripe production key" }, "before": { "active": true, "name": "Stripe test key" }, "diff": { "added": {}, "modified": { "name": { "new": "Stripe production key", "old": "Stripe test key" } }, "removed": {} }, "id": "aud_6968b3984275d71e90f7f09f", "ip_address": "203.0.113.42", "job_id": "job_6968b3985e8c9902207afaeb", "occurred_at": "2026-01-15T09:30:00Z", "origin": "dashboard", "reason": "Rotated to the production key", "request_id": "req_6968b3984d1c238d", "target_id": "cred_6968b39855d91a3561684b32", "target_parent_id": "agnt_6968b3984d1c238dbe7e2e29", "target_type": "credential", "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_5) AppleWebKit/605.1.15" } ] ], "items": { "$ref": "#/components/schemas/AuditResponse" }, "title": "Data", "type": "array" }, "has_more": { "description": "Whether more results exist after this page.", "examples": [ true ], "title": "Has More", "type": "boolean" }, "next_cursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Cursor for the next page; null when there are no more results.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Next Cursor" } }, "required": [ "data", "has_more" ], "title": "AuditListResponse", "type": "object" }, "AuditResponse": { "description": "Audit entry representation in API responses.", "examples": [ { "action": "update", "actor_id": "usr_6968b3987ee4c3ec0b4ee3b9", "actor_session_id": "5f0c2a9e-3b7d-4c1a-9e8f-2d6b4a1c7e30", "actor_type": "user", "after": { "active": true, "name": "Stripe production key" }, "before": { "active": true, "name": "Stripe test key" }, "diff": { "added": {}, "modified": { "name": { "new": "Stripe production key", "old": "Stripe test key" } }, "removed": {} }, "id": "aud_6968b3984275d71e90f7f09f", "ip_address": "203.0.113.42", "job_id": "job_6968b3985e8c9902207afaeb", "occurred_at": "2026-01-15T09:30:00Z", "origin": "dashboard", "reason": "Rotated to the production key", "request_id": "req_6968b3984d1c238d", "target_id": "cred_6968b39855d91a3561684b32", "target_parent_id": "agnt_6968b3984d1c238dbe7e2e29", "target_type": "credential", "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_5) AppleWebKit/605.1.15" } ], "properties": { "action": { "description": "The audited action, e.g. `create`, `update` or `revoke`.", "examples": [ "update" ], "title": "Action", "type": "string" }, "actor_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the actor that performed the action; null if unknown.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "Actor Id" }, "actor_session_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Session the actor acted under; null if not recorded.", "examples": [ "5f0c2a9e-3b7d-4c1a-9e8f-2d6b4a1c7e30" ], "title": "Actor Session Id" }, "actor_type": { "description": "Kind of actor that performed the action, e.g. `user` or `agent`.", "examples": [ "user" ], "title": "Actor Type", "type": "string" }, "after": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "description": "Snapshot of the target after the action; null if none.", "examples": [ { "active": true, "name": "Stripe production key" } ], "title": "After" }, "before": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "description": "Snapshot of the target before the action; null if none.", "examples": [ { "active": true, "name": "Stripe test key" } ], "title": "Before" }, "diff": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "description": "Changes between `before` and `after`, keyed `added`, `removed` and `modified` (each modified key maps to `old`/`new`); null when nothing changed.", "examples": [ { "added": {}, "modified": { "name": { "new": "Stripe production key", "old": "Stripe test key" } }, "removed": {} } ], "title": "Diff" }, "id": { "description": "Unique ID of the audit entry.", "examples": [ "aud_6968b3984275d71e90f7f09f" ], "title": "Id", "type": "string" }, "ip_address": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Client IP address of the triggering request, if recorded.", "examples": [ "203.0.113.42" ], "title": "Ip Address" }, "job_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the job the action ran under, if any.", "examples": [ "job_6968b3985e8c9902207afaeb" ], "title": "Job Id" }, "occurred_at": { "description": "When the audited action happened (RFC 3339).", "examples": [ "2026-01-15T09:30:00Z" ], "format": "date-time", "title": "Occurred At", "type": "string" }, "origin": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Surface the action was initiated from, e.g. `dashboard`, `cli`, `api`, `agent`, `mcp` or `system`; null if not recorded.", "examples": [ "dashboard" ], "title": "Origin" }, "reason": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Reason recorded for the action; null if none was given.", "examples": [ "Rotated to the production key" ], "title": "Reason" }, "request_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the request that triggered the action, if recorded.", "examples": [ "req_6968b3984d1c238d" ], "title": "Request Id" }, "target_id": { "description": "ID of the entity the action was performed on.", "examples": [ "cred_6968b39855d91a3561684b32" ], "title": "Target Id", "type": "string" }, "target_parent_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the target's parent entity; null when not applicable.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Target Parent Id" }, "target_type": { "description": "Type of the entity the action was performed on.", "examples": [ "credential" ], "title": "Target Type", "type": "string" }, "trace_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Trace ID of the triggering request, if recorded.", "examples": [ "4bf92f3577b34da6a3ce929d0e0e4736" ], "title": "Trace Id" }, "user_agent": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "User-Agent of the triggering request, if recorded.", "examples": [ "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_5) AppleWebKit/605.1.15" ], "title": "User Agent" } }, "required": [ "id", "occurred_at", "action", "target_type", "target_id", "actor_type" ], "title": "AuditResponse", "type": "object" }, "AuditTargetType": { "description": "Entity types that can be the target of an audited action.", "enum": [ "revision", "permission", "user", "credential", "toolkit", "agent", "job", "organisation", "invite_token", "event", "execution_record", "service_account", "token", "overlay", "note", "api", "access_request", "toolkit_key", "credential_binding", "permission_rule_set", "session", "provider_config", "oauth_client", "oauth_grant", "oauth_app_registration" ], "title": "AuditTargetType", "type": "string" }, "AuthorizationCodeRegistrationCreateRequest": { "additionalProperties": false, "description": "Create request for an authorization-code registration.", "examples": [ { "api_vendor": "github", "authorize_url": "https://github.com/login/oauth/authorize", "catalog_api_id": "github.com/api.github.com", "client_id": "Iv1.a1b2c3d4", "client_secret": "", "default_scopes": [ "repo", "read:user" ], "display_name": "GitHub", "flow_kind": "authorization_code", "name": "MyOrg GitHub", "token_url": "https://github.com/login/oauth/access_token" } ], "properties": { "api_vendor": { "description": "Vendor registry key the registration connects.", "examples": [ "github" ], "maxLength": 100, "minLength": 1, "title": "Api Vendor", "type": "string" }, "authorize_url": { "description": "Authorization endpoint URL.", "examples": [ "https://github.com/login/oauth/authorize" ], "maxLength": 2048, "minLength": 1, "title": "Authorize Url", "type": "string" }, "catalog_api_id": { "description": "Catalog API slug this OAuth app targets (e.g. 'github.com/api.github.com'). The credential minted through this registration carries the same slug so its operations preview resolves against a real registered API.", "examples": [ "github.com/api.github.com" ], "maxLength": 255, "minLength": 1, "pattern": "^[^/].*/.*[^/]$", "title": "Catalog Api Id", "type": "string" }, "client_id": { "description": "OAuth client ID of the app.", "examples": [ "Iv1.a1b2c3d4" ], "maxLength": 255, "minLength": 1, "title": "Client Id", "type": "string" }, "client_secret": { "description": "OAuth client secret of the app; stored encrypted and never returned.", "examples": [ "example-secret" ], "maxLength": 4096, "minLength": 1, "title": "Client Secret", "type": "string", "x-sensitive": true }, "default_scopes": { "anyOf": [ { "items": { "maxLength": 255, "minLength": 1, "pattern": "^\\S+$", "type": "string" }, "type": "array" }, { "type": "null" } ], "description": "Scopes requested by default.", "examples": [ [ "repo", "read:user" ] ], "title": "Default Scopes" }, "display_name": { "description": "Vendor family label ('GitHub'), shown on picker cards.", "examples": [ "GitHub" ], "maxLength": 255, "minLength": 1, "title": "Display Name", "type": "string" }, "flow_kind": { "const": "authorization_code", "description": "OAuth flow the registration uses; always `authorization_code`.", "examples": [ "authorization_code" ], "title": "Flow Kind", "type": "string" }, "name": { "description": "Admin-chosen name of the registration.", "examples": [ "MyOrg GitHub" ], "maxLength": 255, "minLength": 1, "title": "Name", "type": "string" }, "token_url": { "description": "Token endpoint URL.", "examples": [ "https://github.com/login/oauth/access_token" ], "maxLength": 2048, "minLength": 1, "title": "Token Url", "type": "string" } }, "required": [ "name", "api_vendor", "catalog_api_id", "display_name", "flow_kind", "client_id", "client_secret", "authorize_url", "token_url" ], "title": "AuthorizationCodeRegistrationCreateRequest", "type": "object" }, "BasicAuthCreateRequest": { "description": "Create request for basic credentials.", "examples": [ { "api": { "catalog_api_id": "stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "name": "Stripe live key", "password": "example-secret", "provider": "static", "runtime_config": { "headers": { "Stripe-Version": "2024-04-10" }, "query_params": { "locale": "en-GB" } }, "server_variables": { "region": "eu" }, "type": "basic", "username": "svc-reporting" } ], "properties": { "api": { "$ref": "#/components/schemas/APIReferenceRequest", "examples": [ { "catalog_api_id": "stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" } ] }, "name": { "description": "Human-readable label for the credential.", "examples": [ "Stripe live key" ], "title": "Name", "type": "string" }, "password": { "description": "Password for HTTP Basic auth. Stored encrypted; never returned after create.", "examples": [ "example-secret" ], "title": "Password", "type": "string", "x-sensitive": true }, "provider": { "default": "static", "description": "Credential provider; 'static' for stored secrets.", "examples": [ "static" ], "title": "Provider", "type": "string" }, "runtime_config": { "anyOf": [ { "$ref": "#/components/schemas/RuntimeConfig" }, { "type": "null" } ], "description": "Per-upstream-call overrides; reserved and not currently applied.", "examples": [ { "headers": { "Stripe-Version": "2024-04-10" }, "query_params": { "locale": "en-GB" } } ] }, "server_variables": { "anyOf": [ { "additionalProperties": { "type": "string" }, "type": "object" }, { "type": "null" } ], "description": "OpenAPI server-variable values for URL template substitution (at most 20).", "examples": [ { "region": "eu" } ], "title": "Server Variables" }, "type": { "const": "basic", "description": "Credential type; always `basic`.", "examples": [ "basic" ], "title": "Type", "type": "string" }, "username": { "description": "Username sent with HTTP Basic auth.", "examples": [ "svc-reporting" ], "title": "Username", "type": "string" } }, "required": [ "type", "name", "api", "username", "password" ], "title": "BasicAuthCreateRequest", "type": "object" }, "BasicAuthUpdateRequest": { "description": "Update request for basic credentials.", "examples": [ { "active": true, "name": "Stripe live key", "password": "example-secret", "runtime_config": { "headers": { "Stripe-Version": "2024-04-10" }, "query_params": { "locale": "en-GB" } }, "server_variables": { "region": "eu" }, "type": "basic", "username": "svc-reporting" } ], "properties": { "active": { "anyOf": [ { "type": "boolean" }, { "type": "null" } ], "description": "Enable or disable the credential for injection; omit to leave unchanged.", "examples": [ true ], "title": "Active" }, "name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "New label for the credential; omit to leave unchanged.", "examples": [ "Stripe live key" ], "title": "Name" }, "password": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Replacement password; omit to leave unchanged.", "examples": [ "example-secret" ], "title": "Password", "x-sensitive": true }, "runtime_config": { "anyOf": [ { "$ref": "#/components/schemas/RuntimeConfig" }, { "type": "null" } ], "description": "Per-upstream-call overrides; reserved and not currently applied.", "examples": [ { "headers": { "Stripe-Version": "2024-04-10" }, "query_params": { "locale": "en-GB" } } ] }, "server_variables": { "anyOf": [ { "additionalProperties": { "type": "string" }, "type": "object" }, { "type": "null" } ], "description": "Replacement OpenAPI server-variable values; omit to leave unchanged.", "examples": [ { "region": "eu" } ], "title": "Server Variables" }, "type": { "const": "basic", "description": "Credential type; always `basic`.", "examples": [ "basic" ], "title": "Type", "type": "string" }, "username": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Replacement username; omit to leave unchanged.", "examples": [ "svc-reporting" ], "title": "Username" } }, "required": [ "type" ], "title": "BasicAuthUpdateRequest", "type": "object" }, "BasicConfirmSessionRequest": { "additionalProperties": false, "description": "Confirm a ``manual_basic`` session with the username and password to store.", "examples": [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "digest": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae", "expected_agent_id": "agnt_6968b3984d1c238dbe7e2e29", "kind": "basic", "password": "example-secret", "permission_rules": [ { "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ], "username": "svc-reporting" } ], "properties": { "agent_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Agent to bind when the session has none; ignored if the session already has one.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id" }, "digest": { "description": "Review digest echoed from the review data; a mismatch is 409 review_stale.", "examples": [ "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae" ], "maxLength": 64, "minLength": 1, "title": "Digest", "type": "string" }, "expected_agent_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Agent ID from the review the approver saw; a mismatch is 409 review_stale.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Expected Agent Id" }, "kind": { "const": "basic", "description": "Confirm variant; always `basic`.", "examples": [ "basic" ], "title": "Kind", "type": "string" }, "password": { "description": "Password to store; write-only.", "examples": [ "example-secret" ], "format": "password", "maxLength": 8192, "minLength": 1, "title": "Password", "type": "string", "writeOnly": true, "x-sensitive": true }, "permission_rules": { "description": "Permission rules to bind for the agent (at most 100).", "examples": [ [ { "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] ], "items": { "$ref": "#/components/schemas/PermissionRuleSchema" }, "maxItems": 100, "title": "Permission Rules", "type": "array" }, "username": { "description": "Username to store.", "examples": [ "svc-reporting" ], "maxLength": 255, "minLength": 1, "title": "Username", "type": "string" } }, "required": [ "permission_rules", "digest", "kind", "username", "password" ], "title": "BasicConfirmSessionRequest", "type": "object" }, "BearerConfirmSessionRequest": { "additionalProperties": false, "description": "Confirm a ``manual_bearer`` session with the bearer token to store.", "examples": [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "digest": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae", "expected_agent_id": "agnt_6968b3984d1c238dbe7e2e29", "kind": "bearer", "permission_rules": [ { "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ], "token": "example-secret" } ], "properties": { "agent_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Agent to bind when the session has none; ignored if the session already has one.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id" }, "digest": { "description": "Review digest echoed from the review data; a mismatch is 409 review_stale.", "examples": [ "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae" ], "maxLength": 64, "minLength": 1, "title": "Digest", "type": "string" }, "expected_agent_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Agent ID from the review the approver saw; a mismatch is 409 review_stale.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Expected Agent Id" }, "kind": { "const": "bearer", "description": "Confirm variant; always `bearer`.", "examples": [ "bearer" ], "title": "Kind", "type": "string" }, "permission_rules": { "description": "Permission rules to bind for the agent (at most 100).", "examples": [ [ { "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] ], "items": { "$ref": "#/components/schemas/PermissionRuleSchema" }, "maxItems": 100, "title": "Permission Rules", "type": "array" }, "token": { "description": "Bearer token to store; write-only.", "examples": [ "example-secret" ], "format": "password", "maxLength": 8192, "minLength": 1, "title": "Token", "type": "string", "writeOnly": true, "x-sensitive": true } }, "required": [ "permission_rules", "digest", "kind", "token" ], "title": "BearerConfirmSessionRequest", "type": "object" }, "BearerTokenCreateRequest": { "description": "Create request for bearer_token credentials.", "examples": [ { "api": { "catalog_api_id": "stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "name": "Stripe live key", "provider": "static", "runtime_config": { "headers": { "Stripe-Version": "2024-04-10" }, "query_params": { "locale": "en-GB" } }, "server_variables": { "region": "eu" }, "token": "example-secret", "type": "bearer_token" } ], "properties": { "api": { "$ref": "#/components/schemas/APIReferenceRequest", "examples": [ { "catalog_api_id": "stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" } ] }, "name": { "description": "Human-readable label for the credential.", "examples": [ "Stripe live key" ], "title": "Name", "type": "string" }, "provider": { "default": "static", "description": "Credential provider; 'static' for stored secrets.", "examples": [ "static" ], "title": "Provider", "type": "string" }, "runtime_config": { "anyOf": [ { "$ref": "#/components/schemas/RuntimeConfig" }, { "type": "null" } ], "description": "Per-upstream-call overrides; reserved and not currently applied.", "examples": [ { "headers": { "Stripe-Version": "2024-04-10" }, "query_params": { "locale": "en-GB" } } ] }, "server_variables": { "anyOf": [ { "additionalProperties": { "type": "string" }, "type": "object" }, { "type": "null" } ], "description": "OpenAPI server-variable values for URL template substitution (at most 20).", "examples": [ { "region": "eu" } ], "title": "Server Variables" }, "token": { "description": "The bearer token secret. Stored encrypted; never returned after create.", "examples": [ "example-secret" ], "title": "Token", "type": "string", "x-sensitive": true }, "type": { "const": "bearer_token", "description": "Credential type; always `bearer_token`.", "examples": [ "bearer_token" ], "title": "Type", "type": "string" } }, "required": [ "type", "name", "api", "token" ], "title": "BearerTokenCreateRequest", "type": "object" }, "BearerTokenUpdateRequest": { "description": "Update request for bearer_token credentials.", "examples": [ { "active": true, "name": "Stripe live key", "runtime_config": { "headers": { "Stripe-Version": "2024-04-10" }, "query_params": { "locale": "en-GB" } }, "server_variables": { "region": "eu" }, "token": "example-secret", "type": "bearer_token" } ], "properties": { "active": { "anyOf": [ { "type": "boolean" }, { "type": "null" } ], "description": "Enable or disable the credential for injection; omit to leave unchanged.", "examples": [ true ], "title": "Active" }, "name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "New label for the credential; omit to leave unchanged.", "examples": [ "Stripe live key" ], "title": "Name" }, "runtime_config": { "anyOf": [ { "$ref": "#/components/schemas/RuntimeConfig" }, { "type": "null" } ], "description": "Per-upstream-call overrides; reserved and not currently applied.", "examples": [ { "headers": { "Stripe-Version": "2024-04-10" }, "query_params": { "locale": "en-GB" } } ] }, "server_variables": { "anyOf": [ { "additionalProperties": { "type": "string" }, "type": "object" }, { "type": "null" } ], "description": "Replacement OpenAPI server-variable values; omit to leave unchanged.", "examples": [ { "region": "eu" } ], "title": "Server Variables" }, "token": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Replacement bearer token; omit to leave unchanged.", "examples": [ "example-secret" ], "title": "Token", "x-sensitive": true }, "type": { "const": "bearer_token", "description": "Credential type; always `bearer_token`.", "examples": [ "bearer_token" ], "title": "Type", "type": "string" } }, "required": [ "type" ], "title": "BearerTokenUpdateRequest", "type": "object" }, "Body_consentAgentCreate": { "examples": [ { "agent_name": "invoice-reconciler", "consent_token": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk", "create_state": "eyJfcHVycG9zZSI6ICJleGFtcGxlIn0=.5d41402abc4b2a76b9719d911017c592" } ], "properties": { "agent_name": { "description": "Name for the new agent; surrounding whitespace is trimmed.", "examples": [ "invoice-reconciler" ], "title": "Agent Name", "type": "string" }, "consent_token": { "description": "Single-use consent handle embedded in the consent page.", "examples": [ "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" ], "title": "Consent Token", "type": "string", "x-sensitive": true }, "create_state": { "description": "Signed single-use agent-creation token embedded in the consent page.", "examples": [ "eyJfcHVycG9zZSI6ICJleGFtcGxlIn0=.5d41402abc4b2a76b9719d911017c592" ], "title": "Create State", "type": "string", "x-sensitive": true } }, "required": [ "consent_token", "create_state", "agent_name" ], "title": "Body_consentAgentCreate", "type": "object" }, "CatalogEntryLinksResponse": { "description": "Hypermedia links for a catalog entry.", "examples": [ { "github": "https://github.com/jentic/jentic-public-apis/tree/main/apis/openapi/stripe.com", "import": "/catalog/stripe.com:import", "operations": "/catalog/stripe.com/operations", "self": "/catalog/stripe.com" } ], "properties": { "github": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Human-facing GitHub tree URL for the entry, when known.", "examples": [ "https://github.com/jentic/jentic-public-apis/tree/main/apis/openapi/stripe.com" ], "title": "Github" }, "import": { "description": "URL of the catalog import action (`POST /catalog/{api_id}:import`).", "examples": [ "https://jentic.example.com/catalog/stripe.com:import" ], "title": "Import", "type": "string" }, "operations": { "description": "URL of the entry's operation preview.", "examples": [ "https://jentic.example.com/catalog/stripe.com/operations" ], "title": "Operations", "type": "string" }, "self": { "description": "Canonical URL of this catalog entry.", "examples": [ "https://jentic.example.com/catalog/stripe.com" ], "title": "Self", "type": "string" } }, "required": [ "self", "operations", "import" ], "title": "CatalogEntryLinksResponse", "type": "object" }, "CatalogEntryResponse": { "description": "A single browsable catalog entry.", "examples": [ { "_links": { "import": "/catalog/stripe.com:import", "operations": "/catalog/stripe.com/operations", "self": "/catalog/stripe.com" }, "api_id": "stripe.com", "path": "apis/openapi/stripe.com", "registered": false, "spec_url": "https://raw.githubusercontent.com/jentic/jentic-public-apis/main/apis/openapi/stripe.com/main/2024-01-01/openapi.json", "vendor": "stripe.com" } ], "properties": { "_links": { "$ref": "#/components/schemas/CatalogEntryLinksResponse", "examples": [ { "github": "https://github.com/jentic/jentic-public-apis/tree/main/apis/openapi/stripe.com", "import": "/catalog/stripe.com:import", "operations": "/catalog/stripe.com/operations", "self": "/catalog/stripe.com" } ] }, "api_id": { "description": "Catalog identity of the API (manifest domain, e.g. `stripe.com`).", "examples": [ "stripe.com" ], "title": "Api Id", "type": "string" }, "path": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Manifest path of the entry within the public-APIs repo.", "examples": [ "apis/openapi/stripe.com" ], "title": "Path" }, "registered": { "description": "Whether this entry is already imported locally — its `spec_url` backs a non-archived revision in `GET /apis`.", "examples": [ true ], "title": "Registered", "type": "boolean" }, "spec_url": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Fetchable OpenAPI spec URL the entry resolves to (used for import + coverage).", "examples": [ "https://raw.githubusercontent.com/jentic/jentic-public-apis/main/apis/openapi/stripe.com/main/2024-04-10/openapi.json" ], "title": "Spec Url" }, "update_available": { "default": false, "description": "Whether this (registered) entry has an upstream spec update the local revision hasn't adopted yet. Always false for unregistered entries.", "examples": [ false ], "title": "Update Available", "type": "boolean" }, "vendor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Registrable-domain vendor derived from `api_id` (e.g. `stripe.com`).", "examples": [ "stripe.com" ], "title": "Vendor" } }, "required": [ "api_id", "vendor", "path", "spec_url", "registered", "_links" ], "title": "CatalogEntryResponse", "type": "object" }, "CatalogListResponse": { "description": "List of catalog entries plus status fields for the Discover status row.", "examples": [ { "catalog_total": 5231, "data": [], "has_more": true, "manifest_age_seconds": 3600, "next_cursor": "eyJpZCI6ICJzdHJpcGUuY29tIn0=", "registered_count": 12 } ], "properties": { "catalog_total": { "description": "Total entries in the whole manifest (pre-filter, pre-page).", "examples": [ 5231 ], "title": "Catalog Total", "type": "integer" }, "data": { "description": "The page of catalog entries.", "examples": [ [ { "_links": { "import": "/catalog/stripe.com:import", "operations": "/catalog/stripe.com/operations", "self": "/catalog/stripe.com" }, "api_id": "stripe.com", "path": "apis/openapi/stripe.com", "registered": false, "spec_url": "https://raw.githubusercontent.com/jentic/jentic-public-apis/main/apis/openapi/stripe.com/main/2024-01-01/openapi.json", "vendor": "stripe.com" } ] ], "items": { "$ref": "#/components/schemas/CatalogEntryResponse" }, "title": "Data", "type": "array" }, "has_more": { "default": false, "description": "Whether another page follows.", "examples": [ true ], "title": "Has More", "type": "boolean" }, "manifest_age_seconds": { "anyOf": [ { "type": "integer" }, { "type": "null" } ], "description": "Age of the cached manifest in seconds, or null when the cache is empty.", "examples": [ 3600 ], "title": "Manifest Age Seconds" }, "next_cursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Opaque keyset cursor for the next page (null when done).", "examples": [ "eyJpZCI6ICJzdHJpcGUuY29tIn0=" ], "title": "Next Cursor" }, "outdated_count": { "default": 0, "description": "Count of whole-manifest registered entries with an upstream update available.", "examples": [ 1 ], "title": "Outdated Count", "type": "integer" }, "registered_count": { "description": "Count of whole-manifest entries already imported locally.", "examples": [ 12 ], "title": "Registered Count", "type": "integer" } }, "required": [ "data", "catalog_total", "registered_count" ], "title": "CatalogListResponse", "type": "object" }, "CatalogRefreshResponse": { "description": "Acknowledgement of a manifest refresh.", "examples": [ { "count": 5231, "status": "refreshed" } ], "properties": { "count": { "description": "Number of entries in the freshly fetched manifest.", "examples": [ 5231 ], "title": "Count", "type": "integer" }, "status": { "default": "refreshed", "description": "Refresh outcome marker.", "examples": [ "refreshed" ], "title": "Status", "type": "string" } }, "required": [ "count" ], "title": "CatalogRefreshResponse", "type": "object" }, "CatalogSnoozeRequest": { "description": "Body for ``POST /catalog/{api_id}:snooze`` (C1, #925).\n\n``snoozed_until`` is optional: omit or send ``null`` to mute-until-newer (the primary\nper-API affordance — the badge re-lights only when a *newer* upstream digest lands);\nprovide an ISO-8601 timestamp for a time-boxed snooze that lapses at that instant.", "examples": [ { "snoozed_until": "2026-02-01T00:00:00Z" } ], "properties": { "snoozed_until": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "Optional expiry for the snooze (ISO-8601). Null = mute until a newer upstream digest is observed.", "examples": [ "2026-02-01T00:00:00Z" ], "title": "Snoozed Until" } }, "title": "CatalogSnoozeRequest", "type": "object" }, "ChangePasswordRequest": { "description": "Payload for changing own password.", "examples": [ { "current_password": "example-password", "new_password": "example-new-password" } ], "properties": { "current_password": { "description": "The caller's current password.", "examples": [ "example-password" ], "maxLength": 128, "minLength": 1, "title": "Current Password", "type": "string", "x-sensitive": true }, "new_password": { "description": "The new password to set.", "examples": [ "example-new-password" ], "maxLength": 128, "minLength": 12, "title": "New Password", "type": "string", "x-sensitive": true } }, "required": [ "current_password", "new_password" ], "title": "ChangePasswordRequest", "type": "object" }, "ClaimRequest": { "description": "Request body for claiming ownership of a self-registered agent.", "examples": [ { "token": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" } ], "properties": { "token": { "description": "Single-use claim token returned when the agent self-registered.", "examples": [ "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" ], "maxLength": 512, "minLength": 1, "title": "Token", "type": "string", "x-sensitive": true } }, "required": [ "token" ], "title": "ClaimRequest", "type": "object" }, "ConnectRequestBody": { "description": "Request body for initiating a credential connect flow.", "examples": [ { "extra": { "prompt": "consent" }, "scopes": [ "read_write" ] } ], "properties": { "extra": { "additionalProperties": { "type": "string" }, "description": "Additional provider-specific connect parameters.", "examples": [ { "prompt": "consent" } ], "title": "Extra", "type": "object" }, "scopes": { "description": "OAuth scopes to request.", "examples": [ [ "read_write" ] ], "items": { "type": "string" }, "title": "Scopes", "type": "array" } }, "title": "ConnectRequestBody", "type": "object" }, "ConnectSessionListResponse": { "description": "Cursor-paginated envelope of connect-session summaries.", "examples": [ { "data": [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "connected_as": "octocat", "created_at": "2026-01-15T09:30:00Z", "credential_id": "cred_6968b39855d91a3561684b32", "error_code": "access_denied", "reason": "Needs read access to triage issues in the platform repo.", "requested_by_actor_id": "agnt_6968b3984d1c238dbe7e2e29", "session_id": "cs_6968b3983b8b91c75627bee5", "state": "connected", "vendor_display_name": "GitHub", "vendor_key": "github" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } ], "properties": { "data": { "description": "The page of connect sessions.", "examples": [ [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "connected_as": "octocat", "created_at": "2026-01-15T09:30:00Z", "credential_id": "cred_6968b39855d91a3561684b32", "error_code": "access_denied", "reason": "Needs read access to triage issues in the platform repo.", "requested_by_actor_id": "agnt_6968b3984d1c238dbe7e2e29", "session_id": "cs_6968b3983b8b91c75627bee5", "state": "connected", "vendor_display_name": "GitHub", "vendor_key": "github" } ] ], "items": { "$ref": "#/components/schemas/ConnectSessionSummaryResponse" }, "title": "Data", "type": "array" }, "has_more": { "description": "Whether more results exist after this page.", "examples": [ true ], "title": "Has More", "type": "boolean" }, "next_cursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Cursor for the next page; null when there are no more results.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Next Cursor" } }, "required": [ "data", "has_more" ], "title": "ConnectSessionListResponse", "type": "object" }, "ConnectSessionSummaryResponse": { "description": "Slim list row for the console — deliberately excludes ``poll_token``.", "examples": [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "connected_as": "octocat", "created_at": "2026-01-15T09:30:00Z", "credential_id": "cred_6968b39855d91a3561684b32", "error_code": "access_denied", "reason": "Needs read access to triage issues in the platform repo.", "requested_by_actor_id": "agnt_6968b3984d1c238dbe7e2e29", "session_id": "cs_6968b3983b8b91c75627bee5", "state": "connected", "vendor_display_name": "GitHub", "vendor_key": "github" } ], "properties": { "agent_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the agent the credential is bound to on confirm; null when unbound.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id" }, "connected_as": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Upstream account the credential connected as; null until known.", "examples": [ "octocat" ], "title": "Connected As" }, "created_at": { "description": "When the session was created (RFC 3339).", "examples": [ "2026-01-15T09:30:00Z" ], "format": "date-time", "title": "Created At", "type": "string" }, "credential_id": { "description": "ID of the session's credential (pending until the session connects).", "examples": [ "cred_6968b39855d91a3561684b32" ], "title": "Credential Id", "type": "string" }, "error_code": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Reserved for a failure code; always null on listed sessions.", "examples": [ "access_denied" ], "title": "Error Code" }, "reason": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Free-text reason given when the session was started.", "examples": [ "Needs read access to triage issues in the platform repo." ], "title": "Reason" }, "requested_by_actor_id": { "description": "ID of the actor that started the session.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Requested By Actor Id", "type": "string" }, "session_id": { "description": "Unique ID of the connect session.", "examples": [ "cs_6968b3983b8b91c75627bee5" ], "title": "Session Id", "type": "string" }, "state": { "description": "Current lifecycle state of the session.", "enum": [ "created", "awaiting_app", "polling", "connected" ], "examples": [ "connected" ], "title": "State", "type": "string" }, "vendor_display_name": { "description": "Display name of the vendor.", "examples": [ "GitHub" ], "title": "Vendor Display Name", "type": "string" }, "vendor_key": { "description": "Vendor registry key the session connects.", "examples": [ "github" ], "title": "Vendor Key", "type": "string" } }, "required": [ "session_id", "state", "vendor_key", "vendor_display_name", "requested_by_actor_id", "created_at", "credential_id" ], "title": "ConnectSessionSummaryResponse", "type": "object" }, "ConsentAgentStatusResponse": { "description": "Minimal tri-state for the consent page's pending-agent awaiting page (P4).\n\nDeliberately carries nothing else — no agent name, owner, or scopes — so\nthe anonymous poll endpoint cannot be used to read agent details. The\npoll is keyed by a signed ``agent-status`` blob bound to one agent id,\nnever a bare id, and non-terminal lifecycle states (disabled, archived, a\nvanished row) all read as ``pending`` so the endpoint is not a lifecycle\noracle either.", "examples": [ { "status": "pending" } ], "properties": { "status": { "description": "Approval state of the agent: `pending`, `approved` or `denied`; any state other than approved or denied reads as `pending`.", "enum": [ "pending", "approved", "denied" ], "examples": [ "pending" ], "title": "Status", "type": "string" } }, "required": [ "status" ], "title": "ConsentAgentStatusResponse", "type": "object" }, "CreateAdminRequest": { "description": "Payload for first-run admin creation (one-time setup).", "examples": [ { "email": "admin@example.com", "first_name": "Ada", "last_name": "Lovelace", "password": "example-password" } ], "properties": { "email": { "description": "Email address of the first admin.", "examples": [ "admin@example.com" ], "maxLength": 320, "minLength": 1, "title": "Email", "type": "string" }, "first_name": { "default": "Admin", "description": "First name of the first admin; defaults to `Admin`.", "examples": [ "Ada" ], "maxLength": 100, "minLength": 1, "title": "First Name", "type": "string" }, "last_name": { "default": "User", "description": "Last name of the first admin; defaults to `User`.", "examples": [ "Lovelace" ], "maxLength": 100, "minLength": 1, "title": "Last Name", "type": "string" }, "password": { "description": "Password for the first admin.", "examples": [ "example-password" ], "maxLength": 128, "minLength": 12, "title": "Password", "type": "string", "x-sensitive": true } }, "required": [ "email", "password" ], "title": "CreateAdminRequest", "type": "object" }, "CredentialAgentListResponse": { "description": "Paginated list of agents directly bound to a credential.", "examples": [ { "data": [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "agent_name": "billing-assistant", "bound_at": "2026-01-15T09:30:00Z", "rule_set_id": "prs_6968b3987c22b63e87e79f05", "status": "active", "suspended": false } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } ], "properties": { "data": { "description": "The page of bound agents.", "examples": [ [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "agent_name": "billing-assistant", "bound_at": "2026-01-15T09:30:00Z", "rule_set_id": "prs_6968b3987c22b63e87e79f05", "status": "active", "suspended": false } ] ], "items": { "$ref": "#/components/schemas/CredentialAgentResponse" }, "title": "Data", "type": "array" }, "has_more": { "description": "Whether more results exist after this page.", "examples": [ true ], "title": "Has More", "type": "boolean" }, "next_cursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Cursor for the next page; null when there are no more results.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Next Cursor" } }, "required": [ "data", "has_more" ], "title": "CredentialAgentListResponse", "type": "object" }, "CredentialAgentResponse": { "description": "Agent directly bound to a credential (theme 5 phase 1).", "examples": [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "agent_name": "billing-assistant", "bound_at": "2026-01-15T09:30:00Z", "rule_set_id": "prs_6968b3987c22b63e87e79f05", "status": "active", "suspended": false } ], "properties": { "agent_id": { "description": "ID of the bound agent.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" }, "agent_name": { "description": "Name of the bound agent.", "examples": [ "billing-assistant" ], "title": "Agent Name", "type": "string" }, "bound_at": { "description": "When the agent was bound to the credential (RFC 3339).", "examples": [ "2026-01-15T09:30:00Z" ], "format": "date-time", "title": "Bound At", "type": "string" }, "rule_set_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Shared permission rule set this binding points at, if any. While attached, the set's ordered list is the binding's effective policy; null means the binding's inline rules apply.", "examples": [ "prs_6968b3987c22b63e87e79f05" ], "title": "Rule Set Id" }, "status": { "description": "Status of the bound agent.", "examples": [ "active" ], "title": "Status", "type": "string" }, "suspended": { "description": "True when the binding is soft-suspended (reversible cut-off): the binding and its rules survive, but the agent cannot execute through this credential until resumed.", "examples": [ false ], "title": "Suspended", "type": "boolean" } }, "required": [ "agent_id", "agent_name", "status", "bound_at", "suspended" ], "title": "CredentialAgentResponse", "type": "object" }, "CredentialBindRequest": { "description": "Request body for directly binding a credential to an agent.", "examples": [ { "credential_id": "cred_6968b39855d91a3561684b32" } ], "properties": { "credential_id": { "description": "ID of the credential to bind to the agent.", "examples": [ "cred_6968b39855d91a3561684b32" ], "maxLength": 255, "minLength": 1, "title": "Credential Id", "type": "string" } }, "required": [ "credential_id" ], "title": "CredentialBindRequest", "type": "object" }, "CredentialBindingEntry": { "description": "Direct agent↔credential binding summary for the /me response (theme 5 phase 1).", "examples": [ { "bound_at": "2026-01-15T09:30:00Z", "credential_id": "cred_6968b39855d91a3561684b32", "name": "Stripe production key", "rule_set_id": "prs_6968b3987c22b63e87e79f05", "serves": [ { "api_name": "stripe", "api_vendor": "stripe.com", "api_version": "2024-04-10" } ], "suspended": false, "suspended_reason": "api_deleted" } ], "properties": { "bound_at": { "description": "When the credential was bound (RFC 3339).", "examples": [ "2026-01-15T09:30:00Z" ], "format": "date-time", "title": "Bound At", "type": "string" }, "credential_id": { "description": "ID of the bound credential.", "examples": [ "cred_6968b39855d91a3561684b32" ], "title": "Credential Id", "type": "string" }, "name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Name of the bound credential; null if it no longer exists or cannot be resolved.", "examples": [ "Stripe production key" ], "title": "Name" }, "rule_set_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the shared permission rule set attached; null when inline rules apply.", "examples": [ "prs_6968b3987c22b63e87e79f05" ], "title": "Rule Set Id" }, "serves": { "default": [], "description": "The APIs the bound credential serves; empty if unresolvable.", "examples": [ [ { "api_name": "stripe", "api_vendor": "stripe.com", "api_version": "2024-04-10" } ] ], "items": { "$ref": "#/components/schemas/ServedApiRef" }, "title": "Serves", "type": "array" }, "suspended": { "default": false, "description": "Whether the binding is suspended; the agent cannot execute through it until resumed.", "examples": [ false ], "title": "Suspended", "type": "boolean" }, "suspended_reason": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Why the binding is suspended: null for a manual suspension, `api_deleted` when the API the credential serves was deleted.", "examples": [ "api_deleted" ], "title": "Suspended Reason" } }, "required": [ "credential_id", "bound_at" ], "title": "CredentialBindingEntry", "type": "object" }, "CredentialBindingListResponse": { "description": "List of direct credential bindings.", "examples": [ { "data": [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "bound_at": "2026-01-15T09:30:00Z", "credential_id": "cred_6968b39855d91a3561684b32", "id": "acb_6968b3989a4f1c2e7d3b5a60", "name": "Stripe production key", "rule_set_id": "prs_6968b3987c22b63e87e79f05", "serves": [ { "api_name": "stripe", "api_vendor": "stripe.com", "api_version": "2024-04-10" } ], "suspended": false, "suspended_reason": "api_deleted" } ] } ], "properties": { "data": { "description": "The agent's direct credential bindings.", "examples": [ [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "bound_at": "2026-01-15T09:30:00Z", "credential_id": "cred_6968b39855d91a3561684b32", "id": "acb_6968b3989a4f1c2e7d3b5a60", "name": "Stripe production key", "rule_set_id": "prs_6968b3987c22b63e87e79f05", "serves": [ { "api_name": "stripe", "api_vendor": "stripe.com", "api_version": "2024-04-10" } ], "suspended": false, "suspended_reason": "api_deleted" } ] ], "items": { "$ref": "#/components/schemas/CredentialBindingResponse" }, "title": "Data", "type": "array" } }, "required": [ "data" ], "title": "CredentialBindingListResponse", "type": "object" }, "CredentialBindingResponse": { "description": "Direct agent↔credential binding representation in API responses.", "examples": [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "bound_at": "2026-01-15T09:30:00Z", "credential_id": "cred_6968b39855d91a3561684b32", "id": "acb_6968b3989a4f1c2e7d3b5a60", "name": "Stripe production key", "rule_set_id": "prs_6968b3987c22b63e87e79f05", "serves": [ { "api_name": "stripe", "api_vendor": "stripe.com", "api_version": "2024-04-10" } ], "suspended": false, "suspended_reason": "api_deleted" } ], "properties": { "agent_id": { "description": "ID of the agent the credential is bound to.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" }, "bound_at": { "description": "When the credential was bound (RFC 3339).", "examples": [ "2026-01-15T09:30:00Z" ], "format": "date-time", "title": "Bound At", "type": "string" }, "credential_id": { "description": "ID of the bound credential.", "examples": [ "cred_6968b39855d91a3561684b32" ], "title": "Credential Id", "type": "string" }, "id": { "description": "Unique ID of the binding.", "examples": [ "acb_6968b3989a4f1c2e7d3b5a60" ], "title": "Id", "type": "string" }, "name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Name of the bound credential; null if it cannot be resolved.", "examples": [ "Stripe production key" ], "title": "Name" }, "rule_set_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the shared permission rule set attached; null when inline rules apply.", "examples": [ "prs_6968b3987c22b63e87e79f05" ], "title": "Rule Set Id" }, "serves": { "default": [], "description": "The APIs the bound credential serves; empty if unresolvable.", "examples": [ [ { "api_name": "stripe", "api_vendor": "stripe.com", "api_version": "2024-04-10" } ] ], "items": { "$ref": "#/components/schemas/ServedApiRef" }, "title": "Serves", "type": "array" }, "suspended": { "description": "Whether the binding is suspended, cutting off the agent's access to it.", "examples": [ false ], "title": "Suspended", "type": "boolean" }, "suspended_reason": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Why the binding is suspended: null for a manual suspension, `api_deleted` when the API the credential serves was deleted; cleared on resume.", "examples": [ "api_deleted" ], "title": "Suspended Reason" } }, "required": [ "id", "agent_id", "credential_id", "bound_at", "suspended" ], "title": "CredentialBindingResponse", "type": "object" }, "CredentialCreateResponse": { "description": "Create response: redacted + secret shown once.", "examples": [ { "credential": { "active": true, "api": { "name": "stripe", "vendor": "stripe-com", "version": "2024-04-10" }, "created_at": "2026-01-15T09:30:00Z", "credential_id": "cred_01HZX9...", "name": "Stripe live key", "provider": "static", "type": "api_key" }, "secret": { "key": "sk_live_…" } }, { "credential": { "active": true, "api": { "name": "posthog-api", "vendor": "posthog-com", "version": "1.0" }, "created_at": "2026-01-15T09:31:00Z", "credential_id": "cred_01HZXA...", "name": "PostHog personal key", "provider": "static", "type": "bearer_token" }, "secret": { "token": "phx_…" }, "warnings": [ "API scope 'posthog-com/posthog-api/1.0' matches no imported API — executions using this credential will fail. Import a matching API, or delete this credential and re-create it scoped to an imported identity; imported APIs for this vendor: posthog-com/posthog-com-posthog-api (1.0)" ] } ], "properties": { "credential": { "$ref": "#/components/schemas/CredentialRedactedResponse", "examples": [ { "active": true, "api": { "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "created_at": "2026-01-15T09:30:00Z", "credential_id": "cred_01HZX9...", "details": { "field_name": "Authorization", "hint": "…live_abcd", "location": "header" }, "name": "Stripe live key", "provider": "static", "type": "api_key" } ] }, "secret": { "additionalProperties": true, "description": "Type-specific secret material, returned only in this create response.", "examples": [ { "key": "example-secret" } ], "title": "Secret", "type": "object", "x-sensitive": true }, "warnings": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "description": "Advisory warnings from create — e.g. the credential's API scope matches no imported API identity, so execution through it would fail until a matching API is imported. The credential is created regardless; null when there is nothing to flag.", "examples": [ [ "API scope 'stripe.com/stripe/2024-04-10' matches no imported API." ] ], "title": "Warnings" } }, "required": [ "credential", "secret" ], "title": "CredentialCreateResponse", "type": "object" }, "CredentialListResponse": { "description": "Paginated list of credentials.", "examples": [ { "data": [ { "active": true, "api": { "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "created_at": "2026-01-15T09:30:00Z", "credential_id": "cred_01HZX9...", "details": { "field_name": "Authorization", "hint": "…live_abcd", "location": "header" }, "name": "Stripe live key", "provider": "static", "type": "api_key" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } ], "properties": { "data": { "description": "The page of credentials.", "examples": [ [ { "active": true, "api": { "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "created_at": "2026-01-15T09:30:00Z", "credential_id": "cred_01HZX9...", "details": { "field_name": "Authorization", "hint": "…live_abcd", "location": "header" }, "name": "Stripe live key", "provider": "static", "type": "api_key" } ] ], "items": { "$ref": "#/components/schemas/CredentialRedactedResponse" }, "title": "Data", "type": "array" }, "has_more": { "description": "Whether more results exist after this page.", "examples": [ true ], "title": "Has More", "type": "boolean" }, "next_cursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Cursor for the next page; null when there are no more results.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Next Cursor" } }, "required": [ "data", "has_more" ], "title": "CredentialListResponse", "type": "object" }, "CredentialLocation": { "description": "Where an API-key credential is injected into a request.", "enum": [ "header", "query", "cookie" ], "title": "CredentialLocation", "type": "string" }, "CredentialRedactedResponse": { "description": "Redacted credential response (for read/list/patch).", "examples": [ { "active": true, "api": { "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "created_at": "2026-01-15T09:30:00Z", "credential_id": "cred_01HZX9...", "details": { "field_name": "Authorization", "hint": "…live_abcd", "location": "header" }, "name": "Stripe live key", "provider": "static", "type": "api_key" } ], "properties": { "active": { "description": "Whether the credential is enabled for injection.", "examples": [ true ], "title": "Active", "type": "boolean" }, "api": { "$ref": "#/components/schemas/APIReference", "description": "The (vendor, name, version) API this credential targets.", "examples": [ { "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" } ] }, "catalog_api_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Catalog identity slug of the target API (`domain[/sub-api]`), when recorded at create time. Display-only; null for older credentials.", "examples": [ "stripe.com" ], "title": "Catalog Api Id" }, "created_at": { "description": "Creation timestamp (UTC).", "examples": [ "2026-01-15T09:30:00Z" ], "format": "date-time", "title": "Created At", "type": "string" }, "created_by": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Identity that created the credential (its owner).", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "Created By" }, "credential_id": { "description": "Stable credential identifier, prefixed `cred_`.", "examples": [ "cred_6968b39855d91a3561684b32" ], "title": "Credential Id", "type": "string" }, "details": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "description": "Redacted, type-specific projection (hints/last-N chars; never the secret). For oauth2: client_id, token_url, grant_type (authorization_code | client_credentials), scopes, and — for authorization_code only — `connected`, whether the interactive sign-in completed and is still usable (null for other grants).", "examples": [ { "client_id": "ca_example123", "connected": true, "grant_type": "authorization_code", "scopes": [ "read_write" ], "token_url": "https://connect.stripe.com/oauth/token" } ], "title": "Details" }, "name": { "description": "Human-readable label.", "examples": [ "Stripe Connect" ], "title": "Name", "type": "string" }, "oauth_app_registration_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Id of the shared ``oauth_app_registrations`` row this credential was minted through, if any. Null for legacy embedded OAuth credentials and every non-OAuth type.", "examples": [ "oar_6968b39821e5f89a6975f501" ], "title": "Oauth App Registration Id" }, "oauth_app_registration_name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Admin-facing name of the shared OAuth app registration this credential was minted through. Null when the credential is not backed by a shared registration.", "examples": [ "MyOrg Stripe" ], "title": "Oauth App Registration Name" }, "provider": { "description": "Credential provider; 'static' for stored secrets.", "examples": [ "direct_oauth2" ], "title": "Provider", "type": "string" }, "provider_account_ref": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Opaque reference to the provider account, when applicable.", "examples": [ "acct_1Nv0FGQ9RKHgCVdK" ], "title": "Provider Account Ref" }, "server_variables": { "anyOf": [ { "additionalProperties": { "type": "string" }, "type": "object" }, { "type": "null" } ], "description": "OpenAPI server-variable values for URL template substitution.", "examples": [ { "region": "eu" } ], "title": "Server Variables" }, "type": { "$ref": "#/components/schemas/CredentialType", "description": "Credential auth type (api_key, bearer_token, basic, oauth2).", "examples": [ "oauth2" ] }, "updated_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "Last update timestamp (UTC).", "examples": [ "2026-01-20T14:05:00Z" ], "title": "Updated At" } }, "required": [ "credential_id", "type", "name", "api", "provider", "active", "created_at" ], "title": "CredentialRedactedResponse", "type": "object" }, "CredentialType": { "description": "Wire-level credential type used by the provider abstraction.", "enum": [ "bearer_token", "api_key", "basic", "oauth2", "no_auth", "sigv4" ], "title": "CredentialType", "type": "string" }, "CurrentUserResponse": { "description": "Current user profile.", "examples": [ { "active": true, "created_at": "2026-01-15T09:30:00Z", "email": "ada@example.com", "first_name": "Ada", "id": "usr_6968b3987ee4c3ec0b4ee3b9", "last_name": "Lovelace", "must_change_password": false, "permissions": [ "users:write", "users:read", "agents:read" ], "updated_at": "2026-01-20T14:05:00Z" } ], "properties": { "active": { "description": "Whether the user account is enabled.", "examples": [ true ], "title": "Active", "type": "boolean" }, "created_at": { "description": "When the user was created (RFC 3339).", "examples": [ "2026-01-15T09:30:00Z" ], "format": "date-time", "title": "Created At", "type": "string" }, "email": { "description": "Email address of the user.", "examples": [ "ada@example.com" ], "title": "Email", "type": "string" }, "first_name": { "description": "First name of the user.", "examples": [ "Ada" ], "title": "First Name", "type": "string" }, "id": { "description": "Unique ID of the user.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "Id", "type": "string" }, "last_name": { "description": "Last name of the user.", "examples": [ "Lovelace" ], "title": "Last Name", "type": "string" }, "must_change_password": { "description": "Whether the user must change their password before using other endpoints.", "examples": [ false ], "title": "Must Change Password", "type": "boolean" }, "permissions": { "description": "The user's effective permissions, including those implied by assigned ones.", "examples": [ [ "users:write", "users:read", "agents:read" ] ], "items": { "type": "string" }, "title": "Permissions", "type": "array" }, "updated_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "When the user was last updated (RFC 3339); null if never updated.", "examples": [ "2026-01-20T14:05:00Z" ], "title": "Updated At" } }, "required": [ "id", "email", "first_name", "last_name", "active", "permissions", "must_change_password", "created_at" ], "title": "CurrentUserResponse", "type": "object" }, "DailyExecutionBucket": { "description": "Execution counts for a single day.", "examples": [ { "date": "2026-01-15", "failed": 8, "success": 120, "total": 128 } ], "properties": { "date": { "description": "The day the bucket covers, as `YYYY-MM-DD`.", "examples": [ "2026-01-15" ], "title": "Date", "type": "string" }, "failed": { "description": "Number of those executions that failed.", "examples": [ 8 ], "title": "Failed", "type": "integer" }, "success": { "description": "Number of those executions that completed.", "examples": [ 120 ], "title": "Success", "type": "integer" }, "total": { "description": "Number of executions started that day.", "examples": [ 128 ], "title": "Total", "type": "integer" } }, "required": [ "date", "total", "success", "failed" ], "title": "DailyExecutionBucket", "type": "object" }, "DenyRequest": { "description": "Request body for denying an agent.", "examples": [ { "reason": "Requested permissions exceed the agent's stated purpose." } ], "properties": { "reason": { "description": "Why the agent is being denied.", "examples": [ "Requested permissions exceed the agent's stated purpose." ], "maxLength": 1024, "minLength": 1, "title": "Reason", "type": "string" } }, "required": [ "reason" ], "title": "DenyRequest", "type": "object" }, "DeviceAuthorizationRegistrationCreateRequest": { "additionalProperties": false, "description": "Create request for a device-authorization registration.", "examples": [ { "api_vendor": "github", "authorization_endpoint": "https://github.com/login/device/code", "catalog_api_id": "github.com/api.github.com", "client_id": "Iv1.a1b2c3d4", "default_scopes": [ "repo" ], "display_name": "GitHub", "flow_kind": "device_authorization", "name": "MyOrg GitHub (device flow)", "token_endpoint": "https://github.com/login/oauth/access_token" } ], "properties": { "api_vendor": { "description": "Vendor registry key the registration connects.", "examples": [ "github" ], "maxLength": 100, "minLength": 1, "title": "Api Vendor", "type": "string" }, "authorization_endpoint": { "description": "Device authorization endpoint URL.", "examples": [ "https://github.com/login/device/code" ], "maxLength": 2048, "minLength": 1, "title": "Authorization Endpoint", "type": "string" }, "catalog_api_id": { "description": "Catalog API slug this OAuth app targets (e.g. 'github.com/api.github.com').", "examples": [ "github.com/api.github.com" ], "maxLength": 255, "minLength": 1, "pattern": "^[^/].*/.*[^/]$", "title": "Catalog Api Id", "type": "string" }, "client_id": { "description": "OAuth client ID of the app.", "examples": [ "Iv1.a1b2c3d4" ], "maxLength": 255, "minLength": 1, "title": "Client Id", "type": "string" }, "default_scopes": { "anyOf": [ { "items": { "maxLength": 255, "minLength": 1, "pattern": "^\\S+$", "type": "string" }, "type": "array" }, { "type": "null" } ], "description": "Scopes requested by default.", "examples": [ [ "repo" ] ], "title": "Default Scopes" }, "display_name": { "description": "Vendor family label ('GitHub'), shown on picker cards.", "examples": [ "GitHub" ], "maxLength": 255, "minLength": 1, "title": "Display Name", "type": "string" }, "flow_kind": { "const": "device_authorization", "description": "OAuth flow the registration uses; always `device_authorization`.", "examples": [ "device_authorization" ], "title": "Flow Kind", "type": "string" }, "name": { "description": "Admin-chosen name of the registration.", "examples": [ "MyOrg GitHub" ], "maxLength": 255, "minLength": 1, "title": "Name", "type": "string" }, "token_endpoint": { "description": "Token endpoint URL.", "examples": [ "https://github.com/login/oauth/access_token" ], "maxLength": 2048, "minLength": 1, "title": "Token Endpoint", "type": "string" } }, "required": [ "name", "api_vendor", "catalog_api_id", "display_name", "flow_kind", "client_id", "authorization_endpoint", "token_endpoint" ], "title": "DeviceAuthorizationRegistrationCreateRequest", "type": "object" }, "EffectivePermission": { "description": "A single effective permission with provenance.", "examples": [ { "implied_by": "users:write", "name": "users:read" } ], "properties": { "implied_by": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Assigned permission that implies this one; null when it is assigned directly.", "examples": [ "users:write" ], "title": "Implied By" }, "name": { "description": "Permission name.", "examples": [ "users:read" ], "title": "Name", "type": "string" } }, "required": [ "name" ], "title": "EffectivePermission", "type": "object" }, "ErrorItem": { "description": "A granular error detail entry within the errors[] array of a ProblemDetails response.\n\nAt least one of pointer, parameter, or header SHOULD be present to identify the error source.", "examples": [ { "code": "JENTIC-V-001", "detail": "Field 'name' must not be blank.", "header": "Authorization", "parameter": "limit", "pointer": "#/name" } ], "properties": { "code": { "anyOf": [ { "maxLength": 50, "type": "string" }, { "type": "null" } ], "description": "An optional provider-specific code identifying this error in internal taxonomy or documentation.", "examples": [ "JENTIC-V-001" ], "title": "Code" }, "detail": { "description": "A human-readable explanation of this specific error. Be precise — name the field, parameter, or header involved.", "examples": [ "Field 'name' must not be blank." ], "maxLength": 4096, "title": "Detail", "type": "string" }, "header": { "anyOf": [ { "maxLength": 1024, "type": "string" }, { "type": "null" } ], "description": "The name of the request header that is the source of this error.", "examples": [ "Authorization" ], "title": "Header" }, "parameter": { "anyOf": [ { "maxLength": 1024, "type": "string" }, { "type": "null" } ], "description": "The name of the query or path parameter that is the source of this error.", "examples": [ "limit" ], "title": "Parameter" }, "pointer": { "anyOf": [ { "maxLength": 1024, "type": "string" }, { "type": "null" } ], "description": "A JSON Pointer (RFC 6901) to the specific request body property that is the source of this error.", "examples": [ "#/name" ], "title": "Pointer" } }, "required": [ "detail" ], "title": "ErrorItem", "type": "object" }, "EventLinks": { "description": "HAL-style links for an event.", "examples": [ { "action": "https://jentic.example.com/events/evt_6968b398b04f002b6dbff4d1/action", "execution": "https://jentic.example.com/executions/exec_6968b3982706c619fe73f0cf", "job": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb", "self": "https://jentic.example.com/events/evt_6968b398b04f002b6dbff4d1" } ], "properties": { "action": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Reserved link to a follow-up action; currently always null.", "examples": [ "https://jentic.example.com/events/evt_6968b398b04f002b6dbff4d1/action" ], "title": "Action" }, "execution": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "URL of the related execution record; null if none.", "examples": [ "https://jentic.example.com/executions/exec_6968b3982706c619fe73f0cf" ], "title": "Execution" }, "job": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "URL of the related job; null if none.", "examples": [ "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb" ], "title": "Job" }, "self": { "description": "URL of this event.", "examples": [ "https://jentic.example.com/events/evt_6968b398b04f002b6dbff4d1" ], "title": "Self", "type": "string" } }, "required": [ "self" ], "title": "EventLinks", "type": "object" }, "EventListResponse": { "description": "Paginated list of events.", "examples": [ { "data": [ { "_links": { "action": "https://jentic.example.com/events/evt_6968b398b04f002b6dbff4d1/action", "execution": "https://jentic.example.com/executions/exec_6968b3982706c619fe73f0cf", "job": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb", "self": "https://jentic.example.com/events/evt_6968b398b04f002b6dbff4d1" }, "actor_id": "usr_6968b3987ee4c3ec0b4ee3b9", "actor_type": "user", "created_at": "2026-01-15T09:30:00Z", "data": { "job_id": "job_6968b3985e8c9902207afaeb", "revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" }, "detail": "The import produced 1 revision with 142 operations.", "event_id": "evt_6968b398b04f002b6dbff4d1", "requires_action": false, "severity": "info", "summary": "Imported stripe.com/stripe 2024-04-10", "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736", "type": "import.completed" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } ], "properties": { "data": { "description": "The page of events.", "examples": [ [ { "_links": { "action": "https://jentic.example.com/events/evt_6968b398b04f002b6dbff4d1/action", "execution": "https://jentic.example.com/executions/exec_6968b3982706c619fe73f0cf", "job": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb", "self": "https://jentic.example.com/events/evt_6968b398b04f002b6dbff4d1" }, "actor_id": "usr_6968b3987ee4c3ec0b4ee3b9", "actor_type": "user", "created_at": "2026-01-15T09:30:00Z", "data": { "job_id": "job_6968b3985e8c9902207afaeb", "revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" }, "detail": "The import produced 1 revision with 142 operations.", "event_id": "evt_6968b398b04f002b6dbff4d1", "requires_action": false, "severity": "info", "summary": "Imported stripe.com/stripe 2024-04-10", "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736", "type": "import.completed" } ] ], "items": { "$ref": "#/components/schemas/EventResponse" }, "title": "Data", "type": "array" }, "has_more": { "description": "Whether more results exist after this page.", "examples": [ true ], "title": "Has More", "type": "boolean" }, "next_cursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Cursor for the next page; null when there are no more results.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Next Cursor" } }, "required": [ "data", "has_more" ], "title": "EventListResponse", "type": "object" }, "EventResponse": { "description": "Event representation in API responses.", "examples": [ { "_links": { "action": "https://jentic.example.com/events/evt_6968b398b04f002b6dbff4d1/action", "execution": "https://jentic.example.com/executions/exec_6968b3982706c619fe73f0cf", "job": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb", "self": "https://jentic.example.com/events/evt_6968b398b04f002b6dbff4d1" }, "actor_id": "usr_6968b3987ee4c3ec0b4ee3b9", "actor_type": "user", "created_at": "2026-01-15T09:30:00Z", "data": { "job_id": "job_6968b3985e8c9902207afaeb", "revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" }, "detail": "The import produced 1 revision with 142 operations.", "event_id": "evt_6968b398b04f002b6dbff4d1", "requires_action": false, "severity": "info", "summary": "Imported stripe.com/stripe 2024-04-10", "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736", "type": "import.completed" } ], "properties": { "_links": { "$ref": "#/components/schemas/EventLinks", "examples": [ { "action": "https://jentic.example.com/events/evt_6968b398b04f002b6dbff4d1/action", "execution": "https://jentic.example.com/executions/exec_6968b3982706c619fe73f0cf", "job": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb", "self": "https://jentic.example.com/events/evt_6968b398b04f002b6dbff4d1" } ] }, "actor_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the actor that caused the event; null if none.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "Actor Id" }, "actor_type": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Kind of actor that caused the event, e.g. `user` or `agent`; null if none.", "examples": [ "user" ], "title": "Actor Type" }, "created_at": { "description": "When the event was created (RFC 3339).", "examples": [ "2026-01-15T09:30:00Z" ], "format": "date-time", "title": "Created At", "type": "string" }, "data": { "additionalProperties": true, "description": "Type-specific structured payload; empty object when there is none.", "examples": [ { "job_id": "job_6968b3985e8c9902207afaeb", "revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" } ], "title": "Data", "type": "object" }, "detail": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Longer human-readable detail; null if none.", "examples": [ "The import produced 1 revision with 142 operations." ], "title": "Detail" }, "event_id": { "description": "Unique ID of the event (`evt_…`).", "examples": [ "evt_6968b398b04f002b6dbff4d1" ], "title": "Event Id", "type": "string" }, "requires_action": { "description": "Whether the event needs someone to act on it.", "examples": [ false ], "title": "Requires Action", "type": "boolean" }, "severity": { "$ref": "#/components/schemas/EventSeverity", "examples": [ "info" ] }, "summary": { "description": "Short human-readable summary of the event.", "examples": [ "Imported stripe.com/stripe 2024-04-10" ], "title": "Summary", "type": "string" }, "trace_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Trace ID of the request that produced the event, if any.", "examples": [ "4bf92f3577b34da6a3ce929d0e0e4736" ], "title": "Trace Id" }, "type": { "description": "Namespaced event type, e.g. `import.completed`. Opaque string: historical events may carry types that are no longer emitted.", "examples": [ "import.completed" ], "title": "Type", "type": "string" } }, "required": [ "event_id", "type", "severity", "summary", "requires_action", "created_at", "_links" ], "title": "EventResponse", "type": "object" }, "EventSeverity": { "description": "Severity level for platform events.", "enum": [ "info", "warning", "error", "critical" ], "title": "EventSeverity", "type": "string" }, "ExecutionListResponse": { "description": "Paginated list of executions.", "examples": [ { "data": [ { "_links": { "self": "https://jentic.example.com/executions/exec_6968b3982706c619fe73f0cf" }, "actor_id": "agnt_6968b3984d1c238dbe7e2e29", "actor_type": "agent", "api": { "host": "api.stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "created_at": "2026-01-15T09:30:00Z", "credential_id": "cred_6968b39855d91a3561684b32", "credential_name": "Stripe production key", "duration_ms": 342, "error": "Upstream returned HTTP 502 Bad Gateway", "execution_id": "exec_6968b3982706c619fe73f0cf", "http_status": 200, "operation_id": "listCharges", "operation_method": "GET", "operation_path": "/v1/charges", "origin": "agent", "pinned_revisions": { "stripe.com:stripe:2024-04-10": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" }, "started_at": "2026-01-15T09:30:00Z", "status": "completed", "toolkit_id": "tk_6968b3981ec22d56dbbc91e8", "toolkit_name": "billing-toolkit", "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } ], "properties": { "data": { "description": "The page of execution records.", "examples": [ [ { "_links": { "self": "https://jentic.example.com/executions/exec_6968b3982706c619fe73f0cf" }, "actor_id": "agnt_6968b3984d1c238dbe7e2e29", "actor_type": "agent", "api": { "host": "api.stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "created_at": "2026-01-15T09:30:00Z", "credential_id": "cred_6968b39855d91a3561684b32", "credential_name": "Stripe production key", "duration_ms": 342, "error": "Upstream returned HTTP 502 Bad Gateway", "execution_id": "exec_6968b3982706c619fe73f0cf", "http_status": 200, "operation_id": "listCharges", "operation_method": "GET", "operation_path": "/v1/charges", "origin": "agent", "pinned_revisions": { "stripe.com:stripe:2024-04-10": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" }, "started_at": "2026-01-15T09:30:00Z", "status": "completed", "toolkit_id": "tk_6968b3981ec22d56dbbc91e8", "toolkit_name": "billing-toolkit", "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736" } ] ], "items": { "$ref": "#/components/schemas/ExecutionResponse" }, "title": "Data", "type": "array" }, "has_more": { "description": "Whether more results exist after this page.", "examples": [ true ], "title": "Has More", "type": "boolean" }, "next_cursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Cursor for the next page; null when there are no more results.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Next Cursor" } }, "required": [ "data", "has_more" ], "title": "ExecutionListResponse", "type": "object" }, "ExecutionRecordLinks": { "description": "HATEOAS links for an execution record.", "examples": [ { "self": "https://jentic.example.com/executions/exec_6968b3982706c619fe73f0cf" } ], "properties": { "self": { "description": "URL of this execution record.", "examples": [ "https://jentic.example.com/executions/exec_6968b3982706c619fe73f0cf" ], "title": "Self", "type": "string" } }, "required": [ "self" ], "title": "ExecutionRecordLinks", "type": "object" }, "ExecutionResponse": { "description": "Execution record representation in API responses.", "examples": [ { "_links": { "self": "https://jentic.example.com/executions/exec_6968b3982706c619fe73f0cf" }, "actor_id": "agnt_6968b3984d1c238dbe7e2e29", "actor_type": "agent", "api": { "host": "api.stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "created_at": "2026-01-15T09:30:00Z", "credential_id": "cred_6968b39855d91a3561684b32", "credential_name": "Stripe production key", "duration_ms": 342, "error": "Upstream returned HTTP 502 Bad Gateway", "execution_id": "exec_6968b3982706c619fe73f0cf", "http_status": 200, "operation_id": "listCharges", "operation_method": "GET", "operation_path": "/v1/charges", "origin": "agent", "pinned_revisions": { "stripe.com:stripe:2024-04-10": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" }, "started_at": "2026-01-15T09:30:00Z", "status": "completed", "toolkit_id": "tk_6968b3981ec22d56dbbc91e8", "toolkit_name": "billing-toolkit", "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736" } ], "properties": { "_links": { "$ref": "#/components/schemas/ExecutionRecordLinks", "examples": [ { "self": "https://jentic.example.com/executions/exec_6968b3982706c619fe73f0cf" } ] }, "actor_id": { "description": "ID of the actor that ran the execution.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Actor Id", "type": "string" }, "actor_type": { "description": "Kind of actor that ran the execution, e.g. `user` or `agent`. Opaque string: historical rows may carry a retired type.", "examples": [ "agent" ], "title": "Actor Type", "type": "string" }, "api": { "anyOf": [ { "$ref": "#/components/schemas/ApiInfoResponse" }, { "type": "null" } ], "description": "The API that was called; null when it is not recorded.", "examples": [ { "host": "api.stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" } ] }, "created_at": { "description": "When the execution record was created (RFC 3339).", "examples": [ "2026-01-15T09:30:00Z" ], "format": "date-time", "title": "Created At", "type": "string" }, "credential_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the credential used. Null for inline auth, credential-less APIs, older records and executions that failed before a credential was chosen.", "examples": [ "cred_6968b39855d91a3561684b32" ], "title": "Credential Id" }, "credential_name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Name of the credential used; null when no credential is recorded.", "examples": [ "Stripe production key" ], "title": "Credential Name" }, "duration_ms": { "anyOf": [ { "type": "integer" }, { "type": "null" } ], "description": "Duration of the execution in milliseconds; null if unknown.", "examples": [ 342 ], "title": "Duration Ms" }, "error": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Short error message (at most 128 characters) for a failed execution.", "examples": [ "Upstream returned HTTP 502 Bad Gateway" ], "title": "Error" }, "execution_id": { "description": "Unique ID of the execution record.", "examples": [ "exec_6968b3982706c619fe73f0cf" ], "title": "Execution Id", "type": "string" }, "http_status": { "anyOf": [ { "type": "integer" }, { "type": "null" } ], "description": "HTTP status returned by the upstream; null if no upstream response.", "examples": [ 200 ], "title": "Http Status" }, "operation_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Machine identifier of the operation called; null when none was resolved.", "examples": [ "listCharges" ], "title": "Operation Id" }, "operation_method": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "The operation's HTTP method, e.g. GET. Null whenever operation_path is null.", "examples": [ "GET" ], "title": "Operation Method" }, "operation_path": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "The operation's spec path template, e.g. /repos/{owner}/{repo}. Null when the record carries no human-readable operation identity: records predating the column, executions of a URL that resolved to no registered operation, and async jobs enqueued with only an operation_id. Display surfaces show a placeholder for such rows — the opaque operation_id is a machine key, not a human fallback.", "examples": [ "/v1/charges" ], "title": "Operation Path" }, "origin": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Surface the execution was initiated from, e.g. `api`, `agent` or `mcp`; null if not recorded.", "examples": [ "agent" ], "title": "Origin" }, "pinned_revisions": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "description": "Pinned API revisions used, keyed `vendor:name:version` with the revision ID as value; null when no pin applied.", "examples": [ { "stripe.com:stripe:2024-04-10": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" } ], "title": "Pinned Revisions" }, "started_at": { "description": "When the execution started (RFC 3339).", "examples": [ "2026-01-15T09:30:00Z" ], "format": "date-time", "title": "Started At", "type": "string" }, "status": { "description": "Terminal outcome: `completed` or `failed`. An upstream response with HTTP status 400 or above counts as `failed`.", "examples": [ "completed" ], "title": "Status", "type": "string" }, "toolkit_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Legacy: toolkit that mediated the execution. Null for direct-binding executions; attribute those via `credential_id` instead.", "examples": [ "tk_6968b3981ec22d56dbbc91e8" ], "title": "Toolkit Id" }, "toolkit_name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Legacy: name of the toolkit in `toolkit_id`; null when unavailable.", "examples": [ "billing-toolkit" ], "title": "Toolkit Name" }, "trace_id": { "description": "Trace ID of the execution request.", "examples": [ "4bf92f3577b34da6a3ce929d0e0e4736" ], "title": "Trace Id", "type": "string" } }, "required": [ "execution_id", "trace_id", "started_at", "status", "created_at", "actor_id", "actor_type", "_links" ], "title": "ExecutionResponse", "type": "object" }, "ExecutionStatsResponse": { "description": "Aggregated execution statistics for the dashboard.", "examples": [ { "daily_buckets": [ { "date": "2026-01-15", "failed": 8, "success": 120, "total": 128 } ], "success_rate_percent": 93.75, "top_operations": [ { "api_name": "stripe", "api_vendor": "stripe.com", "failed": 12, "operation_id": "listCharges", "total": 342 } ], "total_executions": 1280 } ], "properties": { "daily_buckets": { "description": "Per-day execution counts, oldest first; days with no executions are omitted.", "examples": [ [ { "date": "2026-01-15", "failed": 8, "success": 120, "total": 128 } ] ], "items": { "$ref": "#/components/schemas/DailyExecutionBucket" }, "title": "Daily Buckets", "type": "array" }, "success_rate_percent": { "description": "Share of executions in the window that completed, as a percentage rounded to two decimals; 0 when there were none.", "examples": [ 93.75 ], "title": "Success Rate Percent", "type": "number" }, "top_operations": { "description": "The most-executed operations in the window, most executions first (up to 10).", "examples": [ [ { "api_name": "stripe", "api_vendor": "stripe.com", "failed": 12, "operation_id": "listCharges", "total": 342 } ] ], "items": { "$ref": "#/components/schemas/TopOperation" }, "title": "Top Operations", "type": "array" }, "total_executions": { "description": "Number of executions started in the window.", "examples": [ 1280 ], "title": "Total Executions", "type": "integer" } }, "required": [ "total_executions", "success_rate_percent", "daily_buckets", "top_operations" ], "title": "ExecutionStatsResponse", "type": "object" }, "ExistingCredentialConfirmSessionRequest": { "additionalProperties": false, "description": "Bind a credential the approver already holds (OAuth only if its grant covers the ask).", "examples": [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "credential_id": "cred_6968b39855d91a3561684b32", "digest": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae", "expected_agent_id": "agnt_6968b3984d1c238dbe7e2e29", "kind": "existing_credential", "permission_rules": [ { "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] } ], "properties": { "agent_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Agent to bind when the session has none; ignored if the session already has one.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id" }, "credential_id": { "description": "ID of the approver's credential to bind.", "examples": [ "cred_6968b39855d91a3561684b32" ], "maxLength": 30, "minLength": 1, "title": "Credential Id", "type": "string" }, "digest": { "description": "Review digest echoed from the review data; a mismatch is 409 review_stale.", "examples": [ "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae" ], "maxLength": 64, "minLength": 1, "title": "Digest", "type": "string" }, "expected_agent_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Agent ID from the review the approver saw; a mismatch is 409 review_stale.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Expected Agent Id" }, "kind": { "const": "existing_credential", "description": "Confirm variant; always `existing_credential`.", "examples": [ "existing_credential" ], "title": "Kind", "type": "string" }, "permission_rules": { "description": "Permission rules to bind for the agent (at most 100).", "examples": [ [ { "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] ], "items": { "$ref": "#/components/schemas/PermissionRuleSchema" }, "maxItems": 100, "title": "Permission Rules", "type": "array" } }, "required": [ "permission_rules", "digest", "kind", "credential_id" ], "title": "ExistingCredentialConfirmSessionRequest", "type": "object" }, "GovernedHostsResponse": { "description": "The caller's governed host set (canonical order) with its change digest.\n\n**Hosts only, deliberately**: the set exists for interception scoping\n(divert lists, host filters), so it carries the minimum knowledge — API\ndetail stays behind the existing authenticated reads (``GET /apis``).\n\nDeliberately **unpaginated**: the set is bounded by the caller's own\ncredential bindings (tens of hosts, not thousands) and the digest must\ncover the whole set atomically — a paginated digest would be meaningless.\nThis is a documented deviation from the list-endpoint pagination\nconvention.", "examples": [ { "data": [ "api.github.com", "api.stripe.com", "files.stripe.com:8443" ], "digest": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08" } ], "properties": { "data": { "description": "Governed host entries, normalised (lowercased, FQDN root dot stripped, internationalised names IDNA/punycode-encoded), deduplicated, and sorted — the literal URL-index hosts the broker's discovery matches for the APIs the caller's bound credentials cover. An entry is a hostname, a bare IP literal, or either followed by a non-default port (`host[:port]` — default ports are already stripped). Compare case-insensitively (lowercase the incoming host before matching); a gate keying on hostname or SNI alone must strip any `:port` suffix from the entry first. Variable-bearing hosts (defaultless `{var}` server variables) are excluded — the broker's discovery never matches them. On a `5xx` retain the last known set; never fall back to an empty (intercept-nothing) list.", "examples": [ [ "api.github.com", "api.stripe.com", "files.stripe.com:8443" ] ], "items": { "type": "string" }, "title": "Data", "type": "array" }, "digest": { "description": "SHA-256 hex digest over the newline-joined `data` list; also emitted as the response's strong `ETag`. To change-poll, send it back quoted — `If-None-Match: \"\"` (the bare digest is accepted as a compatibility form) — and expect an empty `304` until the host set changes. Poll at most once per minute.", "examples": [ "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08" ], "title": "Digest", "type": "string" } }, "required": [ "data", "digest" ], "title": "GovernedHostsResponse", "type": "object" }, "GroupBy": { "description": "Grouping dimension for usage statistics.\n\n``TOOLKIT`` is a legacy axis: it groups over the surviving\n``execution_records.toolkit_id`` attribution column, which nothing writes\nsince the toolkit path was deleted (theme-5 Phase 6b). It stays so\nhistorical dashboards keep working; ``CREDENTIAL`` is the live\nconsumer axis (execution records carry ``credential_id`` since Phase 2).", "enum": [ "api", "toolkit", "credential", "agent" ], "title": "GroupBy", "type": "string" }, "HealthResponse": { "description": "Health check response for the admin surface.", "examples": [ { "next_step": "create_admin", "setup_required": true, "status": "ok", "surface": "admin" } ], "properties": { "next_step": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Next setup step to perform, e.g. `create_admin`; null when setup is complete.", "examples": [ "create_admin" ], "title": "Next Step" }, "setup_required": { "description": "Whether first-run setup is still needed because no user exists yet.", "examples": [ true ], "title": "Setup Required", "type": "boolean" }, "status": { "description": "Health status of the surface; `ok` when it is serving.", "examples": [ "ok" ], "title": "Status", "type": "string" }, "surface": { "description": "Name of the surface reporting health; always `admin`.", "examples": [ "admin" ], "title": "Surface", "type": "string" } }, "required": [ "status", "surface", "setup_required" ], "title": "HealthResponse", "type": "object" }, "InstanceIdentityResponse": { "description": "Self-describing identity of the backend serving this request.\n\nA client can compare ``backend``/``canonical_base_url``/``host`` against where\nit *thinks* it is pointed to confirm it is talking to the intended backend\n(e.g. a local install vs. a remote one) before diagnosing \"missing\" data.", "examples": [ { "backend": "remote", "broker_url": "https://broker.jentic.example.com", "canonical_base_url": "https://jentic.example.com", "host": "jentic.example.com", "instance_id": "5f2c9e0b7a41d8c3", "mcp_enabled": true } ], "properties": { "backend": { "description": "Operator-declared backend locality (server.backend): 'local' for a self-hosted install on the operator's own machine/network, 'remote' for a hosted install run elsewhere. A hint, not an authorization signal; defaults to 'local'.", "enum": [ "local", "remote" ], "examples": [ "remote" ], "title": "Backend", "type": "string" }, "broker_url": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "The broker (data plane) base URL a client should send `execute` traffic to, as configured by the operator (server.mcp.broker_url), with any userinfo stripped. Null when the platform cannot honestly advertise one: on a 'remote' backend a loopback-host value (the config default) describes the control plane's own machine, not an address any client can dial, so it is withheld rather than published as misleading guidance. Deployment metadata, not a secret — the broker URL is handed to every client expected to call it (issue #1249).", "examples": [ "https://broker.jentic.example.com" ], "title": "Broker Url" }, "canonical_base_url": { "description": "The instance's own canonical base URL (auth.canonical_base_url, else server.public_base_url, else the serving bind origin), with any userinfo stripped.", "examples": [ "https://jentic.example.com" ], "title": "Canonical Base Url", "type": "string" }, "host": { "description": "Host (and port, when the canonical base URL declares one) parsed from canonical_base_url; '' if unset or unparseable.", "examples": [ "jentic.example.com" ], "title": "Host", "type": "string" }, "instance_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Opaque digest derived from the telemetry instance id — stable per install, but not the telemetry id itself. Null when telemetry has not resolved an id (e.g. telemetry disabled).", "examples": [ "5f2c9e0b7a41d8c3" ], "title": "Instance Id" }, "mcp_enabled": { "default": false, "description": "Whether this instance serves the daemon-native Streamable HTTP MCP endpoint at /mcp (server.mcp.enabled). Lets clients (notably the UI's agent MCP card) advertise the HTTP transport only when it exists. Not sensitive: the endpoint's enabled state is observable by probing /mcp anyway.", "examples": [ true ], "title": "Mcp Enabled", "type": "boolean" } }, "required": [ "backend", "canonical_base_url", "host" ], "title": "InstanceIdentityResponse", "type": "object" }, "IntegrationsConnectRequest": { "additionalProperties": false, "description": "Start connecting a credential for a vendor or a registry API.", "examples": [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "api": { "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "auth_type": "oauth2", "name": "GitHub (work)", "oauth_app_registration_id": "oar_6968b39821e5f89a6975f501", "preferred_flow": "authorization_code", "reason": "Needs read access to triage issues in the platform repo.", "requested_permission_rules": [ { "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ], "requested_scopes": [ "repo", "read:user" ], "vendor": "github" } ], "properties": { "agent_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the agent to bind the credential to on confirm; agent callers must omit it, and when omitted by a user the credential connects unbound.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id" }, "api": { "anyOf": [ { "$ref": "#/components/schemas/ApiTargetRequest" }, { "type": "null" } ], "description": "Registry API to connect a credential for. Exactly one of vendor or api.", "examples": [ { "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" } ] }, "auth_type": { "anyOf": [ { "maxLength": 255, "type": "string" }, { "type": "null" } ], "description": "Declared scheme name or kind to use for an api target", "examples": [ "oauth2" ], "title": "Auth Type" }, "name": { "anyOf": [ { "maxLength": 255, "type": "string" }, { "type": "null" } ], "description": "Label for the resulting credential; defaults to the vendor's display name.", "examples": [ "GitHub (work)" ], "title": "Name" }, "oauth_app_registration_id": { "anyOf": [ { "maxLength": 30, "type": "string" }, { "type": "null" } ], "description": "ID of the admin OAuth app registration to connect through; required when several active registrations offer the flow.", "examples": [ "oar_6968b39821e5f89a6975f501" ], "title": "Oauth App Registration Id" }, "preferred_flow": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Flow kind to use if the source offers it; defaults to the source's first flow.", "examples": [ "authorization_code" ], "title": "Preferred Flow" }, "reason": { "anyOf": [ { "maxLength": 1024, "type": "string" }, { "type": "null" } ], "description": "Free-text reason for the request, shown to the approver.", "examples": [ "Needs read access to triage issues in the platform repo." ], "title": "Reason" }, "requested_permission_rules": { "description": "Permission rules proposed for the agent, shown pre-filled on the review page; nothing is bound until confirm.", "examples": [ [ { "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] ], "items": { "$ref": "#/components/schemas/PermissionRuleSchema" }, "maxItems": 100, "title": "Requested Permission Rules", "type": "array" }, "requested_scopes": { "description": "Upstream scopes to request (at most 100).", "examples": [ [ "repo", "read:user" ] ], "items": { "type": "string" }, "maxItems": 100, "title": "Requested Scopes", "type": "array" }, "vendor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Vendor registry key (e.g. 'github'). Exactly one of vendor or api.", "examples": [ "github" ], "title": "Vendor" } }, "title": "IntegrationsConnectRequest", "type": "object" }, "IntrospectResponse": { "description": "RFC 7662 introspection response.", "examples": [ { "active": true, "exp": 1769903999, "scope": "apis:read capabilities:execute", "sub": "agnt_6968b3984d1c238dbe7e2e29", "token_type": "access_token" } ], "properties": { "active": { "description": "Whether the token is currently valid.", "examples": [ true ], "title": "Active", "type": "boolean" }, "exp": { "anyOf": [ { "type": "integer" }, { "type": "null" } ], "description": "Token expiry, in seconds since the Unix epoch; omitted if unknown.", "examples": [ 1769903999 ], "title": "Exp" }, "scope": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Space-separated effective scopes of the token; omitted if unknown.", "examples": [ "apis:read capabilities:execute" ], "title": "Scope" }, "sub": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the actor the token was issued to; omitted if unknown.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Sub" }, "token_type": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Kind of token: `access_token` or `refresh_token`; omitted if unknown.", "examples": [ "access_token" ], "title": "Token Type" } }, "required": [ "active" ], "title": "IntrospectResponse", "type": "object" }, "InviteIssuedResponse": { "description": "Response when an invite token is issued.", "examples": [ { "expires_at": "2026-01-22T09:30:00Z", "token": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" } ], "properties": { "expires_at": { "description": "When the invite token expires (RFC 3339).", "examples": [ "2026-01-22T09:30:00Z" ], "format": "date-time", "title": "Expires At", "type": "string" }, "token": { "description": "One-time invite token the user redeems to set a password.", "examples": [ "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" ], "title": "Token", "type": "string", "x-sensitive": true } }, "required": [ "token", "expires_at" ], "title": "InviteIssuedResponse", "type": "object" }, "InviteState": { "description": "State of a user invitation.", "enum": [ "pending", "redeemed", "expired", "accepted" ], "title": "InviteState", "type": "string" }, "JobLinksResponse": { "description": "Hypermedia links for a job.", "examples": [ { "execution": "https://jentic.example.com/executions/exec_6968b3982706c619fe73f0cf", "result": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb/result", "self": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb" } ], "properties": { "execution": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "URL of the related execution record; null if none.", "examples": [ "https://jentic.example.com/executions/exec_6968b3982706c619fe73f0cf" ], "title": "Execution" }, "result": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "URL of the job result; null until the job has completed.", "examples": [ "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb/result" ], "title": "Result" }, "self": { "description": "URL of this job.", "examples": [ "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb" ], "title": "Self", "type": "string" } }, "required": [ "self" ], "title": "JobLinksResponse", "type": "object" }, "JobListResponse": { "description": "Paginated list of jobs.", "examples": [ { "data": [ { "_links": { "execution": "https://jentic.example.com/executions/exec_6968b3982706c619fe73f0cf", "result": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb/result", "self": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb" }, "actor_id": "agnt_6968b3984d1c238dbe7e2e29", "actor_type": "agent", "created_at": "2026-01-15T09:30:00Z", "error": "Upstream returned HTTP 502 Bad Gateway", "execution_id": "exec_6968b3982706c619fe73f0cf", "job_id": "job_6968b3985e8c9902207afaeb", "kind": "execution", "status": "completed", "updated_at": "2026-01-15T09:30:05Z" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } ], "properties": { "data": { "description": "The page of jobs.", "examples": [ [ { "_links": { "execution": "https://jentic.example.com/executions/exec_6968b3982706c619fe73f0cf", "result": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb/result", "self": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb" }, "actor_id": "agnt_6968b3984d1c238dbe7e2e29", "actor_type": "agent", "created_at": "2026-01-15T09:30:00Z", "error": "Upstream returned HTTP 502 Bad Gateway", "execution_id": "exec_6968b3982706c619fe73f0cf", "job_id": "job_6968b3985e8c9902207afaeb", "kind": "execution", "status": "completed", "updated_at": "2026-01-15T09:30:05Z" } ] ], "items": { "$ref": "#/components/schemas/JobResponse" }, "title": "Data", "type": "array" }, "has_more": { "description": "Whether more results exist after this page.", "examples": [ true ], "title": "Has More", "type": "boolean" }, "next_cursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Cursor for the next page; null when there are no more results.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Next Cursor" } }, "required": [ "data", "has_more" ], "title": "JobListResponse", "type": "object" }, "JobResponse": { "description": "Job representation in API responses.", "examples": [ { "_links": { "execution": "https://jentic.example.com/executions/exec_6968b3982706c619fe73f0cf", "result": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb/result", "self": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb" }, "actor_id": "agnt_6968b3984d1c238dbe7e2e29", "actor_type": "agent", "created_at": "2026-01-15T09:30:00Z", "error": "Upstream returned HTTP 502 Bad Gateway", "execution_id": "exec_6968b3982706c619fe73f0cf", "job_id": "job_6968b3985e8c9902207afaeb", "kind": "execution", "status": "completed", "updated_at": "2026-01-15T09:30:05Z" } ], "properties": { "_links": { "$ref": "#/components/schemas/JobLinksResponse", "examples": [ { "execution": "https://jentic.example.com/executions/exec_6968b3982706c619fe73f0cf", "result": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb/result", "self": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb" } ] }, "actor_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Subject that enqueued the job. Null only for legacy rows with no actor.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Actor Id" }, "actor_type": { "description": "Kind of actor that enqueued the job: 'user' or 'agent'. Opaque string: historical rows may carry a retired type such as 'service_account'.", "examples": [ "agent" ], "title": "Actor Type", "type": "string" }, "created_at": { "description": "When the job was created (RFC 3339).", "examples": [ "2026-01-15T09:30:00Z" ], "format": "date-time", "title": "Created At", "type": "string" }, "error": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Error message recorded for the job; null if none.", "examples": [ "Upstream returned HTTP 502 Bad Gateway" ], "title": "Error" }, "execution_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the execution record linked to the job, if any.", "examples": [ "exec_6968b3982706c619fe73f0cf" ], "title": "Execution Id" }, "job_id": { "description": "Unique ID of the job.", "examples": [ "job_6968b3985e8c9902207afaeb" ], "title": "Job Id", "type": "string" }, "kind": { "description": "Kind of job, e.g. `import` or `execution`.", "examples": [ "execution" ], "title": "Kind", "type": "string" }, "status": { "description": "Lifecycle state: `queued`, `running`, `completed`, `failed`, `cancelled` or `dead_letter`.", "examples": [ "completed" ], "title": "Status", "type": "string" }, "updated_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "When the job was last updated (RFC 3339); null if never updated.", "examples": [ "2026-01-15T09:30:05Z" ], "title": "Updated At" } }, "required": [ "job_id", "kind", "status", "created_at", "actor_type", "_links" ], "title": "JobResponse", "type": "object" }, "JwksUpdateRequest": { "description": "Request body for updating an agent's JWKS (public keys).\n\nThe JWKS must contain at least one Ed25519 public key and must not\ncontain any private key material.", "examples": [ { "jwks": { "keys": [ { "crv": "Ed25519", "kid": "agent-key-1", "kty": "OKP", "x": "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo" } ] } } ], "properties": { "jwks": { "additionalProperties": true, "description": "JWKS containing public keys", "examples": [ { "keys": [ { "crv": "Ed25519", "kid": "agent-key-1", "kty": "OKP", "x": "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo" } ] } ], "title": "Jwks", "type": "object" } }, "required": [ "jwks" ], "title": "JwksUpdateRequest", "type": "object" }, "LoginRequest": { "description": "Credentials for login.", "examples": [ { "email": "ada@example.com", "password": "example-password" } ], "properties": { "email": { "description": "Email address of the user.", "examples": [ "ada@example.com" ], "maxLength": 320, "minLength": 1, "title": "Email", "type": "string" }, "password": { "description": "The user's password.", "examples": [ "example-password" ], "maxLength": 128, "minLength": 1, "title": "Password", "type": "string", "x-sensitive": true } }, "required": [ "email", "password" ], "title": "LoginRequest", "type": "object" }, "LoginResponse": { "description": "JWT token response after successful authentication.", "examples": [ { "access_token": "example-access-token", "expires_in": 3600, "must_change_password": false, "token_type": "bearer" } ], "properties": { "access_token": { "description": "Signed JWT to send as a bearer token on subsequent requests.", "examples": [ "example-access-token" ], "title": "Access Token", "type": "string", "x-sensitive": true }, "expires_in": { "description": "Lifetime of the access token in seconds.", "examples": [ 3600 ], "title": "Expires In", "type": "integer" }, "must_change_password": { "description": "Whether the user must change their password before using other endpoints.", "examples": [ false ], "title": "Must Change Password", "type": "boolean" }, "token_type": { "description": "Token type; always `bearer`.", "examples": [ "bearer" ], "title": "Token Type", "type": "string" } }, "required": [ "access_token", "token_type", "expires_in", "must_change_password" ], "title": "LoginResponse", "type": "object" }, "McpConfigRegistrationRequest": { "description": "Report that an MCP config entry was written for one agent runtime.", "examples": [ { "runtime": "cursor" } ], "properties": { "runtime": { "$ref": "#/components/schemas/McpConfigRuntime", "description": "The agent runtime whose MCP config entry was written — a closed set; clients map anything unrecognised to `other`.", "examples": [ "cursor" ] } }, "required": [ "runtime" ], "title": "McpConfigRegistrationRequest", "type": "object" }, "McpConfigRegistrationResponse": { "description": "Acknowledgement of a config-registration report.", "examples": [ { "recorded": true, "runtime": "cursor" } ], "properties": { "recorded": { "description": "Whether the report was recorded as an event. `false` means it was accepted but throttled (an identical (actor, runtime) report was already recorded within the last 24h).", "examples": [ true ], "title": "Recorded", "type": "boolean" }, "runtime": { "$ref": "#/components/schemas/McpConfigRuntime", "description": "The runtime the report was recorded for.", "examples": [ "cursor" ] } }, "required": [ "runtime", "recorded" ], "title": "McpConfigRegistrationResponse", "type": "object" }, "McpConfigRuntime": { "description": "Closed-enum tag naming the agent runtime an MCP config entry targets.\n\nAttached only to ``mcp_config_registered`` — one event per runtime whose\nconfig file/entry ``jentic setup``/``jentic skill init`` writes. A closed\nset (never the raw runtime string) so the config-written → first-session →\nfirst-execute funnel stays property-free on the wire.", "enum": [ "claude_desktop", "claude_code", "cursor", "codex", "other" ], "title": "McpConfigRuntime", "type": "string" }, "MeAgent": { "description": "Identity response for an agent actor.", "examples": [ { "approved_by": "usr_6968b3987ee4c3ec0b4ee3b9", "credential_bindings": [ { "bound_at": "2026-01-15T09:30:00Z", "credential_id": "cred_6968b39855d91a3561684b32", "name": "Stripe production key", "rule_set_id": "prs_6968b3987c22b63e87e79f05", "serves": [ { "api_name": "stripe", "api_vendor": "stripe.com", "api_version": "2024-04-10" } ], "suspended": false, "suspended_reason": "api_deleted" } ], "id": "agnt_6968b3984d1c238dbe7e2e29", "name": "invoice-reconciler", "parent_agent_id": "agnt_6968b3984d1c238dbe7e2e29", "permissions": [ "apis:read", "capabilities:execute" ], "status": "active", "token_permissions": [ "apis:read", "capabilities:execute" ], "type": "agent" } ], "properties": { "approved_by": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the user who approved the agent; null if not approved.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "Approved By" }, "credential_bindings": { "default": [], "description": "Credentials bound directly to the agent.", "examples": [ [ { "bound_at": "2026-01-15T09:30:00Z", "credential_id": "cred_6968b39855d91a3561684b32", "name": "Stripe production key", "rule_set_id": "prs_6968b3987c22b63e87e79f05", "serves": [ { "api_name": "stripe", "api_vendor": "stripe.com", "api_version": "2024-04-10" } ], "suspended": false, "suspended_reason": "api_deleted" } ] ], "items": { "$ref": "#/components/schemas/CredentialBindingEntry" }, "title": "Credential Bindings", "type": "array" }, "id": { "description": "Unique ID of the agent.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Id", "type": "string" }, "name": { "description": "Human-readable name of the agent.", "examples": [ "invoice-reconciler" ], "title": "Name", "type": "string" }, "parent_agent_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the parent agent; null when the agent has no parent.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Parent Agent Id" }, "permissions": { "description": "Permissions currently granted to the agent, read live rather than from the token.", "examples": [ [ "apis:read", "capabilities:execute" ] ], "items": { "type": "string" }, "title": "Permissions", "type": "array" }, "status": { "description": "Lifecycle status of the agent: `pending`, `active`, `rejected`, `disabled` or `archived`.", "examples": [ "active" ], "title": "Status", "type": "string" }, "token_permissions": { "description": "Permissions in the presented bearer token; if narrower than `permissions`, obtain a new token to pick up newer grants.", "examples": [ [ "apis:read", "capabilities:execute" ] ], "items": { "type": "string" }, "title": "Token Permissions", "type": "array" }, "type": { "const": "agent", "default": "agent", "description": "Actor type discriminator; always `agent`.", "examples": [ "agent" ], "title": "Type", "type": "string" } }, "required": [ "id", "name", "status", "permissions", "token_permissions" ], "title": "MeAgent", "type": "object" }, "MeUser": { "description": "Identity response for a user actor.", "examples": [ { "admin": true, "email": "ada@example.com", "id": "usr_6968b3987ee4c3ec0b4ee3b9", "must_change_password": false, "name": "Ada Lovelace", "permissions": [ "org:admin", "agents:read" ], "status": "active", "type": "user" } ], "properties": { "admin": { "description": "Whether the caller's token holds `org:admin`.", "examples": [ true ], "title": "Admin", "type": "boolean" }, "email": { "description": "Email address of the user.", "examples": [ "ada@example.com" ], "title": "Email", "type": "string" }, "id": { "description": "Unique ID of the user.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "Id", "type": "string" }, "must_change_password": { "description": "Whether the user must change their password; most endpoints return 403 until they do.", "examples": [ false ], "title": "Must Change Password", "type": "boolean" }, "name": { "description": "Display name of the user.", "examples": [ "Ada Lovelace" ], "title": "Name", "type": "string" }, "permissions": { "description": "Permissions carried by the caller's token.", "examples": [ [ "org:admin", "agents:read" ] ], "items": { "type": "string" }, "title": "Permissions", "type": "array" }, "status": { "description": "User status: `active` or `disabled`.", "examples": [ "active" ], "title": "Status", "type": "string" }, "type": { "const": "user", "default": "user", "description": "Actor type discriminator; always `user`.", "examples": [ "user" ], "title": "Type", "type": "string" } }, "required": [ "id", "name", "email", "admin", "status", "permissions", "must_change_password" ], "title": "MeUser", "type": "object" }, "NoAuthCreateRequest": { "description": "Create request for no_auth credentials.\n\nA no-auth credential carries no secret — it represents \"this API is called\nwithout authentication\". It still exists as a credential row so an agent\nbinding (and its permission rules) can hang off it, and the broker resolves\nit as a no-op auth (see broker credential resolver / injection).", "examples": [ { "api": { "catalog_api_id": "stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "name": "Stripe live key", "provider": "static", "runtime_config": { "headers": { "Stripe-Version": "2024-04-10" }, "query_params": { "locale": "en-GB" } }, "server_variables": { "region": "eu" }, "type": "no_auth" } ], "properties": { "api": { "$ref": "#/components/schemas/APIReferenceRequest", "examples": [ { "catalog_api_id": "stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" } ] }, "name": { "description": "Human-readable label for the credential.", "examples": [ "Stripe live key" ], "title": "Name", "type": "string" }, "provider": { "default": "static", "description": "Credential provider; 'static' for stored secrets.", "examples": [ "static" ], "title": "Provider", "type": "string" }, "runtime_config": { "anyOf": [ { "$ref": "#/components/schemas/RuntimeConfig" }, { "type": "null" } ], "description": "Per-upstream-call overrides; reserved and not currently applied.", "examples": [ { "headers": { "Stripe-Version": "2024-04-10" }, "query_params": { "locale": "en-GB" } } ] }, "server_variables": { "anyOf": [ { "additionalProperties": { "type": "string" }, "type": "object" }, { "type": "null" } ], "description": "OpenAPI server-variable values for URL template substitution (at most 20).", "examples": [ { "region": "eu" } ], "title": "Server Variables" }, "type": { "const": "no_auth", "description": "Credential type; always `no_auth`.", "examples": [ "no_auth" ], "title": "Type", "type": "string" } }, "required": [ "type", "name", "api" ], "title": "NoAuthCreateRequest", "type": "object" }, "NoteApiReference": { "additionalProperties": false, "description": "Loose ``(vendor, name, version)`` identity tuple for a registered API.", "examples": [ { "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" } ], "properties": { "name": { "description": "Name of the API within the vendor.", "examples": [ "stripe" ], "title": "Name", "type": "string" }, "vendor": { "description": "Vendor of the API.", "examples": [ "stripe.com" ], "title": "Vendor", "type": "string" }, "version": { "description": "Version of the API.", "examples": [ "2024-04-10" ], "title": "Version", "type": "string" } }, "required": [ "vendor", "name", "version" ], "title": "NoteApiReference", "type": "object" }, "NoteConfidence": { "description": "Author-supplied confidence in a note (matches the spec ``NoteConfidence`` enum).", "enum": [ "observed", "suspected", "verified" ], "title": "NoteConfidence", "type": "string" }, "NoteCreateRequest": { "additionalProperties": false, "description": "Payload for creating a new note.", "examples": [ { "body": "Stripe returns 401 unless the secret key is sent as a Bearer token; Basic auth with an empty password also works.", "confidence": "observed", "related_execution_id": "exec_6968b3982706c619fe73f0cf", "resource": { "api": { "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "credential_id": "cred_6968b39855d91a3561684b32", "execution_id": "exec_6968b3982706c619fe73f0cf", "operation_id": "op_f92d69f1621f381bce8aaff47053c61b069ffe34" }, "source": "agent", "type": "auth_quirk" } ], "properties": { "body": { "description": "Text of the note, up to 4000 characters.", "examples": [ "Stripe returns 401 unless the secret key is sent as a Bearer token; Basic auth with an empty password also works." ], "maxLength": 4000, "title": "Body", "type": "string" }, "confidence": { "anyOf": [ { "$ref": "#/components/schemas/NoteConfidence" }, { "type": "null" } ], "description": "Author's confidence in the note; null if not stated.", "examples": [ "observed" ] }, "related_execution_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of an execution the note relates to; null if none.", "examples": [ "exec_6968b3982706c619fe73f0cf" ], "title": "Related Execution Id" }, "resource": { "$ref": "#/components/schemas/NoteResource", "examples": [ { "api": { "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "credential_id": "cred_6968b39855d91a3561684b32", "execution_id": "exec_6968b3982706c619fe73f0cf", "operation_id": "op_f92d69f1621f381bce8aaff47053c61b069ffe34" } ] }, "source": { "anyOf": [ { "$ref": "#/components/schemas/NoteSource" }, { "type": "null" } ], "description": "Origin of the note (`agent`, `human` or `platform`); null if not stated.", "examples": [ "agent" ] }, "type": { "anyOf": [ { "$ref": "#/components/schemas/NoteType" }, { "type": "null" } ], "description": "Category of the note; null if uncategorised.", "examples": [ "auth_quirk" ] } }, "required": [ "resource", "body" ], "title": "NoteCreateRequest", "type": "object" }, "NoteResource": { "additionalProperties": false, "description": "Exactly-one-of resource identifier for a note (request side).", "examples": [ { "api": { "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "credential_id": "cred_6968b39855d91a3561684b32", "execution_id": "exec_6968b3982706c619fe73f0cf", "operation_id": "op_f92d69f1621f381bce8aaff47053c61b069ffe34" } ], "properties": { "api": { "anyOf": [ { "$ref": "#/components/schemas/NoteApiReference" }, { "type": "null" } ], "description": "API to attach the note to; set exactly one resource field.", "examples": [ { "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" } ] }, "credential_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the credential to attach the note to; set exactly one resource field.", "examples": [ "cred_6968b39855d91a3561684b32" ], "title": "Credential Id" }, "execution_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the execution to attach the note to; set exactly one resource field.", "examples": [ "exec_6968b3982706c619fe73f0cf" ], "title": "Execution Id" }, "operation_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the operation to attach the note to; set exactly one resource field.", "examples": [ "op_f92d69f1621f381bce8aaff47053c61b069ffe34" ], "title": "Operation Id" } }, "title": "NoteResource", "type": "object" }, "NoteSource": { "description": "Origin tag for a note (matches the spec ``NoteSource`` enum).", "enum": [ "agent", "human", "platform" ], "title": "NoteSource", "type": "string" }, "NoteType": { "description": "Category of a note (matches the spec ``NoteType`` enum).", "enum": [ "auth_quirk", "usage_hint", "execution_feedback", "correction" ], "title": "NoteType", "type": "string" }, "NoteUpdateRequest": { "additionalProperties": false, "description": "Payload for updating an existing note (partial).", "examples": [ { "body": "Stripe returns 401 unless the secret key is sent as a Bearer token; Basic auth with an empty password also works.", "confidence": "verified", "related_execution_id": "exec_6968b3982706c619fe73f0cf", "source": "agent", "type": "auth_quirk" } ], "properties": { "body": { "anyOf": [ { "maxLength": 4000, "type": "string" }, { "type": "null" } ], "description": "New text of the note, up to 4000 characters; may be omitted but not null.", "examples": [ "Stripe returns 401 unless the secret key is sent as a Bearer token; Basic auth with an empty password also works." ], "title": "Body" }, "confidence": { "anyOf": [ { "$ref": "#/components/schemas/NoteConfidence" }, { "type": "null" } ], "description": "New confidence in the note; null clears it.", "examples": [ "verified" ] }, "related_execution_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of an execution the note relates to; null clears it.", "examples": [ "exec_6968b3982706c619fe73f0cf" ], "title": "Related Execution Id" }, "source": { "anyOf": [ { "$ref": "#/components/schemas/NoteSource" }, { "type": "null" } ], "description": "New origin of the note; null clears it.", "examples": [ "agent" ] }, "type": { "anyOf": [ { "$ref": "#/components/schemas/NoteType" }, { "type": "null" } ], "description": "New category of the note; null clears it.", "examples": [ "auth_quirk" ] } }, "title": "NoteUpdateRequest", "type": "object" }, "OAuth2CreateRequest": { "description": "Create request for oauth2 credentials.\n\nFor managed providers (e.g. pipedream, direct_oauth2), token_url/client_id/client_secret\nare optional — the connect flow handles authentication without caller-supplied client details.", "examples": [ { "api": { "catalog_api_id": "stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "authorize_url": "https://connect.stripe.com/oauth/authorize", "client_id": "ca_example123", "client_secret": "example-secret", "grant_type": "client_credentials", "name": "Stripe live key", "provider": "static", "runtime_config": { "headers": { "Stripe-Version": "2024-04-10" }, "query_params": { "locale": "en-GB" } }, "scopes": [ "read_write" ], "server_variables": { "region": "eu" }, "token_url": "https://connect.stripe.com/oauth/token", "type": "oauth2" } ], "properties": { "api": { "$ref": "#/components/schemas/APIReferenceRequest", "examples": [ { "catalog_api_id": "stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" } ] }, "authorize_url": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Authorization endpoint URL; for the device_code grant, the device authorization endpoint.", "examples": [ "https://connect.stripe.com/oauth/authorize" ], "title": "Authorize Url" }, "client_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "OAuth client ID; required for non-managed providers.", "examples": [ "ca_example123" ], "title": "Client Id" }, "client_secret": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "OAuth client secret; required for non-managed providers except the device_code grant. Stored encrypted; never returned after create.", "examples": [ "example-secret" ], "title": "Client Secret", "x-sensitive": true }, "grant_type": { "default": "client_credentials", "description": "OAuth2 grant type (e.g. client_credentials, authorization_code, device_code).", "examples": [ "client_credentials" ], "title": "Grant Type", "type": "string" }, "name": { "description": "Human-readable label for the credential.", "examples": [ "Stripe live key" ], "title": "Name", "type": "string" }, "provider": { "default": "static", "description": "Credential provider; 'static' for stored secrets.", "examples": [ "static" ], "title": "Provider", "type": "string" }, "runtime_config": { "anyOf": [ { "$ref": "#/components/schemas/RuntimeConfig" }, { "type": "null" } ], "description": "Per-upstream-call overrides; reserved and not currently applied.", "examples": [ { "headers": { "Stripe-Version": "2024-04-10" }, "query_params": { "locale": "en-GB" } } ] }, "scopes": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "description": "OAuth scopes to request.", "examples": [ [ "read_write" ] ], "title": "Scopes" }, "server_variables": { "anyOf": [ { "additionalProperties": { "type": "string" }, "type": "object" }, { "type": "null" } ], "description": "OpenAPI server-variable values for URL template substitution (at most 20).", "examples": [ { "region": "eu" } ], "title": "Server Variables" }, "token_url": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Token endpoint URL; required for non-managed providers.", "examples": [ "https://connect.stripe.com/oauth/token" ], "title": "Token Url" }, "type": { "const": "oauth2", "description": "Credential type; always `oauth2`.", "examples": [ "oauth2" ], "title": "Type", "type": "string" } }, "required": [ "type", "name", "api" ], "title": "OAuth2CreateRequest", "type": "object" }, "OAuth2UpdateRequest": { "description": "Update request for oauth2 credentials.", "examples": [ { "active": true, "client_secret": "example-secret", "name": "Stripe live key", "runtime_config": { "headers": { "Stripe-Version": "2024-04-10" }, "query_params": { "locale": "en-GB" } }, "scopes": [ "read_write" ], "server_variables": { "region": "eu" }, "token_url": "https://connect.stripe.com/oauth/token", "type": "oauth2" } ], "properties": { "active": { "anyOf": [ { "type": "boolean" }, { "type": "null" } ], "description": "Enable or disable the credential for injection; omit to leave unchanged.", "examples": [ true ], "title": "Active" }, "client_secret": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Replacement client secret; omit to leave unchanged. token_url and scopes are applied only together with it.", "examples": [ "example-secret" ], "title": "Client Secret", "x-sensitive": true }, "name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "New label for the credential; omit to leave unchanged.", "examples": [ "Stripe live key" ], "title": "Name" }, "runtime_config": { "anyOf": [ { "$ref": "#/components/schemas/RuntimeConfig" }, { "type": "null" } ], "description": "Per-upstream-call overrides; reserved and not currently applied.", "examples": [ { "headers": { "Stripe-Version": "2024-04-10" }, "query_params": { "locale": "en-GB" } } ] }, "scopes": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "description": "Replacement OAuth scopes; applied only when client_secret is sent.", "examples": [ [ "read_write" ] ], "title": "Scopes" }, "server_variables": { "anyOf": [ { "additionalProperties": { "type": "string" }, "type": "object" }, { "type": "null" } ], "description": "Replacement OpenAPI server-variable values; omit to leave unchanged.", "examples": [ { "region": "eu" } ], "title": "Server Variables" }, "token_url": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Replacement token endpoint URL; applied only when client_secret is sent.", "examples": [ "https://connect.stripe.com/oauth/token" ], "title": "Token Url" }, "type": { "const": "oauth2", "description": "Credential type; always `oauth2`.", "examples": [ "oauth2" ], "title": "Type", "type": "string" } }, "required": [ "type" ], "title": "OAuth2UpdateRequest", "type": "object" }, "OAuthAppRegistrationFlowKind": { "description": "Which OAuth flow a registration supports.", "enum": [ "authorization_code", "device_authorization" ], "title": "OAuthAppRegistrationFlowKind", "type": "string" }, "OAuthAppRegistrationListResponse": { "description": "Paginated list of OAuth app registrations.", "examples": [ { "data": [ { "api_vendor": "github", "authorization_endpoint": "https://github.com/login/device/code", "authorize_url": "https://github.com/login/oauth/authorize", "catalog_api_id": "github.com/api.github.com", "client_id": "Iv1.a1b2c3d4", "created_at": "2026-01-15T09:30:00Z", "created_by": "usr_6968b3987ee4c3ec0b4ee3b9", "default_scopes": [ "repo", "read:user" ], "dependent_credential_count": 4, "display_name": "GitHub", "flow_kind": "authorization_code", "has_client_secret": true, "id": "oar_6968b39821e5f89a6975f501", "is_active": true, "name": "MyOrg GitHub", "secret_last_rotated_at": "2026-01-20T14:05:00Z", "token_endpoint": "https://github.com/login/oauth/access_token", "token_url": "https://github.com/login/oauth/access_token", "updated_at": "2026-01-20T14:05:00Z" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } ], "properties": { "data": { "description": "The page of OAuth app registrations.", "examples": [ [ { "api_vendor": "github", "authorization_endpoint": "https://github.com/login/device/code", "authorize_url": "https://github.com/login/oauth/authorize", "catalog_api_id": "github.com/api.github.com", "client_id": "Iv1.a1b2c3d4", "created_at": "2026-01-15T09:30:00Z", "created_by": "usr_6968b3987ee4c3ec0b4ee3b9", "default_scopes": [ "repo", "read:user" ], "dependent_credential_count": 4, "display_name": "GitHub", "flow_kind": "authorization_code", "has_client_secret": true, "id": "oar_6968b39821e5f89a6975f501", "is_active": true, "name": "MyOrg GitHub", "secret_last_rotated_at": "2026-01-20T14:05:00Z", "token_endpoint": "https://github.com/login/oauth/access_token", "token_url": "https://github.com/login/oauth/access_token", "updated_at": "2026-01-20T14:05:00Z" } ] ], "items": { "$ref": "#/components/schemas/OAuthAppRegistrationResponse" }, "title": "Data", "type": "array" }, "has_more": { "description": "Whether more results exist after this page.", "examples": [ true ], "title": "Has More", "type": "boolean" }, "next_cursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Cursor for the next page; null when there are no more results.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Next Cursor" } }, "required": [ "data", "has_more" ], "title": "OAuthAppRegistrationListResponse", "type": "object" }, "OAuthAppRegistrationResponse": { "description": "Registration as returned to admins.\n\nNever includes the client secret — only ``has_client_secret`` +\n``secret_last_rotated_at`` so an admin can see rotation history without\nbeing able to read the material.", "examples": [ { "api_vendor": "github", "authorization_endpoint": "https://github.com/login/device/code", "authorize_url": "https://github.com/login/oauth/authorize", "catalog_api_id": "github.com/api.github.com", "client_id": "Iv1.a1b2c3d4", "created_at": "2026-01-15T09:30:00Z", "created_by": "usr_6968b3987ee4c3ec0b4ee3b9", "default_scopes": [ "repo", "read:user" ], "dependent_credential_count": 4, "display_name": "GitHub", "flow_kind": "authorization_code", "has_client_secret": true, "id": "oar_6968b39821e5f89a6975f501", "is_active": true, "name": "MyOrg GitHub", "secret_last_rotated_at": "2026-01-20T14:05:00Z", "token_endpoint": "https://github.com/login/oauth/access_token", "token_url": "https://github.com/login/oauth/access_token", "updated_at": "2026-01-20T14:05:00Z" } ], "properties": { "api_vendor": { "description": "Vendor registry key the registration connects.", "examples": [ "github" ], "title": "Api Vendor", "type": "string" }, "authorization_endpoint": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Device authorization endpoint URL; null for authorization-code registrations.", "examples": [ "https://github.com/login/device/code" ], "title": "Authorization Endpoint" }, "authorize_url": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Authorization endpoint URL; null for device-authorization registrations.", "examples": [ "https://github.com/login/oauth/authorize" ], "title": "Authorize Url" }, "catalog_api_id": { "description": "Catalog API slug this OAuth app targets (e.g. 'googleapis-com/gmail'). Feeds credential.catalog_api_id at connect time so the operations preview resolves against a real registered API.", "examples": [ "github.com/api.github.com" ], "title": "Catalog Api Id", "type": "string" }, "client_id": { "description": "OAuth client ID of the app.", "examples": [ "Iv1.a1b2c3d4" ], "title": "Client Id", "type": "string" }, "created_at": { "description": "When the registration was created (RFC 3339).", "examples": [ "2026-01-15T09:30:00Z" ], "format": "date-time", "title": "Created At", "type": "string" }, "created_by": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the actor that created the registration.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "Created By" }, "default_scopes": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "description": "Scopes requested by default; null if none are set.", "examples": [ [ "repo", "read:user" ] ], "title": "Default Scopes" }, "dependent_credential_count": { "description": "Number of credentials minted through this registration.", "examples": [ 4 ], "title": "Dependent Credential Count", "type": "integer" }, "display_name": { "description": "Vendor family label ('Gmail'), shown alongside the admin's per-registration 'name' on the picker card.", "examples": [ "GitHub" ], "title": "Display Name", "type": "string" }, "flow_kind": { "$ref": "#/components/schemas/OAuthAppRegistrationFlowKind", "examples": [ "authorization_code" ] }, "has_client_secret": { "description": "Whether a client secret is stored.", "examples": [ true ], "title": "Has Client Secret", "type": "boolean" }, "id": { "description": "Unique ID of the OAuth app registration.", "examples": [ "oar_6968b39821e5f89a6975f501" ], "title": "Id", "type": "string" }, "is_active": { "description": "Whether the registration is active.", "examples": [ true ], "title": "Is Active", "type": "boolean" }, "name": { "description": "Admin-chosen name of the registration.", "examples": [ "MyOrg GitHub" ], "title": "Name", "type": "string" }, "secret_last_rotated_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "When the client secret was last rotated (RFC 3339); null if never rotated.", "examples": [ "2026-01-20T14:05:00Z" ], "title": "Secret Last Rotated At" }, "token_endpoint": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Token endpoint URL; null for authorization-code registrations.", "examples": [ "https://github.com/login/oauth/access_token" ], "title": "Token Endpoint" }, "token_url": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Token endpoint URL; null for device-authorization registrations.", "examples": [ "https://github.com/login/oauth/access_token" ], "title": "Token Url" }, "updated_at": { "description": "When the registration was last updated (RFC 3339).", "examples": [ "2026-01-20T14:05:00Z" ], "format": "date-time", "title": "Updated At", "type": "string" } }, "required": [ "id", "name", "api_vendor", "catalog_api_id", "display_name", "flow_kind", "client_id", "is_active", "has_client_secret", "secret_last_rotated_at", "created_at", "updated_at", "created_by", "dependent_credential_count" ], "title": "OAuthAppRegistrationResponse", "type": "object" }, "OAuthAppRegistrationRotateSecretRequest": { "additionalProperties": false, "description": "Rotate the client secret on an auth-code registration.", "examples": [ { "client_secret": "example-secret" } ], "properties": { "client_secret": { "description": "New OAuth client secret; stored encrypted and never returned.", "examples": [ "example-secret" ], "maxLength": 4096, "minLength": 1, "title": "Client Secret", "type": "string", "x-sensitive": true } }, "required": [ "client_secret" ], "title": "OAuthAppRegistrationRotateSecretRequest", "type": "object" }, "OAuthAppRegistrationUpdateRequest": { "additionalProperties": false, "description": "Partial update — fields not present are left untouched.", "examples": [ { "authorization_endpoint": "https://github.com/login/device/code", "authorize_url": "https://github.com/login/oauth/authorize", "default_scopes": [ "repo", "read:user" ], "display_name": "GitHub", "is_active": true, "name": "MyOrg GitHub", "token_endpoint": "https://github.com/login/oauth/access_token", "token_url": "https://github.com/login/oauth/access_token" } ], "properties": { "authorization_endpoint": { "anyOf": [ { "maxLength": 2048, "minLength": 1, "type": "string" }, { "type": "null" } ], "description": "New device authorization endpoint URL; device-authorization registrations only.", "examples": [ "https://github.com/login/device/code" ], "title": "Authorization Endpoint" }, "authorize_url": { "anyOf": [ { "maxLength": 2048, "minLength": 1, "type": "string" }, { "type": "null" } ], "description": "New authorization endpoint URL; authorization-code registrations only.", "examples": [ "https://github.com/login/oauth/authorize" ], "title": "Authorize Url" }, "default_scopes": { "anyOf": [ { "items": { "maxLength": 255, "minLength": 1, "pattern": "^\\S+$", "type": "string" }, "type": "array" }, { "type": "null" } ], "description": "Replacement default scopes; omit to leave unchanged.", "examples": [ [ "repo", "read:user" ] ], "title": "Default Scopes" }, "display_name": { "anyOf": [ { "maxLength": 255, "minLength": 1, "type": "string" }, { "type": "null" } ], "description": "New vendor family label; omit to leave unchanged.", "examples": [ "GitHub" ], "title": "Display Name" }, "is_active": { "anyOf": [ { "type": "boolean" }, { "type": "null" } ], "description": "Activate or deactivate the registration; omit to leave unchanged.", "examples": [ true ], "title": "Is Active" }, "name": { "anyOf": [ { "maxLength": 255, "minLength": 1, "type": "string" }, { "type": "null" } ], "description": "New registration name; omit to leave unchanged.", "examples": [ "MyOrg GitHub" ], "title": "Name" }, "token_endpoint": { "anyOf": [ { "maxLength": 2048, "minLength": 1, "type": "string" }, { "type": "null" } ], "description": "New token endpoint URL; device-authorization registrations only.", "examples": [ "https://github.com/login/oauth/access_token" ], "title": "Token Endpoint" }, "token_url": { "anyOf": [ { "maxLength": 2048, "minLength": 1, "type": "string" }, { "type": "null" } ], "description": "New token endpoint URL; authorization-code registrations only.", "examples": [ "https://github.com/login/oauth/access_token" ], "title": "Token Url" } }, "title": "OAuthAppRegistrationUpdateRequest", "type": "object" }, "OAuthApprovalDecisionRequest": { "description": "Inline admin approve/deny posted from the approval-pending page.\n\n``state`` is the signed approval-state blob minted by ``/authorize`` for\nthis exact authorize request — the decision endpoint never accepts a bare\n``client_id``.\n\n``state`` is deliberately NOT marked x-sensitive: the CLI's GEN-21\nredaction backstop unions every sensitive field's BARE name globally, and\n\"state\" is generic enough to redact unrelated CLI output (e.g. the MCP\nsession-diagnosis ``state`` field). The blob is not a lasting bearer\ncredential — it is HMAC-signed, purpose-discriminated, TTL'd (600 s), and\nthe decision endpoint additionally requires an authenticated admin with\n``oauth-clients:write`` — so global redaction buys nothing worth that\ncollision.", "examples": [ { "action": "approve", "state": "eyJfcHVycG9zZSI6ICJleGFtcGxlIn0=.5d41402abc4b2a76b9719d911017c592" } ], "properties": { "action": { "description": "The decision: `approve` or `deny` the pending client.", "enum": [ "approve", "deny" ], "examples": [ "approve" ], "title": "Action", "type": "string" }, "state": { "description": "Signed approval-state token issued by `/authorize` for this request.", "examples": [ "eyJfcHVycG9zZSI6ICJleGFtcGxlIn0=.5d41402abc4b2a76b9719d911017c592" ], "title": "State", "type": "string" } }, "required": [ "state", "action" ], "title": "OAuthApprovalDecisionRequest", "type": "object" }, "OAuthApprovalStatusResponse": { "description": "Minimal tri-state approval status for a pending-client authorize request.\n\nDeliberately carries nothing else — no client name, redirect URIs, or\nmetadata — so the anonymous poll endpoint cannot be used to read client\ndetails out of the registry.", "examples": [ { "status": "approved" } ], "properties": { "status": { "description": "Approval state of the client: `pending`, `approved` or `denied`.", "enum": [ "pending", "approved", "denied" ], "examples": [ "approved" ], "title": "Status", "type": "string" } }, "required": [ "status" ], "title": "OAuthApprovalStatusResponse", "type": "object" }, "OAuthClientCreateRequest": { "description": "Request body for creating an OAuth client.", "examples": [ { "description": "My application production deployment", "name": "my-app-production", "redirect_uris": [ "https://app.example.com/auth/callback" ], "require_consent": true } ], "properties": { "allowed_scopes": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "description": "If set, restricts which scopes this client may request. An empty list denies all non-OIDC scopes. Null means unrestricted (all scopes permitted).", "examples": [ [ "apis:read", "capabilities:execute" ] ], "title": "Allowed Scopes" }, "consent_model": { "default": "user", "description": "What a user's consent grants for this client. ``user`` keeps today's act-as-user semantics; ``agent`` marks the client for agent-bound consent (the MCP path).", "enum": [ "user", "agent" ], "examples": [ "user" ], "title": "Consent Model", "type": "string" }, "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Optional description of the client.", "examples": [ "Billing assistant production deployment" ], "title": "Description" }, "name": { "description": "Human-readable name for the client.", "examples": [ "billing-assistant-prod" ], "maxLength": 255, "title": "Name", "type": "string" }, "redirect_uris": { "description": "Allowed OAuth callback URLs. At least one required.", "examples": [ [ "https://client.example.com/oauth/callback" ] ], "items": { "maxLength": 2048, "type": "string" }, "maxItems": 20, "minItems": 1, "title": "Redirect Uris", "type": "array" }, "require_consent": { "default": true, "description": "Whether to show a consent screen during authorization. Set to false for trusted first-party integrations.", "examples": [ true ], "title": "Require Consent", "type": "boolean" }, "token_endpoint_auth_method": { "default": "client_secret_basic", "description": "Client authentication method at the token endpoint. ``client_secret_basic`` creates a confidential client with a generated secret; ``none`` creates a public (secret-less) client that relies on PKCE alone — no secret is generated or returned.", "enum": [ "client_secret_basic", "none" ], "examples": [ "client_secret_basic" ], "title": "Token Endpoint Auth Method", "type": "string" } }, "required": [ "name", "redirect_uris" ], "title": "OAuthClientCreateRequest", "type": "object" }, "OAuthClientCreateResponse": { "description": "Returned on creation — includes the one-time plaintext client secret.", "examples": [ { "active": true, "active_grant_count": 0, "allowed_scopes": [ "agents:read", "credentials:read" ], "approval_status": "approved", "client_id": "oc_abc123...", "client_secret": "", "consent_model": "user", "created_at": "2026-08-18T12:00:00Z", "created_by": "usr_abc123", "description": "My application production deployment", "id": "oac_2NxYz...", "name": "my-app-production", "redirect_uris": [ "https://app.example.com/auth/callback" ], "registration_source": "admin", "require_consent": true, "software_id": "com.example.my-app", "token_endpoint_auth_method": "client_secret_basic", "updated_at": "2026-08-18T12:00:00Z" } ], "properties": { "active": { "description": "Whether the client is enabled; false for disabled, pending or denied clients.", "examples": [ true ], "title": "Active", "type": "boolean" }, "active_grant_count": { "default": 0, "description": "Number of active consent→agent grants for this client. Computed on the read endpoints (list/get); write-path responses report 0.", "examples": [ 3 ], "title": "Active Grant Count", "type": "integer" }, "allowed_scopes": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "description": "Scopes this client may request. Null means unrestricted.", "examples": [ [ "apis:read", "capabilities:execute" ] ], "title": "Allowed Scopes" }, "approval_status": { "description": "Admin approval lifecycle: ``pending``, ``approved``, or ``denied``. Only approved clients may enter OAuth flows; ``active`` remains the independent kill switch.", "examples": [ "approved" ], "title": "Approval Status", "type": "string" }, "client_id": { "description": "Public client identifier used in OAuth flows.", "examples": [ "oc_Xk3vQ9mT2pLw8RzN5bYc1HdF7gJs4AeU" ], "title": "Client Id", "type": "string" }, "client_secret": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "The client secret. Shown only once at creation — store it securely. Null for public (secret-less) clients.", "examples": [ "example-client-secret" ], "title": "Client Secret", "x-sensitive": true }, "consent_model": { "description": "What a user's consent grants for this client: ``user`` or ``agent``.", "examples": [ "user" ], "title": "Consent Model", "type": "string" }, "created_at": { "description": "When the client was created (RFC 3339).", "examples": [ "2026-01-15T09:30:00Z" ], "format": "date-time", "title": "Created At", "type": "string" }, "created_by": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the actor that created the client; null if not recorded.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "Created By" }, "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Description of the client; null if none.", "examples": [ "Billing assistant production deployment" ], "title": "Description" }, "id": { "description": "Record ID of the OAuth client (`oac_…`), not its public `client_id`.", "examples": [ "oac_6968b39840a935d9f7e2714b" ], "title": "Id", "type": "string" }, "name": { "description": "Human-readable name for the client.", "examples": [ "billing-assistant-prod" ], "title": "Name", "type": "string" }, "redirect_uris": { "description": "Allowed OAuth callback URLs.", "examples": [ [ "https://client.example.com/oauth/callback" ] ], "items": { "type": "string" }, "title": "Redirect Uris", "type": "array" }, "registration_source": { "description": "How the client entered the registry: ``admin`` or ``dcr``.", "examples": [ "admin" ], "title": "Registration Source", "type": "string" }, "require_consent": { "description": "Whether a consent screen is shown during authorization.", "examples": [ true ], "title": "Require Consent", "type": "boolean" }, "software_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "RFC 7591 software identifier claimed at registration, if any.", "examples": [ "com.example.billing-assistant" ], "title": "Software Id" }, "token_endpoint_auth_method": { "description": "Client authentication method at the token endpoint: ``client_secret_basic`` (confidential) or ``none`` (public, PKCE-only).", "examples": [ "client_secret_basic" ], "title": "Token Endpoint Auth Method", "type": "string" }, "updated_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "When the client was last updated (RFC 3339); null if never updated.", "examples": [ "2026-01-20T14:05:00Z" ], "title": "Updated At" } }, "required": [ "id", "client_id", "name", "description", "redirect_uris", "allowed_scopes", "active", "require_consent", "token_endpoint_auth_method", "consent_model", "registration_source", "software_id", "approval_status", "created_at", "updated_at", "created_by", "client_secret" ], "title": "OAuthClientCreateResponse", "type": "object" }, "OAuthClientDenyRequest": { "description": "Request body for denying an OAuth client.", "examples": [ { "reason": "Unrecognised publisher; redirect URI not owned by a known vendor." } ], "properties": { "reason": { "anyOf": [ { "maxLength": 1024, "type": "string" }, { "type": "null" } ], "description": "Optional reason recorded in the audit trail.", "examples": [ "Unrecognised publisher; redirect URI not owned by a known vendor." ], "title": "Reason" } }, "title": "OAuthClientDenyRequest", "type": "object" }, "OAuthClientListResponse": { "description": "A list of OAuth clients.", "examples": [ { "data": [ { "active": true, "active_grant_count": 0, "allowed_scopes": [ "agents:read", "credentials:read" ], "approval_status": "approved", "client_id": "oc_abc123...", "consent_model": "user", "created_at": "2026-08-18T12:00:00Z", "created_by": "usr_abc123", "description": "My application production deployment", "id": "oac_2NxYz...", "name": "my-app-production", "redirect_uris": [ "https://app.example.com/auth/callback" ], "registration_source": "admin", "require_consent": true, "software_id": "com.example.my-app", "token_endpoint_auth_method": "client_secret_basic", "updated_at": "2026-08-18T12:00:00Z" } ] } ], "properties": { "data": { "description": "The OAuth clients.", "examples": [ [ { "active": true, "active_grant_count": 0, "allowed_scopes": [ "agents:read", "credentials:read" ], "approval_status": "approved", "client_id": "oc_abc123...", "consent_model": "user", "created_at": "2026-08-18T12:00:00Z", "created_by": "usr_abc123", "description": "My application production deployment", "id": "oac_2NxYz...", "name": "my-app-production", "redirect_uris": [ "https://app.example.com/auth/callback" ], "registration_source": "admin", "require_consent": true, "software_id": "com.example.my-app", "token_endpoint_auth_method": "client_secret_basic", "updated_at": "2026-08-18T12:00:00Z" } ] ], "items": { "$ref": "#/components/schemas/OAuthClientResponse" }, "title": "Data", "type": "array" } }, "required": [ "data" ], "title": "OAuthClientListResponse", "type": "object" }, "OAuthClientRegistrationRequest": { "description": "POST /oauth-clients request body (RFC 7591 client metadata subset).", "examples": [ { "application_type": "native", "client_name": "Cursor", "grant_types": [ "authorization_code", "refresh_token" ], "redirect_uris": [ "https://client.example.com/oauth/callback" ], "response_types": [ "code" ], "scope": "apis:read capabilities:execute", "software_id": "com.example.mcp-client", "software_version": "1.4.2", "token_endpoint_auth_method": "none" } ], "properties": { "application_type": { "anyOf": [ { "maxLength": 32, "type": "string" }, { "type": "null" } ], "description": "Accepted and echoed ('native' for desktop/CLI apps, per the 2026-07-28 MCP spec revision); localhost http redirect URIs are allowed regardless.", "examples": [ "native" ], "title": "Application Type" }, "client_name": { "description": "Human-readable client name; self-asserted and not verified by the server.", "examples": [ "Cursor" ], "maxLength": 255, "minLength": 1, "title": "Client Name", "type": "string" }, "grant_types": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "description": "Subset of ['authorization_code', 'refresh_token'].", "examples": [ [ "authorization_code", "refresh_token" ] ], "title": "Grant Types" }, "redirect_uris": { "description": "1-20 redirect URIs. `https` always; `http` for loopback hosts only; RFC 8252 §7.1 private-use (custom) schemes are accepted for native apps (browser-executable and other dangerous schemes are rejected).", "examples": [ [ "https://client.example.com/oauth/callback" ] ], "items": { "type": "string" }, "maxItems": 20, "minItems": 1, "title": "Redirect Uris", "type": "array" }, "response_types": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "description": "Only ['code'] is supported.", "examples": [ [ "code" ] ], "title": "Response Types" }, "scope": { "anyOf": [ { "maxLength": 6500, "type": "string" }, { "type": "null" } ], "description": "Space-separated scopes requested as the client's ceiling (at most 100 tokens); capped to the scopes the server grants OAuth clients, and the full set when omitted.", "examples": [ "apis:read capabilities:execute" ], "title": "Scope" }, "software_id": { "anyOf": [ { "maxLength": 255, "type": "string" }, { "type": "null" } ], "description": "Stable identifier of the client software; with the redirect URIs it is used to match a repeat registration to the existing client.", "examples": [ "com.example.mcp-client" ], "title": "Software Id" }, "software_version": { "anyOf": [ { "maxLength": 255, "type": "string" }, { "type": "null" } ], "description": "Version of the client software.", "examples": [ "1.4.2" ], "title": "Software Version" }, "token_endpoint_auth_method": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Must be 'none' if supplied — this endpoint only registers public (secret-less, PKCE-only) clients.", "examples": [ "none" ], "title": "Token Endpoint Auth Method" } }, "required": [ "client_name", "redirect_uris" ], "title": "OAuthClientRegistrationRequest", "type": "object" }, "OAuthClientRegistrationResponse": { "description": "POST /oauth-clients response (201 created, or 200 on a D8 dedupe hit).\n\nRFC 7591-compatible: ``client_id`` plus the registered metadata. No\n``client_secret`` (public clients only) and no\n``registration_access_token`` (D12 — no RFC 7592 self-management surface;\nclients retry ``/authorize``, they don't poll).", "examples": [ { "application_type": "native", "client_id": "oc_Xk3vQ9mT2pLw8RzN5bYc1HdF7gJs4AeU", "client_id_issued_at": 1767225600, "client_name": "Cursor", "grant_types": [ "authorization_code", "refresh_token" ], "redirect_uris": [ "https://client.example.com/oauth/callback" ], "response_types": [ "code" ], "scope": "apis:read capabilities:execute", "software_id": "com.example.mcp-client", "software_version": "1.4.2", "token_endpoint_auth_method": "none" } ], "properties": { "application_type": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "The application type as sent in the request; omitted if not sent.", "examples": [ "native" ], "title": "Application Type" }, "client_id": { "description": "The client identifier to use in OAuth requests.", "examples": [ "oc_Xk3vQ9mT2pLw8RzN5bYc1HdF7gJs4AeU" ], "title": "Client Id", "type": "string" }, "client_id_issued_at": { "description": "Seconds since the Unix epoch at which the client_id was issued.", "examples": [ 1767225600 ], "title": "Client Id Issued At", "type": "integer" }, "client_name": { "description": "The client name as sent in the request.", "examples": [ "Cursor" ], "title": "Client Name", "type": "string" }, "grant_types": { "default": [ "authorization_code", "refresh_token" ], "description": "Grant types the client may use.", "examples": [ [ "authorization_code", "refresh_token" ] ], "items": { "type": "string" }, "title": "Grant Types", "type": "array" }, "redirect_uris": { "description": "The registered redirect URIs.", "examples": [ [ "https://client.example.com/oauth/callback" ] ], "items": { "type": "string" }, "title": "Redirect Uris", "type": "array" }, "response_types": { "default": [ "code" ], "description": "Response types the client may use; always `code`.", "examples": [ [ "code" ] ], "items": { "type": "string" }, "title": "Response Types", "type": "array" }, "scope": { "description": "Space-separated scope ceiling granted to the client (the request's scope capped to the MCP tool-scope set).", "examples": [ "apis:read capabilities:execute" ], "title": "Scope", "type": "string" }, "software_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "The software ID as sent in the request; omitted if not sent.", "examples": [ "com.example.mcp-client" ], "title": "Software Id" }, "software_version": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "The software version as sent in the request; omitted if not sent.", "examples": [ "1.4.2" ], "title": "Software Version" }, "token_endpoint_auth_method": { "default": "none", "description": "Always `none`: the client is public and uses PKCE.", "examples": [ "none" ], "title": "Token Endpoint Auth Method", "type": "string" } }, "required": [ "client_id", "client_id_issued_at", "client_name", "redirect_uris", "scope" ], "title": "OAuthClientRegistrationResponse", "type": "object" }, "OAuthClientResponse": { "description": "An OAuth client in API responses.", "examples": [ { "active": true, "active_grant_count": 0, "allowed_scopes": [ "agents:read", "credentials:read" ], "approval_status": "approved", "client_id": "oc_abc123...", "consent_model": "user", "created_at": "2026-08-18T12:00:00Z", "created_by": "usr_abc123", "description": "My application production deployment", "id": "oac_2NxYz...", "name": "my-app-production", "redirect_uris": [ "https://app.example.com/auth/callback" ], "registration_source": "admin", "require_consent": true, "software_id": "com.example.my-app", "token_endpoint_auth_method": "client_secret_basic", "updated_at": "2026-08-18T12:00:00Z" } ], "properties": { "active": { "description": "Whether the client is enabled; false for disabled, pending or denied clients.", "examples": [ true ], "title": "Active", "type": "boolean" }, "active_grant_count": { "default": 0, "description": "Number of active consent→agent grants for this client. Computed on the read endpoints (list/get); write-path responses report 0.", "examples": [ 3 ], "title": "Active Grant Count", "type": "integer" }, "allowed_scopes": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "description": "Scopes this client may request. Null means unrestricted.", "examples": [ [ "apis:read", "capabilities:execute" ] ], "title": "Allowed Scopes" }, "approval_status": { "description": "Admin approval lifecycle: ``pending``, ``approved``, or ``denied``. Only approved clients may enter OAuth flows; ``active`` remains the independent kill switch.", "examples": [ "approved" ], "title": "Approval Status", "type": "string" }, "client_id": { "description": "Public client identifier used in OAuth flows.", "examples": [ "oc_Xk3vQ9mT2pLw8RzN5bYc1HdF7gJs4AeU" ], "title": "Client Id", "type": "string" }, "consent_model": { "description": "What a user's consent grants for this client: ``user`` or ``agent``.", "examples": [ "user" ], "title": "Consent Model", "type": "string" }, "created_at": { "description": "When the client was created (RFC 3339).", "examples": [ "2026-01-15T09:30:00Z" ], "format": "date-time", "title": "Created At", "type": "string" }, "created_by": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the actor that created the client; null if not recorded.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "Created By" }, "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Description of the client; null if none.", "examples": [ "Billing assistant production deployment" ], "title": "Description" }, "id": { "description": "Record ID of the OAuth client (`oac_…`), not its public `client_id`.", "examples": [ "oac_6968b39840a935d9f7e2714b" ], "title": "Id", "type": "string" }, "name": { "description": "Human-readable name for the client.", "examples": [ "billing-assistant-prod" ], "title": "Name", "type": "string" }, "redirect_uris": { "description": "Allowed OAuth callback URLs.", "examples": [ [ "https://client.example.com/oauth/callback" ] ], "items": { "type": "string" }, "title": "Redirect Uris", "type": "array" }, "registration_source": { "description": "How the client entered the registry: ``admin`` or ``dcr``.", "examples": [ "admin" ], "title": "Registration Source", "type": "string" }, "require_consent": { "description": "Whether a consent screen is shown during authorization.", "examples": [ true ], "title": "Require Consent", "type": "boolean" }, "software_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "RFC 7591 software identifier claimed at registration, if any.", "examples": [ "com.example.billing-assistant" ], "title": "Software Id" }, "token_endpoint_auth_method": { "description": "Client authentication method at the token endpoint: ``client_secret_basic`` (confidential) or ``none`` (public, PKCE-only).", "examples": [ "client_secret_basic" ], "title": "Token Endpoint Auth Method", "type": "string" }, "updated_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "When the client was last updated (RFC 3339); null if never updated.", "examples": [ "2026-01-20T14:05:00Z" ], "title": "Updated At" } }, "required": [ "id", "client_id", "name", "description", "redirect_uris", "allowed_scopes", "active", "require_consent", "token_endpoint_auth_method", "consent_model", "registration_source", "software_id", "approval_status", "created_at", "updated_at", "created_by" ], "title": "OAuthClientResponse", "type": "object" }, "OAuthClientRotateSecretResponse": { "description": "Returned on secret rotation — the new one-time plaintext secret.", "examples": [ { "client_secret": "example-client-secret" } ], "properties": { "client_secret": { "description": "The new client secret. Store it securely; the previous secret is now invalid.", "examples": [ "example-client-secret" ], "title": "Client Secret", "type": "string", "x-sensitive": true } }, "required": [ "client_secret" ], "title": "OAuthClientRotateSecretResponse", "type": "object" }, "OAuthClientUpdateRequest": { "description": "Request body for updating an OAuth client.", "examples": [ { "active": true, "allowed_scopes": [ "apis:read", "capabilities:execute" ], "description": "Billing assistant production deployment", "name": "billing-assistant-prod", "redirect_uris": [ "https://client.example.com/oauth/callback" ], "require_consent": true } ], "properties": { "active": { "anyOf": [ { "type": "boolean" }, { "type": "null" } ], "description": "False disables the client and true re-enables it; null means no change.", "examples": [ true ], "title": "Active" }, "allowed_scopes": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "description": "Scope restriction list. Null means no change; an empty list denies all non-OIDC scopes; the wildcard ``[\"*\"]`` resets to unrestricted.", "examples": [ [ "apis:read", "capabilities:execute" ] ], "title": "Allowed Scopes" }, "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "New description for the client; null means no change.", "examples": [ "Billing assistant production deployment" ], "title": "Description" }, "name": { "anyOf": [ { "maxLength": 255, "type": "string" }, { "type": "null" } ], "description": "New name for the client; null means no change.", "examples": [ "billing-assistant-prod" ], "title": "Name" }, "redirect_uris": { "anyOf": [ { "items": { "maxLength": 2048, "type": "string" }, "maxItems": 20, "minItems": 1, "type": "array" }, { "type": "null" } ], "description": "Replacement list of allowed OAuth callback URLs; null means no change.", "examples": [ [ "https://client.example.com/oauth/callback" ] ], "title": "Redirect Uris" }, "require_consent": { "anyOf": [ { "type": "boolean" }, { "type": "null" } ], "description": "Whether to show a consent screen during authorization; null means no change.", "examples": [ true ], "title": "Require Consent" } }, "title": "OAuthClientUpdateRequest", "type": "object" }, "OAuthConfirmSessionRequest": { "description": "Confirm an OAuth session: the scopes to request and the agent's rules.\n\nThe default variant — a body without ``kind`` is this one.", "examples": [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "confirmed_scopes": [ "repo", "read:user" ], "digest": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae", "expected_agent_id": "agnt_6968b3984d1c238dbe7e2e29", "kind": "oauth", "permission_rules": [ { "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] } ], "properties": { "agent_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Agent to bind when the session has none; ignored if the session already has one.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id" }, "confirmed_scopes": { "description": "Upstream scopes the approver confirmed (at most 100).", "examples": [ [ "repo", "read:user" ] ], "items": { "type": "string" }, "maxItems": 100, "title": "Confirmed Scopes", "type": "array" }, "digest": { "anyOf": [ { "maxLength": 64, "type": "string" }, { "type": "null" } ], "description": "Review digest echoed from the review data; a mismatch is 409 review_stale. Required for an API target.", "examples": [ "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae" ], "title": "Digest" }, "expected_agent_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Agent ID from the review the approver saw; a mismatch is 409 review_stale. Required for an API target.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Expected Agent Id" }, "kind": { "const": "oauth", "default": "oauth", "description": "Confirm variant; `oauth` (the default when omitted).", "examples": [ "oauth" ], "title": "Kind", "type": "string" }, "permission_rules": { "description": "Permission rules to bind for the agent (at most 100).", "examples": [ [ { "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] ], "items": { "$ref": "#/components/schemas/PermissionRuleSchema" }, "maxItems": 100, "title": "Permission Rules", "type": "array" } }, "required": [ "confirmed_scopes" ], "title": "OAuthConfirmSessionRequest", "type": "object" }, "OAuthErrorResponse": { "description": "OAuth 2.0 error response (RFC 6749 §5.2 dialect).\n\nSpec-facing OAuth endpoints (token, RFC 7009 revocation, RFC 7591\nregistration) answer errors in this dialect rather than RFC 9457 Problem\nDetails, because real OAuth/MCP clients parse it.", "examples": [ { "error": "invalid_request", "error_description": "missing required parameter" } ], "properties": { "error": { "description": "ASCII error code, e.g. `invalid_request`, `invalid_grant`, `invalid_client`, `unsupported_grant_type`, `invalid_client_metadata`, `slow_down`.", "examples": [ "invalid_request" ], "title": "Error", "type": "string" }, "error_description": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Human-readable explanation of the error.", "examples": [ "missing required parameter" ], "title": "Error Description" } }, "required": [ "error" ], "title": "OAuthErrorResponse", "type": "object" }, "OAuthGrantAdminListResponse": { "description": "A paginated list of OAuth grants (admin cross-view).", "examples": [ { "data": [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "agent_status": "active", "can_revoke": true, "client_name": "billing-assistant-prod", "client_origin": "https://client.example.com", "created_at": "2026-01-15T09:30:00Z", "id": "ocg_6968b3985e21c5fdf643025d", "last_used_at": "2026-01-19T08:12:00Z", "oauth_client_id": "oc_Xk3vQ9mT2pLw8RzN5bYc1HdF7gJs4AeU", "revoked_at": "2026-01-20T14:05:00Z", "scopes": [ "apis:read", "capabilities:execute" ], "status": "revoked", "user_id": "usr_6968b3987ee4c3ec0b4ee3b9" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } ], "properties": { "data": { "description": "The page of grants.", "examples": [ [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "agent_status": "active", "can_revoke": true, "client_name": "billing-assistant-prod", "client_origin": "https://client.example.com", "created_at": "2026-01-15T09:30:00Z", "id": "ocg_6968b3985e21c5fdf643025d", "last_used_at": "2026-01-19T08:12:00Z", "oauth_client_id": "oc_Xk3vQ9mT2pLw8RzN5bYc1HdF7gJs4AeU", "revoked_at": "2026-01-20T14:05:00Z", "scopes": [ "apis:read", "capabilities:execute" ], "status": "revoked", "user_id": "usr_6968b3987ee4c3ec0b4ee3b9" } ] ], "items": { "$ref": "#/components/schemas/OAuthGrantAdminResponse" }, "title": "Data", "type": "array" }, "has_more": { "description": "Whether more results exist after this page.", "examples": [ true ], "title": "Has More", "type": "boolean" }, "next_cursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Cursor for the next page; null when there are no more results.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Next Cursor" } }, "required": [ "data", "has_more" ], "title": "OAuthGrantAdminListResponse", "type": "object" }, "OAuthGrantAdminResponse": { "description": "One consent→agent grant in the admin cross-view.", "examples": [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "agent_status": "active", "can_revoke": true, "client_name": "billing-assistant-prod", "client_origin": "https://client.example.com", "created_at": "2026-01-15T09:30:00Z", "id": "ocg_6968b3985e21c5fdf643025d", "last_used_at": "2026-01-19T08:12:00Z", "oauth_client_id": "oc_Xk3vQ9mT2pLw8RzN5bYc1HdF7gJs4AeU", "revoked_at": "2026-01-20T14:05:00Z", "scopes": [ "apis:read", "capabilities:execute" ], "status": "revoked", "user_id": "usr_6968b3987ee4c3ec0b4ee3b9" } ], "properties": { "agent_id": { "description": "The agent this grant binds the client to.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" }, "agent_status": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Lifecycle state of the bound agent (`active`, `disabled`, `archived`, …). A grant on a non-active agent is dormant: the row stays `active` (disable is reversible — re-enable restores the standing consent without a new consent round) but no token resolves while the agent is non-active. Lets listings tell a working connection from a dormant one (#1233).", "examples": [ "active" ], "title": "Agent Status" }, "can_revoke": { "description": "Whether the CALLER may revoke this grant (the consenting user, or an admin holding the revoke permission set). May be false even for callers who can list — e.g. a read-only admin.", "examples": [ true ], "title": "Can Revoke", "type": "boolean" }, "client_name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Display name of the registered client, if the row still exists.", "examples": [ "billing-assistant-prod" ], "title": "Client Name" }, "client_origin": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Origin (scheme://host) of the client's first redirect URI — the 'authorized apps' display pattern.", "examples": [ "https://client.example.com" ], "title": "Client Origin" }, "created_at": { "description": "When the grant was created (RFC 3339).", "examples": [ "2026-01-15T09:30:00Z" ], "format": "date-time", "title": "Created At", "type": "string" }, "id": { "description": "Grant ID (ksuid, `ocg_` prefix).", "examples": [ "ocg_6968b3985e21c5fdf643025d" ], "title": "Id", "type": "string" }, "last_used_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "Last time the client obtained tokens under this grant (stamped at exchange/refresh, not per request).", "examples": [ "2026-01-19T08:12:00Z" ], "title": "Last Used At" }, "oauth_client_id": { "description": "The client's public client_id — the same identifier stamped on tokens minted under this grant.", "examples": [ "oc_Xk3vQ9mT2pLw8RzN5bYc1HdF7gJs4AeU" ], "title": "Oauth Client Id", "type": "string" }, "revoked_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "When the grant was revoked (RFC 3339); null while it is active.", "examples": [ "2026-01-20T14:05:00Z" ], "title": "Revoked At" }, "scopes": { "description": "Scopes granted at consent (the D2 intersection).", "examples": [ [ "apis:read", "capabilities:execute" ] ], "items": { "type": "string" }, "title": "Scopes", "type": "array" }, "status": { "description": "Grant lifecycle state: ``active`` or ``revoked``.", "examples": [ "revoked" ], "title": "Status", "type": "string" }, "user_id": { "description": "The consenting user who approved this grant. Shown even after an agent ownership transfer: the grant stays with the original consenter (it is their consent, not the agent's).", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "User Id", "type": "string" } }, "required": [ "id", "oauth_client_id", "client_name", "client_origin", "user_id", "agent_id", "scopes", "status", "created_at", "revoked_at", "last_used_at", "can_revoke" ], "title": "OAuthGrantAdminResponse", "type": "object" }, "OAuthGrantListResponse": { "description": "A paginated list of OAuth grants.", "examples": [ { "data": [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "agent_status": "active", "can_revoke": true, "client_name": "Cursor", "client_origin": "https://client.example.com", "created_at": "2026-01-15T09:30:00Z", "id": "ocg_6968b3985e21c5fdf643025d", "last_used_at": "2026-01-24T08:15:00Z", "oauth_client_id": "oc_Xk3vQ9mT2pLw8RzN5bYc1HdF7gJs4AeU", "revoked_at": "2026-01-25T16:00:00Z", "scopes": [ "apis:read", "capabilities:execute" ], "status": "revoked", "user_id": "usr_6968b3987ee4c3ec0b4ee3b9" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } ], "properties": { "data": { "description": "The page of OAuth grants.", "examples": [ [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "agent_status": "active", "can_revoke": true, "client_name": "Cursor", "client_origin": "https://client.example.com", "created_at": "2026-01-15T09:30:00Z", "id": "ocg_6968b3985e21c5fdf643025d", "last_used_at": "2026-01-24T08:15:00Z", "oauth_client_id": "oc_Xk3vQ9mT2pLw8RzN5bYc1HdF7gJs4AeU", "revoked_at": "2026-01-25T16:00:00Z", "scopes": [ "apis:read", "capabilities:execute" ], "status": "revoked", "user_id": "usr_6968b3987ee4c3ec0b4ee3b9" } ] ], "items": { "$ref": "#/components/schemas/OAuthGrantResponse" }, "title": "Data", "type": "array" }, "has_more": { "description": "Whether more results exist after this page.", "examples": [ true ], "title": "Has More", "type": "boolean" }, "next_cursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Cursor for the next page; null when there are no more results.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Next Cursor" } }, "required": [ "data", "has_more" ], "title": "OAuthGrantListResponse", "type": "object" }, "OAuthGrantResponse": { "description": "One consent→agent grant in API responses.", "examples": [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "agent_status": "active", "can_revoke": true, "client_name": "Cursor", "client_origin": "https://client.example.com", "created_at": "2026-01-15T09:30:00Z", "id": "ocg_6968b3985e21c5fdf643025d", "last_used_at": "2026-01-24T08:15:00Z", "oauth_client_id": "oc_Xk3vQ9mT2pLw8RzN5bYc1HdF7gJs4AeU", "revoked_at": "2026-01-25T16:00:00Z", "scopes": [ "apis:read", "capabilities:execute" ], "status": "revoked", "user_id": "usr_6968b3987ee4c3ec0b4ee3b9" } ], "properties": { "agent_id": { "description": "The agent this grant binds the client to.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" }, "agent_status": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Lifecycle state of the bound agent (`active`, `disabled`, `archived`, …). A grant on a non-active agent is dormant: the row stays `active` (disable is reversible — re-enable restores the standing consent without a new consent round) but no token resolves while the agent is non-active. Lets listings tell a working connection from a dormant one (#1233).", "examples": [ "active" ], "title": "Agent Status" }, "can_revoke": { "description": "Whether the CALLER may revoke this grant (the consenting user, or an admin holding the revoke permission set). May be false even for callers who can list — e.g. the agent's new owner after an ownership transfer, or a read-only admin.", "examples": [ true ], "title": "Can Revoke", "type": "boolean" }, "client_name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Display name of the registered client, if the row still exists.", "examples": [ "Cursor" ], "title": "Client Name" }, "client_origin": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Origin (scheme://host) of the client's first redirect URI — the 'authorized apps' display pattern.", "examples": [ "https://client.example.com" ], "title": "Client Origin" }, "created_at": { "description": "When the grant was created (RFC 3339).", "examples": [ "2026-01-15T09:30:00Z" ], "format": "date-time", "title": "Created At", "type": "string" }, "id": { "description": "Grant ID (ksuid, `ocg_` prefix).", "examples": [ "ocg_6968b3985e21c5fdf643025d" ], "title": "Id", "type": "string" }, "last_used_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "Last time the client obtained tokens under this grant (stamped at exchange/refresh, not per request).", "examples": [ "2026-01-24T08:15:00Z" ], "title": "Last Used At" }, "oauth_client_id": { "description": "The client's public client_id — the same identifier stamped on tokens minted under this grant.", "examples": [ "oc_Xk3vQ9mT2pLw8RzN5bYc1HdF7gJs4AeU" ], "title": "Oauth Client Id", "type": "string" }, "revoked_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "When the grant was revoked (RFC 3339); null while it is active.", "examples": [ "2026-01-25T16:00:00Z" ], "title": "Revoked At" }, "scopes": { "description": "Scopes granted at consent (the D2 intersection).", "examples": [ [ "apis:read", "capabilities:execute" ] ], "items": { "type": "string" }, "title": "Scopes", "type": "array" }, "status": { "description": "Grant lifecycle state: ``active`` or ``revoked``.", "examples": [ "revoked" ], "title": "Status", "type": "string" }, "user_id": { "description": "The consenting user who approved this grant. Shown even after an agent ownership transfer: the grant stays with the original consenter (it is their consent, not the agent's).", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "User Id", "type": "string" } }, "required": [ "id", "oauth_client_id", "client_name", "client_origin", "user_id", "agent_id", "scopes", "status", "created_at", "revoked_at", "last_used_at", "can_revoke" ], "title": "OAuthGrantResponse", "type": "object" }, "OperationPreviewListResponse": { "description": "Capped, offset-paginated operation preview for a catalog entry.\n\nUnlike list endpoints (cursor-paginated), the preview uses simple\noffset/limit pagination deliberately: it reads a single, already-fetched spec\ndocument and is hard-capped at ``PREVIEW_MAX_OPERATIONS`` operations, so there\nis no large/mutating result set that would justify keyset cursors.", "examples": [ { "data": [], "info": { "description": "Payments.", "title": "Stripe", "version": "2024-01-01" }, "offset": 0, "security_schemes": {}, "total": 42, "truncated": true } ], "properties": { "data": { "description": "The page of previewed operations.", "examples": [ [ { "description": "", "method": "GET", "operation_id": "listCharges", "parameters": [], "path": "/v1/charges", "security": [ "BearerAuth" ], "summary": "List charges", "tags": [ "charges" ] } ] ], "items": { "$ref": "#/components/schemas/PreviewOperationResponse" }, "title": "Data", "type": "array" }, "info": { "$ref": "#/components/schemas/PreviewInfoResponse", "description": "The spec's `info` block.", "examples": [ { "description": "Payments.", "title": "Stripe", "version": "2024-01-01" } ] }, "offset": { "description": "Offset of the returned window.", "examples": [ 0 ], "title": "Offset", "type": "integer" }, "security_schemes": { "additionalProperties": { "additionalProperties": true, "type": "object" }, "description": "Slimmed `components.securitySchemes` projection.", "examples": [ { "BearerAuth": { "scheme": "bearer", "type": "http" } } ], "title": "Security Schemes", "type": "object" }, "total": { "description": "Total operations in the spec (pre-page).", "examples": [ 42 ], "title": "Total", "type": "integer" }, "truncated": { "description": "Whether more operations follow this window.", "examples": [ true ], "title": "Truncated", "type": "boolean" } }, "required": [ "data", "total", "offset", "truncated", "info", "security_schemes" ], "title": "OperationPreviewListResponse", "type": "object" }, "OperationResultResponse": { "description": "A single search result matching the OperationResult spec.", "examples": [ { "_links": { "inspect": "https://jentic.example.com/inspect?id=GET%20https%3A%2F%2Fapi.stripe.com%2Fv1%2Fcharges" }, "api": { "host": "api.stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "description": "Returns a list of charges you've previously created, newest first.", "method": "GET", "name": "List all charges", "operation_id": "op_f92d69f1621f381bce8aaff47053c61b069ffe34", "relevance_score": 0.87, "target": "GET:https://api.stripe.com/v1/charges", "type": "operation", "url": "https://api.stripe.com/v1/charges" } ], "properties": { "_links": { "$ref": "#/components/schemas/SearchLinksResponse", "examples": [ { "inspect": "https://jentic.example.com/inspect?id=GET%20https%3A%2F%2Fapi.stripe.com%2Fv1%2Fcharges" } ] }, "api": { "$ref": "#/components/schemas/ApiReferenceResponse", "examples": [ { "host": "api.stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" } ] }, "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Description of the operation; null if the spec gives none.", "examples": [ "Returns a list of charges you've previously created, newest first." ], "title": "Description" }, "method": { "description": "HTTP method of the operation.", "examples": [ "GET" ], "title": "Method", "type": "string" }, "name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Summary of the operation from the spec; null if it has none.", "examples": [ "List all charges" ], "title": "Name" }, "operation_id": { "description": "Registry ID of the operation.", "examples": [ "op_f92d69f1621f381bce8aaff47053c61b069ffe34" ], "title": "Operation Id", "type": "string" }, "relevance_score": { "description": "Relevance of the result to the query, from 0 to 1; higher is more relevant.", "examples": [ 0.87 ], "title": "Relevance Score", "type": "number" }, "target": { "description": "The value to pass as the operation target to inspect/execute (CLI argument; MCP operation_id argument). METHOD:url when url is absolute; the registry operation_id when url is host-relative (the spec declares no servers, or only a relative one) — such a target is inspect-only: with no upstream host there is nothing for the broker to proxy, so execute refuses it.", "examples": [ "GET:https://api.stripe.com/v1/charges" ], "title": "Target", "type": "string" }, "type": { "const": "operation", "default": "operation", "description": "Result kind; always `operation`.", "examples": [ "operation" ], "title": "Type", "type": "string" }, "url": { "description": "URL of the operation, built from the spec's server and path; host-relative when the spec declares no absolute server.", "examples": [ "https://api.stripe.com/v1/charges" ], "title": "Url", "type": "string" } }, "required": [ "api", "operation_id", "method", "url", "target", "relevance_score", "_links" ], "title": "OperationResultResponse", "type": "object" }, "OperationSummaryLinksResponse": { "description": "Hypermedia links for an operation summary.", "examples": [ { "inspect": "https://jentic.example.com/inspect?operation_id=op_f92d69f1621f381bce8aaff47053c61b069ffe34&revision_id=3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" } ], "properties": { "inspect": { "description": "URL of the operation's full detail via `GET /inspect`.", "examples": [ "https://jentic.example.com/inspect?operation_id=op_f92d69f1621f381bce8aaff47053c61b069ffe34&revision_id=3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" ], "title": "Inspect", "type": "string" } }, "required": [ "inspect" ], "title": "OperationSummaryLinksResponse", "type": "object" }, "OperationSummaryListResponse": { "description": "Cursor-paginated list of operations.", "examples": [ { "data": [ { "_links": { "inspect": "https://jentic.example.com/inspect?operation_id=op_f92d69f1621f381bce8aaff47053c61b069ffe34&revision_id=3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" }, "api": { "host": "api.stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "deprecated": false, "description": "Returns a list of charges you've previously created, newest first.", "method": "GET", "name": "List all charges", "operation_id": "op_f92d69f1621f381bce8aaff47053c61b069ffe34", "path": "/v1/charges", "revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "tags": [ "Charges" ] } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } ], "properties": { "data": { "description": "The page of operations.", "examples": [ [ { "_links": { "inspect": "https://jentic.example.com/inspect?operation_id=op_f92d69f1621f381bce8aaff47053c61b069ffe34&revision_id=3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" }, "api": { "host": "api.stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "deprecated": false, "description": "Returns a list of charges you've previously created, newest first.", "method": "GET", "name": "List all charges", "operation_id": "op_f92d69f1621f381bce8aaff47053c61b069ffe34", "path": "/v1/charges", "revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "tags": [ "Charges" ] } ] ], "items": { "$ref": "#/components/schemas/OperationSummaryResponse" }, "title": "Data", "type": "array" }, "has_more": { "description": "Whether more results exist after this page.", "examples": [ true ], "title": "Has More", "type": "boolean" }, "next_cursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Cursor for the next page; null when there are no more results.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Next Cursor" } }, "required": [ "data", "has_more" ], "title": "OperationSummaryListResponse", "type": "object" }, "OperationSummaryResponse": { "description": "Single operation in a paginated list.", "examples": [ { "_links": { "inspect": "https://jentic.example.com/inspect?operation_id=op_f92d69f1621f381bce8aaff47053c61b069ffe34&revision_id=3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" }, "api": { "host": "api.stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "deprecated": false, "description": "Returns a list of charges you've previously created, newest first.", "method": "GET", "name": "List all charges", "operation_id": "op_f92d69f1621f381bce8aaff47053c61b069ffe34", "path": "/v1/charges", "revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "tags": [ "Charges" ] } ], "properties": { "_links": { "$ref": "#/components/schemas/OperationSummaryLinksResponse", "examples": [ { "inspect": "https://jentic.example.com/inspect?operation_id=op_f92d69f1621f381bce8aaff47053c61b069ffe34&revision_id=3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" } ] }, "api": { "$ref": "#/components/schemas/ApiReferenceResponse", "examples": [ { "host": "api.stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" } ] }, "deprecated": { "default": false, "description": "Whether the spec marks the operation as deprecated.", "examples": [ false ], "title": "Deprecated", "type": "boolean" }, "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Description of the operation; null if the spec gives none.", "examples": [ "Returns a list of charges you've previously created, newest first." ], "title": "Description" }, "method": { "description": "HTTP method of the operation.", "examples": [ "GET" ], "title": "Method", "type": "string" }, "name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Summary of the operation from the spec; null if it has none.", "examples": [ "List all charges" ], "title": "Name" }, "operation_id": { "description": "Registry ID of the operation.", "examples": [ "op_f92d69f1621f381bce8aaff47053c61b069ffe34" ], "title": "Operation Id", "type": "string" }, "path": { "description": "Path template of the operation as declared in the spec.", "examples": [ "/v1/charges" ], "title": "Path", "type": "string" }, "revision_id": { "description": "ID of the revision the operation belongs to.", "examples": [ "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" ], "title": "Revision Id", "type": "string" }, "tags": { "description": "Tags the spec assigns to the operation.", "examples": [ [ "Charges" ] ], "items": { "type": "string" }, "title": "Tags", "type": "array" } }, "required": [ "operation_id", "method", "path", "api", "revision_id", "_links" ], "title": "OperationSummaryResponse", "type": "object" }, "OverlayConfirmRequest": { "additionalProperties": false, "description": "Payload for confirming an overlay.", "examples": [ { "execution_id": "exec_6968b3982706c619fe73f0cf" } ], "properties": { "execution_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the execution that verified the overlay, recorded as `confirmed_by_execution_id`.", "examples": [ "exec_6968b3982706c619fe73f0cf" ], "title": "Execution Id" } }, "title": "OverlayConfirmRequest", "type": "object" }, "OverlayLinksResponse": { "description": "Hypermedia links for an overlay resource.\n\nLinks are advertised based on the overlay's *state validity* (mirroring the\nrevisions resource's promote/archive links), so a surface renders an action only\nwhen it is applicable to the current status. They are not permission-scoped — the\n``overlays:confirm`` gate on confirm/rollback is still enforced server-side (403).", "examples": [ { "api": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10", "confirm": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a:confirm", "deprecate": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a", "rollback": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a:rollback", "self": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a" } ], "properties": { "api": { "description": "URL of the API the overlay applies to.", "examples": [ "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10" ], "title": "Api", "type": "string" }, "confirm": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "URL to confirm the overlay; null unless it is `pending`.", "examples": [ "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a:confirm" ], "title": "Confirm" }, "deprecate": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "URL to deprecate the overlay (via `DELETE`); null once it is `deprecated`.", "examples": [ "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a" ], "title": "Deprecate" }, "rollback": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "URL to roll back the overlay; null unless it is `confirmed` and its revision has been produced.", "examples": [ "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a:rollback" ], "title": "Rollback" }, "self": { "description": "URL of this overlay.", "examples": [ "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a" ], "title": "Self", "type": "string" } }, "required": [ "self", "api" ], "title": "OverlayLinksResponse", "type": "object" }, "OverlayListResponse": { "description": "Cursor-paginated list of overlays.", "examples": [ { "data": [ { "_links": { "api": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10", "confirm": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a:confirm", "deprecate": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a", "rollback": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a:rollback", "self": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a" }, "api_id": "debfc9ff-7c37-4a09-801a-575bd4963ddd", "confirmed_at": "2026-01-15T10:05:00Z", "confirmed_by_execution_id": "exec_6968b3982706c619fe73f0cf", "confirmed_revision_id": "6992059c-0abd-4d22-bd07-5287e1bf5e6a", "contributed_by": "docs-review-agent", "created_at": "2026-01-15T09:30:00Z", "created_by": "agnt_6968b3984d1c238dbe7e2e29", "deprecated_at": "2026-01-17T16:45:00Z", "deprecated_reason": "rollback", "document": { "actions": [ { "target": "$.paths['/v1/charges'].get", "update": { "summary": "List all charges, newest first" } } ], "info": { "title": "Clarify charges listing", "version": "1.0.0" }, "overlay": "1.0.0" }, "id": "ovr_6968b398ae1c9a6e2fe6520a", "status": "deprecated", "superseded_revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "target_revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "updated_at": "2026-01-17T16:45:00Z" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } ], "properties": { "data": { "description": "The page of overlays.", "examples": [ [ { "_links": { "api": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10", "confirm": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a:confirm", "deprecate": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a", "rollback": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a:rollback", "self": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a" }, "api_id": "debfc9ff-7c37-4a09-801a-575bd4963ddd", "confirmed_at": "2026-01-15T10:05:00Z", "confirmed_by_execution_id": "exec_6968b3982706c619fe73f0cf", "confirmed_revision_id": "6992059c-0abd-4d22-bd07-5287e1bf5e6a", "contributed_by": "docs-review-agent", "created_at": "2026-01-15T09:30:00Z", "created_by": "agnt_6968b3984d1c238dbe7e2e29", "deprecated_at": "2026-01-17T16:45:00Z", "deprecated_reason": "rollback", "document": { "actions": [ { "target": "$.paths['/v1/charges'].get", "update": { "summary": "List all charges, newest first" } } ], "info": { "title": "Clarify charges listing", "version": "1.0.0" }, "overlay": "1.0.0" }, "id": "ovr_6968b398ae1c9a6e2fe6520a", "status": "deprecated", "superseded_revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "target_revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "updated_at": "2026-01-17T16:45:00Z" } ] ], "items": { "$ref": "#/components/schemas/OverlayResponse" }, "title": "Data", "type": "array" }, "has_more": { "description": "Whether more results exist after this page.", "examples": [ true ], "title": "Has More", "type": "boolean" }, "next_cursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Cursor for the next page; null when there are no more results.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Next Cursor" } }, "required": [ "data", "has_more" ], "title": "OverlayListResponse", "type": "object" }, "OverlayResponse": { "description": "Full overlay resource response.", "examples": [ { "_links": { "api": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10", "confirm": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a:confirm", "deprecate": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a", "rollback": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a:rollback", "self": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a" }, "api_id": "debfc9ff-7c37-4a09-801a-575bd4963ddd", "confirmed_at": "2026-01-15T10:05:00Z", "confirmed_by_execution_id": "exec_6968b3982706c619fe73f0cf", "confirmed_revision_id": "6992059c-0abd-4d22-bd07-5287e1bf5e6a", "contributed_by": "docs-review-agent", "created_at": "2026-01-15T09:30:00Z", "created_by": "agnt_6968b3984d1c238dbe7e2e29", "deprecated_at": "2026-01-17T16:45:00Z", "deprecated_reason": "rollback", "document": { "actions": [ { "target": "$.paths['/v1/charges'].get", "update": { "summary": "List all charges, newest first" } } ], "info": { "title": "Clarify charges listing", "version": "1.0.0" }, "overlay": "1.0.0" }, "id": "ovr_6968b398ae1c9a6e2fe6520a", "status": "deprecated", "superseded_revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "target_revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "updated_at": "2026-01-17T16:45:00Z" } ], "properties": { "_links": { "$ref": "#/components/schemas/OverlayLinksResponse", "examples": [ { "api": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10", "confirm": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a:confirm", "deprecate": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a", "rollback": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a:rollback", "self": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a" } ] }, "api_id": { "description": "ID of the API the overlay applies to.", "examples": [ "debfc9ff-7c37-4a09-801a-575bd4963ddd" ], "title": "Api Id", "type": "string" }, "confirmed_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "When the overlay was confirmed (RFC 3339); null if not confirmed.", "examples": [ "2026-01-15T10:05:00Z" ], "title": "Confirmed At" }, "confirmed_by_execution_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the execution supplied when the overlay was confirmed; null if none.", "examples": [ "exec_6968b3982706c619fe73f0cf" ], "title": "Confirmed By Execution Id" }, "confirmed_revision_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the revision produced by applying the overlay; null until confirmation completes.", "examples": [ "6992059c-0abd-4d22-bd07-5287e1bf5e6a" ], "title": "Confirmed Revision Id" }, "contributed_by": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Free-text attribution label supplied at submission; null if none.", "examples": [ "docs-review-agent" ], "title": "Contributed By" }, "created_at": { "description": "When the overlay was created (RFC 3339).", "examples": [ "2026-01-15T09:30:00Z" ], "format": "date-time", "title": "Created At", "type": "string" }, "created_by": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the actor that created the overlay.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Created By" }, "deprecated_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "When the overlay was deprecated (RFC 3339); null if not deprecated.", "examples": [ "2026-01-17T16:45:00Z" ], "title": "Deprecated At" }, "deprecated_reason": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Why the overlay was deprecated: `manual`, `rollback` or `superseded_by_reimport`; null when not deprecated or not recorded.", "examples": [ "rollback" ], "title": "Deprecated Reason" }, "document": { "additionalProperties": true, "description": "The OpenAPI Overlay document.", "examples": [ { "actions": [ { "target": "$.paths['/v1/charges'].get", "update": { "summary": "List all charges, newest first" } } ], "info": { "title": "Clarify charges listing", "version": "1.0.0" }, "overlay": "1.0.0" } ], "title": "Document", "type": "object" }, "id": { "description": "Unique ID of the overlay.", "examples": [ "ovr_6968b398ae1c9a6e2fe6520a" ], "title": "Id", "type": "string" }, "status": { "description": "Lifecycle status of the overlay: `pending`, `confirmed` or `deprecated`.", "examples": [ "deprecated" ], "title": "Status", "type": "string" }, "superseded_revision_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the revision the overlay replaced when applied, restored by a rollback; null if none.", "examples": [ "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" ], "title": "Superseded Revision Id" }, "target_revision_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the revision the overlay was written against; null if unpinned.", "examples": [ "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" ], "title": "Target Revision Id" }, "updated_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "When the overlay was last updated (RFC 3339); null if never updated.", "examples": [ "2026-01-17T16:45:00Z" ], "title": "Updated At" } }, "required": [ "id", "api_id", "status", "document", "target_revision_id", "contributed_by", "confirmed_by_execution_id", "created_at", "updated_at", "confirmed_at", "deprecated_at", "_links" ], "title": "OverlayResponse", "type": "object" }, "OverlaySubmitRequest": { "additionalProperties": false, "description": "Payload for submitting a new overlay.", "examples": [ { "contributed_by": "docs-review-agent", "document": { "actions": [ { "target": "$.paths['/v1/charges'].get", "update": { "summary": "List all charges, newest first" } } ], "info": { "title": "Clarify charges listing", "version": "1.0.0" }, "overlay": "1.0.0" }, "target_revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" } ], "properties": { "contributed_by": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Free-text attribution label for who contributed the overlay.", "examples": [ "docs-review-agent" ], "title": "Contributed By" }, "document": { "additionalProperties": true, "description": "OpenAPI Overlay document; must be a JSON object with an `actions` array.", "examples": [ { "actions": [ { "target": "$.paths['/v1/charges'].get", "update": { "summary": "List all charges, newest first" } } ], "info": { "title": "Clarify charges listing", "version": "1.0.0" }, "overlay": "1.0.0" } ], "title": "Document", "type": "object" }, "target_revision_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the revision the overlay was written against; null to leave unpinned.", "examples": [ "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" ], "title": "Target Revision Id" } }, "required": [ "document" ], "title": "OverlaySubmitRequest", "type": "object" }, "OverlayUpdateRequest": { "additionalProperties": false, "description": "Payload for updating an existing overlay.", "examples": [ { "document": { "actions": [ { "target": "$.paths['/v1/charges'].get", "update": { "summary": "List all charges, newest first" } } ], "info": { "title": "Clarify charges listing", "version": "1.0.0" }, "overlay": "1.0.0" }, "target_revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" } ], "properties": { "document": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "description": "Replacement OpenAPI Overlay document; omit to keep the current one.", "examples": [ { "actions": [ { "target": "$.paths['/v1/charges'].get", "update": { "summary": "List all charges, newest first" } } ], "info": { "title": "Clarify charges listing", "version": "1.0.0" }, "overlay": "1.0.0" } ], "title": "Document" }, "target_revision_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the revision the overlay was written against.", "examples": [ "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" ], "title": "Target Revision Id" } }, "title": "OverlayUpdateRequest", "type": "object" }, "OwnOAuthClientConfirmSessionRequest": { "additionalProperties": false, "description": "Resolve an ``awaiting_app`` session with the approver's own OAuth client.\n\nThe client is stored on the session's credential (the same shape as a\n``direct_oauth2`` credential) and the session continues as an\nauthorization-code connect. Both endpoints are required: the API's\ndeclared OAuth endpoints are never used for the approver's client, since\nthe spec may be agent-submitted and the token endpoint receives the\nclient secret.", "examples": [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "authorize_url": "https://github.com/login/oauth/authorize", "client_id": "Iv1.a1b2c3d4", "client_secret": "example-secret", "confirmed_scopes": [ "repo", "read:user" ], "digest": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae", "expected_agent_id": "agnt_6968b3984d1c238dbe7e2e29", "kind": "own_oauth_client", "permission_rules": [ { "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ], "token_url": "https://github.com/login/oauth/access_token" } ], "properties": { "agent_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Agent to bind when the session has none; ignored if the session already has one.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id" }, "authorize_url": { "description": "Authorization endpoint URL of the OAuth app.", "examples": [ "https://github.com/login/oauth/authorize" ], "maxLength": 2048, "minLength": 1, "title": "Authorize Url", "type": "string" }, "client_id": { "description": "Client ID of the approver's OAuth app.", "examples": [ "Iv1.a1b2c3d4" ], "maxLength": 255, "minLength": 1, "title": "Client Id", "type": "string" }, "client_secret": { "description": "Client secret of the approver's OAuth app; write-only.", "examples": [ "example-secret" ], "format": "password", "maxLength": 8192, "minLength": 1, "title": "Client Secret", "type": "string", "writeOnly": true, "x-sensitive": true }, "confirmed_scopes": { "description": "Upstream scopes to request (at most 100).", "examples": [ [ "repo", "read:user" ] ], "items": { "type": "string" }, "maxItems": 100, "title": "Confirmed Scopes", "type": "array" }, "digest": { "description": "Review digest echoed from the review data; a mismatch is 409 review_stale.", "examples": [ "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae" ], "maxLength": 64, "minLength": 1, "title": "Digest", "type": "string" }, "expected_agent_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Agent ID from the review the approver saw; a mismatch is 409 review_stale.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Expected Agent Id" }, "kind": { "const": "own_oauth_client", "description": "Confirm variant; always `own_oauth_client`.", "examples": [ "own_oauth_client" ], "title": "Kind", "type": "string" }, "permission_rules": { "description": "Permission rules to bind for the agent (at most 100).", "examples": [ [ { "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] ], "items": { "$ref": "#/components/schemas/PermissionRuleSchema" }, "maxItems": 100, "title": "Permission Rules", "type": "array" }, "token_url": { "description": "Token endpoint URL of the OAuth app.", "examples": [ "https://github.com/login/oauth/access_token" ], "maxLength": 2048, "minLength": 1, "title": "Token Url", "type": "string" } }, "required": [ "permission_rules", "digest", "kind", "client_id", "client_secret", "authorize_url", "token_url" ], "title": "OwnOAuthClientConfirmSessionRequest", "type": "object" }, "PermissionListResponse": { "description": "List of available permissions.", "examples": [ { "data": [ { "description": "Create, update, and disable users", "grantable_by_caller": true, "implies": [ "users:read" ], "name": "users:write" } ] } ], "properties": { "data": { "description": "The permissions in the catalogue.", "examples": [ [ { "description": "Create, update, and disable users", "grantable_by_caller": true, "implies": [ "users:read" ], "name": "users:write" } ] ], "items": { "$ref": "#/components/schemas/PermissionResponse" }, "title": "Data", "type": "array" } }, "required": [ "data" ], "title": "PermissionListResponse", "type": "object" }, "PermissionResponse": { "description": "A single permission entry from the catalogue.", "examples": [ { "description": "Create, update, and disable users", "grantable_by_caller": true, "implies": [ "users:read" ], "name": "users:write" } ], "properties": { "description": { "description": "Human-readable description of what the permission allows.", "examples": [ "Create, update, and disable users" ], "title": "Description", "type": "string" }, "grantable_by_caller": { "description": "Whether the caller may grant this scope to an agent. `org:admin` callers may grant any scope; anyone else only scopes they hold or the default agent scopes, and never `org:admin` or `agents:write`.", "examples": [ true ], "title": "Grantable By Caller", "type": "boolean" }, "implies": { "description": "Permissions this one implies when granted.", "examples": [ [ "users:read" ] ], "items": { "type": "string" }, "title": "Implies", "type": "array" }, "name": { "description": "Permission name, e.g. `users:read`.", "examples": [ "users:write" ], "title": "Name", "type": "string" } }, "required": [ "name", "description", "implies", "grantable_by_caller" ], "title": "PermissionResponse", "type": "object" }, "PermissionRuleListResponse": { "description": "List of permission rules.", "examples": [ { "data": [ { "_comment": "Read-only access to charges.", "_system": false, "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] } ], "properties": { "data": { "description": "The binding's permission rules, in evaluation order.", "examples": [ [ { "_comment": "Read-only access to charges.", "_system": false, "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] ], "items": { "$ref": "#/components/schemas/PermissionRuleReadSchema" }, "title": "Data", "type": "array" } }, "required": [ "data" ], "title": "PermissionRuleListResponse", "type": "object" }, "PermissionRuleReadSchema": { "description": "Permission rule response (includes system fields).", "examples": [ { "_comment": "Read-only access to charges.", "_system": false, "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ], "properties": { "_comment": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Optional note attached to the rule.", "examples": [ "Read-only access to charges." ], "title": "Comment" }, "_system": { "default": false, "description": "True when the rule is platform-managed rather than user-authored.", "examples": [ false ], "title": "System", "type": "boolean" }, "effect": { "description": "Whether this rule allows or denies the matched request.", "enum": [ "allow", "deny" ], "examples": [ "allow" ], "title": "Effect", "type": "string" }, "match_mode": { "default": "regex", "description": "How `path` is interpreted: `regex` (full-match), `prefix` or `exact`.", "enum": [ "regex", "prefix", "exact" ], "examples": [ "prefix" ], "title": "Match Mode", "type": "string" }, "methods": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "description": "HTTP methods the rule matches; null matches all.", "examples": [ [ "GET" ] ], "title": "Methods" }, "operations": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "description": "OpenAPI operation IDs the rule matches; null matches all.", "examples": [ [ "listCharges" ] ], "title": "Operations" }, "path": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Path pattern relative to the API's server URL, interpreted per `match_mode`; null matches all paths.", "examples": [ "/v1/charges" ], "title": "Path" } }, "required": [ "effect" ], "title": "PermissionRuleReadSchema", "type": "object" }, "PermissionRuleSchema": { "additionalProperties": false, "description": "Permission rule for an agent↔credential binding.\n\nRules are evaluated first-match-wins. If no rule matches, the request is\ndenied (default-deny). A binding with zero rules therefore blocks all\noperations — users must explicitly add at least one allow rule.", "examples": [ { "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ], "properties": { "effect": { "description": "Whether this rule allows or denies the matched request.", "enum": [ "allow", "deny" ], "examples": [ "allow" ], "title": "Effect", "type": "string" }, "match_mode": { "default": "regex", "description": "How `path` is interpreted: `regex` (full-match), `prefix` (string prefix), or `exact` (equality). Defaults to `regex` for backwards compatibility.", "enum": [ "regex", "prefix", "exact" ], "examples": [ "prefix" ], "title": "Match Mode", "type": "string" }, "methods": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "description": "HTTP methods to match (case-insensitive). None matches all.", "examples": [ [ "GET" ] ], "title": "Methods" }, "operations": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "description": "OpenAPI operation IDs to match. None matches all operations.", "examples": [ [ "listCharges" ] ], "title": "Operations" }, "path": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Path pattern to match, relative to the API's server URL — the spec's path (`/widgets`), never the full upstream path with the server's base path (`/eu/widgets` for a server `https://host/{region}`). Interpreted per `match_mode`: `regex` uses full-match semantics (the pattern must describe the whole path); `prefix` and `exact` are literal. None matches all paths.", "examples": [ "/v1/charges" ], "title": "Path" } }, "required": [ "effect" ], "title": "PermissionRuleSchema", "type": "object" }, "PermissionTestRequest": { "additionalProperties": false, "description": "Request body for :test — dry-run a request shape against the binding's rules.", "examples": [ { "method": "GET", "operation_id": "listCharges", "path": "/v1/charges" } ], "properties": { "method": { "description": "HTTP method of the hypothetical request (case-insensitive).", "examples": [ "GET" ], "title": "Method", "type": "string" }, "operation_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Optional OpenAPI operation id resolved from the request URL.", "examples": [ "listCharges" ], "title": "Operation Id" }, "path": { "description": "Path of the hypothetical request relative to the API's server URL (the spec's path, e.g. `/widgets/42`) — the path the broker evaluates rules on.", "examples": [ "/v1/charges" ], "title": "Path", "type": "string" } }, "required": [ "method", "path" ], "title": "PermissionTestRequest", "type": "object" }, "PermissionTestResponse": { "description": "Dry-run result matching :class:`PermissionTestResult`.", "examples": [ { "allowed": true, "credential_id": "cred_6968b39855d91a3561684b32", "effect": "allow", "is_system": false, "matched": true, "rule_index": 0 } ], "properties": { "allowed": { "description": "Whether the broker would allow this request under the binding's rules.", "examples": [ true ], "title": "Allowed", "type": "boolean" }, "credential_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "The binding whose rule list contributed the matching rule.", "examples": [ "cred_6968b39855d91a3561684b32" ], "title": "Credential Id" }, "effect": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Effect of the matching rule (`allow`/`deny`); null when no match.", "examples": [ "allow" ], "title": "Effect" }, "is_system": { "anyOf": [ { "type": "boolean" }, { "type": "null" } ], "description": "True when the matching rule was written by the system; null when no match.", "examples": [ false ], "title": "Is System" }, "matched": { "description": "Whether any rule matched; when false, the outcome is default-deny.", "examples": [ true ], "title": "Matched", "type": "boolean" }, "rule_index": { "anyOf": [ { "type": "integer" }, { "type": "null" } ], "description": "Zero-based index in the binding's ordered rule list; null when no match.", "examples": [ 0 ], "title": "Rule Index" } }, "required": [ "allowed", "matched" ], "title": "PermissionTestResponse", "type": "object" }, "Permissions": { "description": "Structured permissions view: assigned + effective.", "examples": [ { "assigned": [ "users:write", "agents:read" ], "effective": [ { "implied_by": "users:write", "name": "users:read" } ] } ], "properties": { "assigned": { "description": "Permissions assigned directly to the user.", "examples": [ [ "users:write", "agents:read" ] ], "items": { "type": "string" }, "title": "Assigned", "type": "array" }, "effective": { "description": "All permissions the user holds, including those implied by assigned ones.", "examples": [ [ { "implied_by": "users:write", "name": "users:read" } ] ], "items": { "$ref": "#/components/schemas/EffectivePermission" }, "title": "Effective", "type": "array" } }, "required": [ "assigned", "effective" ], "title": "Permissions", "type": "object" }, "PermissionsPatchRequest": { "description": "Patch permission rules — add and/or remove.", "examples": [ { "add": [ { "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ], "remove": [ 0, 2 ] } ], "properties": { "add": { "anyOf": [ { "items": { "$ref": "#/components/schemas/PermissionRuleSchema" }, "type": "array" }, { "type": "null" } ], "description": "Rules to append after the existing user rules.", "examples": [ [ { "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] ], "title": "Add" }, "remove": { "anyOf": [ { "items": { "type": "integer" }, "type": "array" }, { "type": "null" } ], "description": "Zero-based indexes of user rules (excluding system rules) to delete; applied before `add`.", "examples": [ [ 0, 2 ] ], "title": "Remove" } }, "title": "PermissionsPatchRequest", "type": "object" }, "PreviewInfoResponse": { "description": "The `info` block fields surfaced in a preview.", "examples": [ { "description": "Payments.", "title": "Stripe", "version": "2024-01-01" } ], "properties": { "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Spec description.", "examples": [ "Payments." ], "title": "Description" }, "title": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Spec title.", "examples": [ "Stripe" ], "title": "Title" }, "version": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Spec version.", "examples": [ "2024-04-10" ], "title": "Version" } }, "required": [ "title", "version", "description" ], "title": "PreviewInfoResponse", "type": "object" }, "PreviewOperationResponse": { "description": "A slimmed operation in a catalog spec preview.", "examples": [ { "description": "", "method": "GET", "operation_id": "listCharges", "parameters": [], "path": "/v1/charges", "security": [ "BearerAuth" ], "summary": "List charges", "tags": [ "charges" ] } ], "properties": { "description": { "description": "Operation description (empty string when absent).", "examples": [ "Returns a list of charges you've previously created, newest first." ], "title": "Description", "type": "string" }, "method": { "description": "Upper-case HTTP method.", "examples": [ "GET" ], "title": "Method", "type": "string" }, "operation_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "OpenAPI operationId, when declared.", "examples": [ "listCharges" ], "title": "Operation Id" }, "parameters": { "description": "Merged path- and operation-level parameters.", "examples": [ [ { "description": "Page size.", "in": "query", "name": "limit", "required": false } ] ], "items": { "$ref": "#/components/schemas/PreviewParameterResponse" }, "title": "Parameters", "type": "array" }, "path": { "description": "Operation path template.", "examples": [ "/v1/charges" ], "title": "Path", "type": "string" }, "security": { "description": "Flattened names of the security schemes that apply.", "examples": [ [ "BearerAuth" ] ], "items": { "type": "string" }, "title": "Security", "type": "array" }, "summary": { "description": "Operation summary (empty string when absent).", "examples": [ "List charges" ], "title": "Summary", "type": "string" }, "tags": { "description": "Operation tags.", "examples": [ [ "charges" ] ], "items": { "type": "string" }, "title": "Tags", "type": "array" } }, "required": [ "method", "path", "summary", "description", "operation_id", "parameters", "security", "tags" ], "title": "PreviewOperationResponse", "type": "object" }, "PreviewParameterResponse": { "description": "A slimmed parameter in an operation preview.", "example": { "description": "Page size.", "in": "query", "name": "limit", "required": false }, "properties": { "description": { "description": "Parameter description (empty string when absent).", "examples": [ "Page size." ], "title": "Description", "type": "string" }, "in": { "description": "OpenAPI parameter location.", "examples": [ "query" ], "title": "In", "type": "string" }, "name": { "description": "Parameter name.", "examples": [ "limit" ], "title": "Name", "type": "string" }, "required": { "description": "Whether the parameter is required.", "examples": [ false ], "title": "Required", "type": "boolean" } }, "required": [ "name", "in", "required", "description" ], "title": "PreviewParameterResponse", "type": "object" }, "ProblemDetail": { "description": "RFC 9457 Problem Details for HTTP APIs.\n\nThis is the standard error response format for all Jentic APIs.\nContent-Type: application/problem+json\n\nSee: https://www.rfc-editor.org/rfc/rfc9457.html", "examples": [ { "detail": "The request body is missing one or more required fields.", "errors": [ { "detail": "Field 'name' is required.", "pointer": "#/name" } ], "instance": "/v2/capability-sets", "status": 400, "title": "Bad Request", "type": "about:blank" } ], "properties": { "code": { "anyOf": [ { "maxLength": 50, "type": "string" }, { "type": "null" } ], "description": "An optional provider-specific code for internal error taxonomy and observability correlation.", "examples": [ "JENTIC-4001" ], "title": "Code" }, "detail": { "description": "A human-readable explanation specific to this occurrence of the problem. MUST be present. Provide actionable information where possible.", "examples": [ "The request body is missing required field 'name'." ], "maxLength": 4096, "title": "Detail", "type": "string" }, "errors": { "anyOf": [ { "items": { "$ref": "#/components/schemas/ErrorItem" }, "maxItems": 1000, "type": "array" }, { "type": "null" } ], "description": "An array of granular error details. Use when multiple validation errors or field-level problems need to be surfaced in a single response.", "examples": [ [ { "code": "JENTIC-V-001", "detail": "Field 'name' must not be blank.", "header": "Authorization", "parameter": "limit", "pointer": "#/name" } ] ], "title": "Errors" }, "instance": { "anyOf": [ { "maxLength": 1024, "type": "string" }, { "type": "null" } ], "description": "A URI reference identifying the specific occurrence of the problem. Typically the request path.", "examples": [ "/v2/capability-sets" ], "title": "Instance" }, "status": { "anyOf": [ { "maximum": 599.0, "minimum": 100.0, "type": "integer" }, { "type": "null" } ], "description": "The HTTP status code for this occurrence of the problem.", "examples": [ 400 ], "title": "Status" }, "title": { "anyOf": [ { "maxLength": 1024, "type": "string" }, { "type": "null" } ], "description": "A short, human-readable summary of the problem type. Should not change between occurrences except for localisation purposes.", "examples": [ "Bad Request" ], "title": "Title" }, "type": { "default": "about:blank", "description": "A URI reference identifying the problem type. When set to 'about:blank', the title SHOULD be the standard HTTP status phrase. Use an IANA-registered type URI where one applies.", "examples": [ "about:blank" ], "maxLength": 1024, "title": "Type", "type": "string" } }, "required": [ "detail" ], "title": "ProblemDetail", "type": "object" }, "ProviderConfigListResponse": { "description": "A list of stored provider configs (secrets redacted).", "examples": [ { "data": [ { "config": { "client_id": "client_abc123", "client_secret": "***", "environment": "production", "kind": "pipedream", "project_id": "proj_abc123" }, "created_at": "2026-06-29T12:00:00Z", "name": "pipedream", "updated_at": "2026-06-29T12:00:00Z" } ] } ], "properties": { "data": { "description": "The stored provider configs.", "examples": [ [ { "config": { "client_id": "client_abc123", "client_secret": "***", "environment": "production", "kind": "pipedream", "project_id": "proj_abc123" }, "created_at": "2026-06-29T12:00:00Z", "name": "pipedream", "updated_at": "2026-06-29T12:00:00Z" } ] ], "items": { "$ref": "#/components/schemas/ProviderConfigResponse" }, "title": "Data", "type": "array" } }, "required": [ "data" ], "title": "ProviderConfigListResponse", "type": "object" }, "ProviderConfigResponse": { "description": "A stored provider config with secret fields redacted.", "examples": [ { "config": { "client_id": "client_abc123", "client_secret": "***", "environment": "production", "kind": "pipedream", "project_id": "proj_abc123" }, "created_at": "2026-06-29T12:00:00Z", "name": "pipedream", "updated_at": "2026-06-29T12:00:00Z" } ], "properties": { "config": { "additionalProperties": true, "description": "Stored config with secret fields redacted.", "examples": [ { "client_id": "client_abc123", "client_secret": "***", "environment": "production", "kind": "pipedream", "project_id": "proj_abc123" } ], "title": "Config", "type": "object" }, "created_at": { "description": "When the provider config was created (RFC 3339).", "examples": [ "2026-01-15T09:30:00Z" ], "format": "date-time", "title": "Created At", "type": "string" }, "name": { "description": "Provider name (e.g. 'pipedream').", "examples": [ "pipedream" ], "title": "Name", "type": "string" }, "updated_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "When the provider config was last updated (RFC 3339); null if never updated.", "examples": [ "2026-01-20T14:05:00Z" ], "title": "Updated At" } }, "required": [ "name", "config", "created_at" ], "title": "ProviderConfigResponse", "type": "object" }, "ProviderConfigSetRequest": { "description": "Request body for setting a provider config.\n\nFields are provider-specific and validated server-side by provider name.\nFor ``pipedream`` the recognised fields are ``project_id``, ``client_id``,\n``client_secret`` (write-only), and optional ``environment``,\n``connect_base_url``, ``expiry_skew_seconds``.", "examples": [ { "config": { "client_id": "client_abc123", "client_secret": "", "environment": "production", "project_id": "proj_abc123" } } ], "properties": { "config": { "additionalProperties": true, "description": "Provider-specific configuration fields, validated by provider name.", "examples": [ { "client_id": "client_abc123", "client_secret": "example-secret", "environment": "production", "project_id": "proj_abc123" } ], "title": "Config", "type": "object" } }, "required": [ "config" ], "title": "ProviderConfigSetRequest", "type": "object" }, "ProviderDiscoveryEntryResponse": { "description": "Discovery metadata for a single credential provider.", "examples": [ { "callback_url": "https://jentic.example.com/api/v1/credentials/oauth/callback", "configured": true, "id": "pipedream", "label": "Pipedream", "managed": true, "types": [ "oauth2", "api_key" ] } ], "properties": { "callback_url": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "OAuth2 redirect URI for providers that require it. When no explicit redirect_uri is configured, this is derived from the deployment's public origin (server.public_base_url or the request origin), so it reflects the exact callback the connect flow will register with the IdP. Add this URL to your OAuth app's allowed redirect URIs.", "examples": [ "https://jentic.example.com/api/v1/credentials/oauth/callback" ], "title": "Callback Url" }, "configured": { "description": "Whether the provider is fully configured and operational.", "examples": [ true ], "title": "Configured", "type": "boolean" }, "id": { "description": "Provider identifier (registry key).", "examples": [ "pipedream" ], "title": "Id", "type": "string" }, "label": { "description": "Human-readable provider name.", "examples": [ "Pipedream" ], "title": "Label", "type": "string" }, "managed": { "description": "Whether the provider handles vendor sign-in on behalf of the user.", "examples": [ true ], "title": "Managed", "type": "boolean" }, "types": { "description": "Wire-level credential types this provider supports.", "examples": [ [ "oauth2", "api_key" ] ], "items": { "$ref": "#/components/schemas/CredentialType" }, "title": "Types", "type": "array" } }, "required": [ "id", "label", "managed", "types", "configured" ], "title": "ProviderDiscoveryEntryResponse", "type": "object" }, "ProviderDiscoveryResponse": { "description": "Discovery response listing all available credential providers.", "examples": [ { "providers": [ { "callback_url": "https://jentic.example.com/api/v1/credentials/oauth/callback", "configured": true, "id": "pipedream", "label": "Pipedream", "managed": true, "types": [ "oauth2", "api_key" ] } ] } ], "properties": { "providers": { "description": "The available credential providers.", "examples": [ [ { "callback_url": "https://jentic.example.com/api/v1/credentials/oauth/callback", "configured": true, "id": "pipedream", "label": "Pipedream", "managed": true, "types": [ "oauth2", "api_key" ] } ] ], "items": { "$ref": "#/components/schemas/ProviderDiscoveryEntryResponse" }, "title": "Providers", "type": "array" } }, "required": [ "providers" ], "title": "ProviderDiscoveryResponse", "type": "object" }, "ReauthorizeConfirmSessionRequest": { "additionalProperties": false, "description": "Bind the approver's OAuth credential and re-consent it with the requested scopes.\n\nRefused when another agent is bound to the credential.", "examples": [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "credential_id": "cred_6968b39855d91a3561684b32", "digest": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae", "expected_agent_id": "agnt_6968b3984d1c238dbe7e2e29", "kind": "reauthorize", "permission_rules": [ { "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] } ], "properties": { "agent_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Agent to bind when the session has none; ignored if the session already has one.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id" }, "credential_id": { "description": "ID of the approver's OAuth credential to bind and re-consent.", "examples": [ "cred_6968b39855d91a3561684b32" ], "maxLength": 30, "minLength": 1, "title": "Credential Id", "type": "string" }, "digest": { "description": "Review digest echoed from the review data; a mismatch is 409 review_stale.", "examples": [ "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae" ], "maxLength": 64, "minLength": 1, "title": "Digest", "type": "string" }, "expected_agent_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Agent ID from the review the approver saw; a mismatch is 409 review_stale.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Expected Agent Id" }, "kind": { "const": "reauthorize", "description": "Confirm variant; always `reauthorize`.", "examples": [ "reauthorize" ], "title": "Kind", "type": "string" }, "permission_rules": { "description": "Permission rules to bind for the agent (at most 100).", "examples": [ [ { "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] ], "items": { "$ref": "#/components/schemas/PermissionRuleSchema" }, "maxItems": 100, "title": "Permission Rules", "type": "array" } }, "required": [ "permission_rules", "digest", "kind", "credential_id" ], "title": "ReauthorizeConfirmSessionRequest", "type": "object" }, "RedeemInviteRequest": { "description": "Payload for redeeming an invite token.", "examples": [ { "invite_token": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk", "password": "example-password" } ], "properties": { "invite_token": { "description": "The invite token issued when the user was created or re-invited.", "examples": [ "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" ], "maxLength": 512, "minLength": 1, "title": "Invite Token", "type": "string", "x-sensitive": true }, "password": { "description": "Password to set for the invited user.", "examples": [ "example-password" ], "maxLength": 128, "minLength": 12, "title": "Password", "type": "string", "x-sensitive": true } }, "required": [ "invite_token", "password" ], "title": "RedeemInviteRequest", "type": "object" }, "RegisterRequest": { "description": "POST /register request body.", "examples": [ { "client_name": "invoice-reconciler", "grant_types": [ "urn:ietf:params:oauth:grant-type:jwt-bearer" ], "jwks": { "keys": [ { "crv": "Ed25519", "kid": "agent-key-1", "kty": "OKP", "x": "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo" } ] }, "scope": "apis:read capabilities:execute", "token_endpoint_auth_method": "private_key_jwt" } ], "properties": { "client_name": { "description": "Name for the new agent.", "examples": [ "invoice-reconciler" ], "maxLength": 255, "minLength": 1, "title": "Client Name", "type": "string" }, "grant_types": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "description": "Accepted for RFC 7591 compatibility and ignored; the agent uses the JWT-bearer grant.", "examples": [ [ "urn:ietf:params:oauth:grant-type:jwt-bearer" ] ], "title": "Grant Types" }, "jwks": { "additionalProperties": true, "description": "A JSON Web Key Set containing at least one Ed25519 public key (kty=OKP, crv=Ed25519). RSA and other key types are not accepted.", "example": { "keys": [ { "crv": "Ed25519", "kid": "agent-key-1", "kty": "OKP", "x": "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo" } ] }, "title": "Jwks", "type": "object" }, "scope": { "anyOf": [ { "maxLength": 6500, "type": "string" }, { "type": "null" } ], "description": "Space-separated permissions requested for the agent (at most 100 tokens).", "examples": [ "apis:read capabilities:execute" ], "title": "Scope" }, "token_endpoint_auth_method": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Accepted for RFC 7591 compatibility and ignored; the agent uses `private_key_jwt`.", "examples": [ "private_key_jwt" ], "title": "Token Endpoint Auth Method" } }, "required": [ "client_name", "jwks" ], "title": "RegisterRequest", "type": "object" }, "RegisterResponse": { "description": "POST /register 201 response.", "examples": [ { "claim_token": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk", "client_id": "agnt_6968b3984d1c238dbe7e2e29", "grant_types": [ "urn:ietf:params:oauth:grant-type:jwt-bearer" ], "registration_access_token": "rat_example-secret", "registration_client_uri": "https://jentic.example.com/register/agnt_6968b3984d1c238dbe7e2e29", "status": "pending", "token_endpoint_auth_method": "private_key_jwt" } ], "properties": { "claim_token": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Single-use token a human presents to `POST /agents/{agent_id}:claim` to take ownership; omitted when the deployment does not issue claim tokens.", "examples": [ "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" ], "title": "Claim Token", "x-sensitive": true }, "client_id": { "description": "ID of the new agent, used as its OAuth client_id.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Client Id", "type": "string" }, "grant_types": { "default": [ "urn:ietf:params:oauth:grant-type:jwt-bearer" ], "description": "Grant types the agent may use; always the JWT-bearer grant.", "examples": [ [ "urn:ietf:params:oauth:grant-type:jwt-bearer" ] ], "items": { "type": "string" }, "title": "Grant Types", "type": "array" }, "registration_access_token": { "description": "Bearer token for polling `registration_client_uri`; shown once and expires after a configured time.", "examples": [ "rat_example-secret" ], "title": "Registration Access Token", "type": "string", "x-sensitive": true }, "registration_client_uri": { "description": "URL to poll for the registration status.", "examples": [ "https://jentic.example.com/register/agnt_6968b3984d1c238dbe7e2e29" ], "title": "Registration Client Uri", "type": "string" }, "status": { "description": "Lifecycle status of the new agent; `pending` until an operator approves it.", "examples": [ "pending" ], "title": "Status", "type": "string" }, "token_endpoint_auth_method": { "default": "private_key_jwt", "description": "How the agent authenticates at the token endpoint; always `private_key_jwt`.", "examples": [ "private_key_jwt" ], "title": "Token Endpoint Auth Method", "type": "string" } }, "required": [ "client_id", "registration_access_token", "registration_client_uri", "status" ], "title": "RegisterResponse", "type": "object" }, "RegistrationStatusResponse": { "description": "GET /register/{agent_id} response.", "examples": [ { "client_id": "agnt_6968b3984d1c238dbe7e2e29", "grant_types": [ "urn:ietf:params:oauth:grant-type:jwt-bearer" ], "status": "active", "token_endpoint_auth_method": "private_key_jwt" } ], "properties": { "client_id": { "description": "ID of the agent, used as its OAuth client_id.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Client Id", "type": "string" }, "grant_types": { "default": [ "urn:ietf:params:oauth:grant-type:jwt-bearer" ], "description": "Grant types the agent may use; always the JWT-bearer grant.", "examples": [ [ "urn:ietf:params:oauth:grant-type:jwt-bearer" ] ], "items": { "type": "string" }, "title": "Grant Types", "type": "array" }, "status": { "description": "Lifecycle status of the agent: `pending`, `active`, `rejected`, `disabled` or `archived`.", "examples": [ "active" ], "title": "Status", "type": "string" }, "token_endpoint_auth_method": { "default": "private_key_jwt", "description": "How the agent authenticates at the token endpoint; always `private_key_jwt`.", "examples": [ "private_key_jwt" ], "title": "Token Endpoint Auth Method", "type": "string" } }, "required": [ "client_id", "status" ], "title": "RegistrationStatusResponse", "type": "object" }, "RevokeRequest": { "description": "Revocation endpoint request (RFC 7009) — JSON or form-encoded.\n\n``token`` is required either way. ``token_type_hint``\n(``access_token``/``refresh_token``) is a lookup-order optimization only —\nthe server falls through both types regardless (RFC 7009 §2.1).\n``client_id`` belongs to the form-encoded public-client arm (G11): the\nsecret-less client's lineage binding; ignored on the bearer-authenticated\nJSON arm, where the platform identity scopes the revocation instead.", "examples": [ { "client_id": "oc_Xk3vQ9mT2pLw8RzN5bYc1HdF7gJs4AeU", "token": "rt_example-refresh-token", "token_type_hint": "refresh_token" } ], "properties": { "client_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Public client's client_id, used on form-encoded requests; ignored on bearer-authenticated JSON requests.", "examples": [ "oc_Xk3vQ9mT2pLw8RzN5bYc1HdF7gJs4AeU" ], "title": "Client Id" }, "token": { "description": "The token to revoke.", "examples": [ "rt_example-refresh-token" ], "title": "Token", "type": "string", "x-sensitive": true }, "token_type_hint": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Optional hint, `access_token` or `refresh_token`; both types are checked regardless.", "examples": [ "refresh_token" ], "title": "Token Type Hint" } }, "required": [ "token" ], "title": "RevokeRequest", "type": "object" }, "RootHealthResponse": { "description": "Liveness body of the canonical root ``GET /health`` probe.", "examples": [ { "status": "ok", "version": "1.0.0" } ], "properties": { "reason": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Why the deployment is not entitled. Present only on the `not_entitled` body.", "examples": [ "AWS Marketplace subscription is not active for this deployment; renew the subscription to restore service" ], "title": "Reason" }, "status": { "description": "`ok` while the process is serving requests. A metered marketplace deployment whose entitlement lapsed answers `not_entitled` (still HTTP 200, so orchestrators don't restart it).", "examples": [ "ok" ], "title": "Status", "type": "string" }, "version": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Running Jentic One release. Absent on the `not_entitled` body.", "examples": [ "1.0.0" ], "title": "Version" } }, "required": [ "status" ], "title": "RootHealthResponse", "type": "object" }, "RouteNotFoundResponse": { "description": "The framework's plain route-not-found body.\n\nConfig-gated routes answer this exact body when their gate is closed, so the\ngate state is indistinguishable from a route that does not exist.", "examples": [ { "detail": "Not Found" } ], "properties": { "detail": { "description": "Always `Not Found`.", "examples": [ "Not Found" ], "title": "Detail", "type": "string" } }, "required": [ "detail" ], "title": "RouteNotFoundResponse", "type": "object" }, "RuleSetAttachRequest": { "description": "Point a direct agent↔credential binding at a shared rule set.", "examples": [ { "rule_set_id": "prs_6968b3987c22b63e87e79f05" } ], "properties": { "rule_set_id": { "description": "Id (`prs_…`) of the rule set to attach.", "examples": [ "prs_6968b3987c22b63e87e79f05" ], "title": "Rule Set Id", "type": "string" } }, "required": [ "rule_set_id" ], "title": "RuleSetAttachRequest", "type": "object" }, "RuleSetCreateRequest": { "description": "Create a shared permission rule set (theme 5 phase 1, Q-04).", "examples": [ { "description": "Allows GET requests to the Stripe API; denies everything else.", "name": "Stripe read-only", "rules": [ { "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] } ], "properties": { "description": { "anyOf": [ { "maxLength": 1000, "type": "string" }, { "type": "null" } ], "description": "Optional free-text description of the set.", "examples": [ "Allows GET requests to the Stripe API; denies everything else." ], "title": "Description" }, "name": { "description": "Unique human-readable name.", "examples": [ "Stripe read-only" ], "maxLength": 255, "title": "Name", "type": "string" }, "rules": { "description": "Initial ordered rule list (first-match-wins, default-deny).", "examples": [ [ { "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] ], "items": { "$ref": "#/components/schemas/PermissionRuleSchema" }, "maxItems": 100, "title": "Rules", "type": "array" } }, "required": [ "name" ], "title": "RuleSetCreateRequest", "type": "object" }, "RuleSetListResponse": { "description": "Paginated list of rule sets.", "examples": [ { "data": [ { "created_at": "2026-01-15T09:30:00Z", "created_by": "usr_6968b3987ee4c3ec0b4ee3b9", "curated": true, "description": "Allows GET requests to the Stripe API; denies everything else.", "name": "Stripe read-only", "rule_count": 2, "rule_set_id": "prs_6968b3987c22b63e87e79f05" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } ], "properties": { "data": { "description": "The page of rule sets.", "examples": [ [ { "created_at": "2026-01-15T09:30:00Z", "created_by": "usr_6968b3987ee4c3ec0b4ee3b9", "curated": true, "description": "Allows GET requests to the Stripe API; denies everything else.", "name": "Stripe read-only", "rule_count": 2, "rule_set_id": "prs_6968b3987c22b63e87e79f05" } ] ], "items": { "$ref": "#/components/schemas/RuleSetSummaryResponse" }, "title": "Data", "type": "array" }, "has_more": { "description": "Whether more results exist after this page.", "examples": [ true ], "title": "Has More", "type": "boolean" }, "next_cursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Cursor for the next page; null when there are no more results.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Next Cursor" } }, "required": [ "data", "has_more" ], "title": "RuleSetListResponse", "type": "object" }, "RuleSetResponse": { "description": "Rule set detail — the ordered rules plus its referencing-binding count.", "examples": [ { "binding_count": 3, "created_at": "2026-01-15T09:30:00Z", "created_by": "usr_6968b3987ee4c3ec0b4ee3b9", "curated": true, "description": "Allows GET requests to the Stripe API; denies everything else.", "name": "Stripe read-only", "rule_set_id": "prs_6968b3987c22b63e87e79f05", "rules": [ { "_comment": "Read-only access to charges.", "_system": false, "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] } ], "properties": { "binding_count": { "description": "How many agent-credential bindings currently point at this set.", "examples": [ 3 ], "title": "Binding Count", "type": "integer" }, "created_at": { "description": "When the rule set was created (RFC 3339).", "examples": [ "2026-01-15T09:30:00Z" ], "format": "date-time", "title": "Created At", "type": "string" }, "created_by": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the actor that created the rule set.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "Created By" }, "curated": { "description": "True when an org admin created the set. A curated set can be attached by any caller allowed to write a binding's rules and edited only by an org admin; any other set is attachable and editable by its creator or an org admin.", "examples": [ true ], "title": "Curated", "type": "boolean" }, "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Free-text description of the rule set; null if unset.", "examples": [ "Allows GET requests to the Stripe API; denies everything else." ], "title": "Description" }, "name": { "description": "Unique human-readable name of the rule set.", "examples": [ "Stripe read-only" ], "title": "Name", "type": "string" }, "rule_set_id": { "description": "Unique ID of the rule set (`prs_…`).", "examples": [ "prs_6968b3987c22b63e87e79f05" ], "title": "Rule Set Id", "type": "string" }, "rules": { "description": "Ordered rule list (first-match-wins, default-deny).", "examples": [ [ { "_comment": "Read-only access to charges.", "_system": false, "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] ], "items": { "$ref": "#/components/schemas/PermissionRuleReadSchema" }, "title": "Rules", "type": "array" } }, "required": [ "rule_set_id", "name", "rules", "binding_count", "curated", "created_at" ], "title": "RuleSetResponse", "type": "object" }, "RuleSetSummaryResponse": { "description": "Rule set list entry.", "examples": [ { "created_at": "2026-01-15T09:30:00Z", "created_by": "usr_6968b3987ee4c3ec0b4ee3b9", "curated": true, "description": "Allows GET requests to the Stripe API; denies everything else.", "name": "Stripe read-only", "rule_count": 2, "rule_set_id": "prs_6968b3987c22b63e87e79f05" } ], "properties": { "created_at": { "description": "When the rule set was created (RFC 3339).", "examples": [ "2026-01-15T09:30:00Z" ], "format": "date-time", "title": "Created At", "type": "string" }, "created_by": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the actor that created the rule set.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "Created By" }, "curated": { "description": "True when an org admin created the set. A curated set can be attached by any caller allowed to write a binding's rules and edited only by an org admin; any other set is attachable and editable by its creator or an org admin.", "examples": [ true ], "title": "Curated", "type": "boolean" }, "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Free-text description of the rule set; null if unset.", "examples": [ "Allows GET requests to the Stripe API; denies everything else." ], "title": "Description" }, "name": { "description": "Unique human-readable name of the rule set.", "examples": [ "Stripe read-only" ], "title": "Name", "type": "string" }, "rule_count": { "description": "Number of rules in the set.", "examples": [ 2 ], "title": "Rule Count", "type": "integer" }, "rule_set_id": { "description": "Unique ID of the rule set (`prs_…`).", "examples": [ "prs_6968b3987c22b63e87e79f05" ], "title": "Rule Set Id", "type": "string" } }, "required": [ "rule_set_id", "name", "rule_count", "curated", "created_at" ], "title": "RuleSetSummaryResponse", "type": "object" }, "RuleSetUpdateRequest": { "description": "Rename or re-describe a rule set.", "examples": [ { "description": "Allows GET requests to the Stripe API; denies everything else.", "name": "Stripe read-only" } ], "properties": { "description": { "anyOf": [ { "maxLength": 1000, "type": "string" }, { "type": "null" } ], "description": "New description; omit to leave unchanged.", "examples": [ "Allows GET requests to the Stripe API; denies everything else." ], "title": "Description" }, "name": { "anyOf": [ { "maxLength": 255, "type": "string" }, { "type": "null" } ], "description": "New unique name; omit to leave unchanged.", "examples": [ "Stripe read-only" ], "title": "Name" } }, "title": "RuleSetUpdateRequest", "type": "object" }, "RuntimeConfig": { "description": "Optional per-upstream-call overrides.", "examples": [ { "headers": { "Stripe-Version": "2024-04-10" }, "query_params": { "locale": "en-GB" } } ], "properties": { "headers": { "anyOf": [ { "additionalProperties": { "type": "string" }, "type": "object" }, { "type": "null" } ], "description": "Header overrides for upstream calls.", "examples": [ { "Stripe-Version": "2024-04-10" } ], "title": "Headers" }, "query_params": { "anyOf": [ { "additionalProperties": { "type": "string" }, "type": "object" }, { "type": "null" } ], "description": "Query-parameter overrides for upstream calls.", "examples": [ { "locale": "en-GB" } ], "title": "Query Params" } }, "title": "RuntimeConfig", "type": "object" }, "SearchLinksResponse": { "description": "Hypermedia links for a search result row.", "examples": [ { "inspect": "https://jentic.example.com/inspect?id=GET%20https%3A%2F%2Fapi.stripe.com%2Fv1%2Fcharges" } ], "properties": { "inspect": { "description": "URL of the operation's full detail via `GET /inspect`.", "examples": [ "https://jentic.example.com/inspect?id=GET%20https%3A%2F%2Fapi.stripe.com%2Fv1%2Fcharges" ], "title": "Inspect", "type": "string" } }, "required": [ "inspect" ], "title": "SearchLinksResponse", "type": "object" }, "SearchRequest": { "additionalProperties": false, "description": "POST /search request body.", "examples": [ { "apis": [ "stripe.com/stripe" ], "cursor": "eyJkIjogMC4yODE2LCAiaWQiOiAib3BfZjkyZDY5ZjE2MjFmMzgxYmNlOGFhZmY0NzA1M2M2MWIwNjlmZmUzNCJ9", "limit": 10, "query": "list recent charges", "revision_pins": { "stripe.com/stripe/2024-04-10": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" } } ], "properties": { "apis": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "description": "Restrict results to these APIs. Each entry is a 'vendor[/name[/version]]' identifier of an imported API (e.g. 'github-com/api-github-com/1.1.4'); vendor and name are normalized like ingest, so raw spellings such as 'stripe.com/api' also resolve. The legacy colon-separated form 'vendor[:name[:version]]' is also accepted.", "examples": [ [ "stripe.com/stripe" ] ], "title": "Apis" }, "cursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": [ "eyJkIjogMC4yODE2LCAiaWQiOiAib3BfZjkyZDY5ZjE2MjFmMzgxYmNlOGFhZmY0NzA1M2M2MWIwNjlmZmUzNCJ9" ], "title": "Cursor" }, "limit": { "default": 10, "description": "Maximum number of results to return (1-100).", "examples": [ 10 ], "maximum": 100.0, "minimum": 1.0, "title": "Limit", "type": "integer" }, "query": { "description": "Free-text search query; must not be empty.", "examples": [ "list recent charges" ], "minLength": 1, "title": "Query", "type": "string" }, "revision_pins": { "anyOf": [ { "additionalProperties": { "type": "string" }, "type": "object" }, { "type": "null" } ], "description": "Pin specific APIs to a revision for this search. Keys are full 'vendor/name/version' identifiers (colon-separated also accepted); values are revision UUIDs.", "examples": [ { "stripe.com/stripe/2024-04-10": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" } ], "title": "Revision Pins" } }, "required": [ "query" ], "title": "SearchRequest", "type": "object" }, "SearchResponse": { "description": "Cursor-paginated search results page.", "examples": [ { "data": [ { "_links": { "inspect": "https://jentic.example.com/inspect?id=GET%20https%3A%2F%2Fapi.stripe.com%2Fv1%2Fcharges" }, "api": { "host": "api.stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "description": "Returns a list of charges you've previously created, newest first.", "method": "GET", "name": "List all charges", "operation_id": "op_f92d69f1621f381bce8aaff47053c61b069ffe34", "relevance_score": 0.87, "target": "GET:https://api.stripe.com/v1/charges", "type": "operation", "url": "https://api.stripe.com/v1/charges" } ], "has_more": true, "next_cursor": "eyJkIjogMC4yODE2LCAiaWQiOiAib3BfZjkyZDY5ZjE2MjFmMzgxYmNlOGFhZmY0NzA1M2M2MWIwNjlmZmUzNCJ9" } ], "properties": { "data": { "description": "The page of matching operations.", "examples": [ [ { "_links": { "inspect": "https://jentic.example.com/inspect?id=GET%20https%3A%2F%2Fapi.stripe.com%2Fv1%2Fcharges" }, "api": { "host": "api.stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "description": "Returns a list of charges you've previously created, newest first.", "method": "GET", "name": "List all charges", "operation_id": "op_f92d69f1621f381bce8aaff47053c61b069ffe34", "relevance_score": 0.87, "target": "GET:https://api.stripe.com/v1/charges", "type": "operation", "url": "https://api.stripe.com/v1/charges" } ] ], "items": { "$ref": "#/components/schemas/OperationResultResponse" }, "title": "Data", "type": "array" }, "has_more": { "description": "Whether more results exist after this page.", "examples": [ true ], "title": "Has More", "type": "boolean" }, "next_cursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Cursor for the next page; null when there are no more results.", "examples": [ "eyJkIjogMC4yODE2LCAiaWQiOiAib3BfZjkyZDY5ZjE2MjFmMzgxYmNlOGFhZmY0NzA1M2M2MWIwNjlmZmUzNCJ9" ], "title": "Next Cursor" } }, "required": [ "data", "has_more" ], "title": "SearchResponse", "type": "object" }, "SecuritySchemeFlowResponse": { "description": "A single OAuth2 flow within a security scheme.", "examples": [ { "authorization_url": "https://connect.stripe.com/oauth/authorize", "flow_type": "authorizationCode", "refresh_url": "https://connect.stripe.com/oauth/token", "scopes": { "read_only": "Read-only access", "read_write": "Read and write access" }, "token_url": "https://connect.stripe.com/oauth/token" } ], "properties": { "authorization_url": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Authorization endpoint URL; null if the flow has none.", "examples": [ "https://connect.stripe.com/oauth/authorize" ], "title": "Authorization Url" }, "flow_type": { "description": "OAuth2 flow type (for example `authorizationCode` or `clientCredentials`).", "examples": [ "authorizationCode" ], "title": "Flow Type", "type": "string" }, "refresh_url": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Token refresh URL; null if the flow has none.", "examples": [ "https://connect.stripe.com/oauth/token" ], "title": "Refresh Url" }, "scopes": { "anyOf": [ { "additionalProperties": { "type": "string" }, "type": "object" }, { "type": "null" } ], "description": "Available scopes mapped to their descriptions.", "examples": [ { "read_only": "Read-only access", "read_write": "Read and write access" } ], "title": "Scopes" }, "token_url": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Token endpoint URL; null if the flow has none.", "examples": [ "https://connect.stripe.com/oauth/token" ], "title": "Token Url" } }, "required": [ "flow_type" ], "title": "SecuritySchemeFlowResponse", "type": "object" }, "SecuritySchemeListResponse": { "description": "List of security schemes for an API's current revision.", "examples": [ { "data": [ { "bearer_format": "JWT", "description": "Use your secret API key as the bearer token.", "flows": [ { "authorization_url": "https://connect.stripe.com/oauth/authorize", "flow_type": "authorizationCode", "refresh_url": "https://connect.stripe.com/oauth/token", "scopes": { "read_only": "Read-only access", "read_write": "Read and write access" }, "token_url": "https://connect.stripe.com/oauth/token" } ], "in_location": "header", "name": "bearerAuth", "open_id_connect_url": "https://accounts.example.com/.well-known/openid-configuration", "param_name": "X-API-Key", "scheme": "bearer", "type": "http" } ] } ], "properties": { "data": { "description": "Security schemes declared by the API's current revision.", "examples": [ [ { "bearer_format": "JWT", "description": "Use your secret API key as the bearer token.", "flows": [ { "authorization_url": "https://connect.stripe.com/oauth/authorize", "flow_type": "authorizationCode", "refresh_url": "https://connect.stripe.com/oauth/token", "scopes": { "read_only": "Read-only access", "read_write": "Read and write access" }, "token_url": "https://connect.stripe.com/oauth/token" } ], "in_location": "header", "name": "bearerAuth", "open_id_connect_url": "https://accounts.example.com/.well-known/openid-configuration", "param_name": "X-API-Key", "scheme": "bearer", "type": "http" } ] ], "items": { "$ref": "#/components/schemas/SecuritySchemeResponse" }, "title": "Data", "type": "array" } }, "required": [ "data" ], "title": "SecuritySchemeListResponse", "type": "object" }, "SecuritySchemeResponse": { "description": "Full security scheme detail for a revision.", "examples": [ { "bearer_format": "JWT", "description": "Use your secret API key as the bearer token.", "flows": [ { "authorization_url": "https://connect.stripe.com/oauth/authorize", "flow_type": "authorizationCode", "refresh_url": "https://connect.stripe.com/oauth/token", "scopes": { "read_only": "Read-only access", "read_write": "Read and write access" }, "token_url": "https://connect.stripe.com/oauth/token" } ], "in_location": "header", "name": "bearerAuth", "open_id_connect_url": "https://accounts.example.com/.well-known/openid-configuration", "param_name": "X-API-Key", "scheme": "bearer", "type": "http" } ], "properties": { "bearer_format": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Hint for the bearer token format; null if not declared.", "examples": [ "JWT" ], "title": "Bearer Format" }, "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Description of the scheme from the spec; null if none.", "examples": [ "Use your secret API key as the bearer token." ], "title": "Description" }, "flows": { "description": "OAuth2 flows declared by the scheme; empty for other types.", "examples": [ [ { "authorization_url": "https://connect.stripe.com/oauth/authorize", "flow_type": "authorizationCode", "refresh_url": "https://connect.stripe.com/oauth/token", "scopes": { "read_only": "Read-only access", "read_write": "Read and write access" }, "token_url": "https://connect.stripe.com/oauth/token" } ] ], "items": { "$ref": "#/components/schemas/SecuritySchemeFlowResponse" }, "title": "Flows", "type": "array" }, "in_location": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Where an API key is sent (`header`, `query` or `cookie`); null for other types.", "examples": [ "header" ], "title": "In Location" }, "name": { "description": "Name of the security scheme as declared in the spec.", "examples": [ "bearerAuth" ], "title": "Name", "type": "string" }, "open_id_connect_url": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "OpenID Connect discovery URL; null unless `type` is `openIdConnect`.", "examples": [ "https://accounts.example.com/.well-known/openid-configuration" ], "title": "Open Id Connect Url" }, "param_name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Name of the header, query or cookie parameter carrying the API key.", "examples": [ "X-API-Key" ], "title": "Param Name" }, "scheme": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "HTTP authentication scheme (for example `bearer`); null unless `type` is `http`.", "examples": [ "bearer" ], "title": "Scheme" }, "type": { "description": "Security scheme type (for example `apiKey`, `http`, `oauth2` or `openIdConnect`).", "examples": [ "http" ], "title": "Type", "type": "string" } }, "required": [ "name", "type" ], "title": "SecuritySchemeResponse", "type": "object" }, "ServedApiRef": { "description": "An API served by an agent's bound credential, keyed by its stored identity.\n\nDistinct from ``APIReference`` on purpose: this carries the *stored* credential\nidentity, where ``api_name``/``api_version`` may be NULL (the \"covers all\nnames/versions\" wildcard, #775) — so they're optional here, unlike the strict\nall-required ``APIReference``. Shared so the auth service schema and the\n``/me`` web schema use ONE model instead of two identical copies.", "examples": [ { "api_name": "stripe", "api_vendor": "stripe.com", "api_version": "2024-04-10" } ], "properties": { "api_name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Name of the served API; null means every API of the vendor.", "examples": [ "stripe" ], "title": "Api Name" }, "api_vendor": { "description": "Vendor of the served API.", "examples": [ "stripe.com" ], "title": "Api Vendor", "type": "string" }, "api_version": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Version of the served API; null means every version.", "examples": [ "2024-04-10" ], "title": "Api Version" } }, "required": [ "api_vendor" ], "title": "ServedApiRef", "type": "object" }, "SetPermissionsRequest": { "description": "Request body for setting user permissions.", "examples": [ { "permissions": [ "users:write", "agents:read" ] } ], "properties": { "permissions": { "description": "Permissions to assign to the user; replaces the current assigned set.", "examples": [ [ "users:write", "agents:read" ] ], "items": { "type": "string" }, "maxItems": 50, "title": "Permissions", "type": "array" } }, "required": [ "permissions" ], "title": "SetPermissionsRequest", "type": "object" }, "Sigv4CreateRequest": { "description": "Create request for sigv4 (AWS Signature V4) credentials.", "examples": [ { "access_key_id": "AKIAIOSFODNN7EXAMPLE", "api": { "catalog_api_id": "stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "aws_region": "us-east-1", "aws_service": "execute-api", "name": "Stripe live key", "provider": "static", "runtime_config": { "headers": { "Stripe-Version": "2024-04-10" }, "query_params": { "locale": "en-GB" } }, "secret_access_key": "example-secret", "server_variables": { "region": "eu" }, "session_token": "example-secret", "type": "sigv4" } ], "properties": { "access_key_id": { "description": "AWS access key id (public identifier).", "examples": [ "AKIAIOSFODNN7EXAMPLE" ], "title": "Access Key Id", "type": "string" }, "api": { "$ref": "#/components/schemas/APIReferenceRequest", "description": "Loose (vendor, name, version) API identity tuple.", "examples": [ { "catalog_api_id": "stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" } ] }, "aws_region": { "description": "Signing region, e.g. 'us-east-1'.", "examples": [ "us-east-1" ], "title": "Aws Region", "type": "string" }, "aws_service": { "description": "Signing service, e.g. 'aoss', 'execute-api', 's3'.", "examples": [ "execute-api" ], "title": "Aws Service", "type": "string" }, "name": { "description": "Human-readable label for the credential.", "examples": [ "Stripe live key" ], "title": "Name", "type": "string" }, "provider": { "default": "static", "description": "Credential provider; 'static' for stored secrets.", "examples": [ "static" ], "title": "Provider", "type": "string" }, "runtime_config": { "anyOf": [ { "$ref": "#/components/schemas/RuntimeConfig" }, { "type": "null" } ], "description": "Per-upstream-call overrides; reserved and not currently applied.", "examples": [ { "headers": { "Stripe-Version": "2024-04-10" }, "query_params": { "locale": "en-GB" } } ] }, "secret_access_key": { "description": "AWS secret access key. Stored encrypted; never returned after create.", "examples": [ "example-secret" ], "title": "Secret Access Key", "type": "string", "x-sensitive": true }, "server_variables": { "anyOf": [ { "additionalProperties": { "type": "string" }, "type": "object" }, { "type": "null" } ], "description": "OpenAPI server-variable values for URL template substitution (at most 20).", "examples": [ { "region": "eu" } ], "title": "Server Variables" }, "session_token": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Optional temporary-credential session token (STS). Expires; re-save when it does.", "examples": [ "example-secret" ], "title": "Session Token", "x-sensitive": true }, "type": { "const": "sigv4", "description": "Credential type; always `sigv4`.", "examples": [ "sigv4" ], "title": "Type", "type": "string" } }, "required": [ "type", "name", "api", "access_key_id", "secret_access_key", "aws_region", "aws_service" ], "title": "Sigv4CreateRequest", "type": "object" }, "Sigv4UpdateRequest": { "description": "Update request for sigv4 credentials (key rotation / scope edit).", "examples": [ { "access_key_id": "AKIAIOSFODNN7EXAMPLE", "active": true, "aws_region": "us-east-1", "aws_service": "execute-api", "clear_session_token": false, "name": "Stripe live key", "runtime_config": { "headers": { "Stripe-Version": "2024-04-10" }, "query_params": { "locale": "en-GB" } }, "secret_access_key": "example-secret", "server_variables": { "region": "eu" }, "session_token": "example-secret", "type": "sigv4" } ], "properties": { "access_key_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Replacement AWS access key ID; must be sent with secret_access_key.", "examples": [ "AKIAIOSFODNN7EXAMPLE" ], "title": "Access Key Id" }, "active": { "anyOf": [ { "type": "boolean" }, { "type": "null" } ], "description": "Enable or disable the credential for injection; omit to leave unchanged.", "examples": [ true ], "title": "Active" }, "aws_region": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Replacement signing region; omit to leave unchanged.", "examples": [ "us-east-1" ], "title": "Aws Region" }, "aws_service": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Replacement signing service; omit to leave unchanged.", "examples": [ "execute-api" ], "title": "Aws Service" }, "clear_session_token": { "default": false, "description": "Remove the stored session token; takes precedence over session_token.", "examples": [ false ], "title": "Clear Session Token", "type": "boolean" }, "name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "New label for the credential; omit to leave unchanged.", "examples": [ "Stripe live key" ], "title": "Name" }, "runtime_config": { "anyOf": [ { "$ref": "#/components/schemas/RuntimeConfig" }, { "type": "null" } ], "description": "Per-upstream-call overrides; reserved and not currently applied.", "examples": [ { "headers": { "Stripe-Version": "2024-04-10" }, "query_params": { "locale": "en-GB" } } ] }, "secret_access_key": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Replacement AWS secret access key; must be sent with access_key_id.", "examples": [ "example-secret" ], "title": "Secret Access Key", "x-sensitive": true }, "server_variables": { "anyOf": [ { "additionalProperties": { "type": "string" }, "type": "object" }, { "type": "null" } ], "description": "Replacement OpenAPI server-variable values; omit to leave unchanged.", "examples": [ { "region": "eu" } ], "title": "Server Variables" }, "session_token": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Replacement STS session token; omit to leave unchanged.", "examples": [ "example-secret" ], "title": "Session Token", "x-sensitive": true }, "type": { "const": "sigv4", "description": "Credential type; always `sigv4`.", "examples": [ "sigv4" ], "title": "Type", "type": "string" } }, "required": [ "type" ], "title": "Sigv4UpdateRequest", "type": "object" }, "TokenResponse": { "description": "Token endpoint success response.", "examples": [ { "access_token": "at_example-access-token", "expires_in": 3600, "id_token": "example-id-token", "refresh_token": "rt_example-refresh-token", "scope": "apis:read capabilities:execute", "token_type": "bearer" } ], "properties": { "access_token": { "description": "The access token to send as a bearer token.", "examples": [ "at_example-access-token" ], "title": "Access Token", "type": "string", "x-sensitive": true }, "expires_in": { "description": "Lifetime of the access token, in seconds.", "examples": [ 3600 ], "title": "Expires In", "type": "integer" }, "id_token": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "OpenID Connect ID token; omitted when none was issued.", "examples": [ "example-id-token" ], "title": "Id Token", "x-sensitive": true }, "refresh_token": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Refresh token for obtaining new tokens; omitted when none was issued.", "examples": [ "rt_example-refresh-token" ], "title": "Refresh Token", "x-sensitive": true }, "scope": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Space-delimited effective scopes of the minted access token (RFC 6749 §3.3), computed the way the platform's resolvers enforce them (live scope grants ∩ client ceiling ∩ consent-grant scopes for agent tokens), so the granted set may be narrower than requested and clients must not assume they got what they asked for. Present on every response whose token carries at least one scope; OMITTED (never the ABNF-invalid empty string) only when the effective set is empty — reachable solely on legs where the client requested no scopes at the token endpoint (the token request carries no scope parameter, and consent fails closed on an empty intersection).", "examples": [ "apis:read capabilities:execute" ], "title": "Scope" }, "token_type": { "default": "bearer", "description": "Token type; always `bearer`.", "examples": [ "bearer" ], "title": "Token Type", "type": "string" } }, "required": [ "access_token", "expires_in" ], "title": "TokenResponse", "type": "object" }, "TopOperation": { "description": "Aggregated execution counts for a single operation.", "examples": [ { "api_name": "stripe", "api_vendor": "stripe.com", "failed": 12, "operation_id": "listCharges", "total": 342 } ], "properties": { "api_name": { "description": "Name of the API the operation belongs to.", "examples": [ "stripe" ], "title": "Api Name", "type": "string" }, "api_vendor": { "description": "Vendor of the API the operation belongs to.", "examples": [ "stripe.com" ], "title": "Api Vendor", "type": "string" }, "failed": { "description": "Number of those executions that failed.", "examples": [ 12 ], "title": "Failed", "type": "integer" }, "operation_id": { "description": "Identifier of the operation.", "examples": [ "listCharges" ], "title": "Operation Id", "type": "string" }, "total": { "description": "Number of executions of the operation in the window.", "examples": [ 342 ], "title": "Total", "type": "integer" } }, "required": [ "api_vendor", "api_name", "operation_id", "total", "failed" ], "title": "TopOperation", "type": "object" }, "UsageBucket": { "description": "Execution counts for a single time bucket.", "examples": [ { "avg_ms": 231.4, "failed": 2, "success": 40, "total": 42, "ts": 1767225600 } ], "properties": { "avg_ms": { "description": "Mean execution duration in the bucket, in milliseconds.", "examples": [ 231.4 ], "title": "Avg Ms", "type": "number" }, "failed": { "description": "Number of those executions that failed.", "examples": [ 2 ], "title": "Failed", "type": "integer" }, "success": { "description": "Number of those executions that completed.", "examples": [ 40 ], "title": "Success", "type": "integer" }, "total": { "description": "Number of executions started in the bucket.", "examples": [ 42 ], "title": "Total", "type": "integer" }, "ts": { "description": "Start of the bucket, in Unix epoch seconds.", "examples": [ 1767225600 ], "title": "Ts", "type": "integer" } }, "required": [ "ts", "total", "success", "failed", "avg_ms" ], "title": "UsageBucket", "type": "object" }, "UsageResponse": { "description": "Full usage statistics response.", "examples": [ { "bucket_seconds": 86400, "buckets": [ { "avg_ms": 231.4, "failed": 2, "success": 40, "total": 42, "ts": 1767225600 } ], "group_by": "api", "since": 1767225600, "stats": { "active_now": 0, "avg_ms": 245.6, "failed": 80, "p50_ms": 180.0, "p95_ms": 720.0, "pending": 0, "success": 1200, "total": 1280 }, "top": [ { "avg_ms": 212.8, "failed": 12, "key": "stripe.com/stripe", "label": "Stripe", "success": 330, "total": 342, "trend": [ 40, 52, 47, 61, 58, 84 ] } ], "until": 1769903999 } ], "properties": { "bucket_seconds": { "description": "Width of each entry in `buckets`, in seconds; chosen from the window length.", "examples": [ 86400 ], "title": "Bucket Seconds", "type": "integer" }, "buckets": { "description": "Execution counts per time bucket, oldest first; empty buckets are omitted.", "examples": [ [ { "avg_ms": 231.4, "failed": 2, "success": 40, "total": 42, "ts": 1767225600 } ] ], "items": { "$ref": "#/components/schemas/UsageBucket" }, "title": "Buckets", "type": "array" }, "group_by": { "description": "Dimension the `top` rows are grouped by.", "examples": [ "api" ], "title": "Group By", "type": "string" }, "since": { "description": "Start of the window, in Unix epoch seconds (inclusive).", "examples": [ 1767225600 ], "title": "Since", "type": "integer" }, "stats": { "$ref": "#/components/schemas/UsageStatsBlock", "examples": [ { "active_now": 0, "avg_ms": 245.6, "failed": 80, "p50_ms": 180.0, "p95_ms": 720.0, "pending": 0, "success": 1200, "total": 1280 } ] }, "top": { "description": "The entities with the most executions in the window, most first.", "examples": [ [ { "avg_ms": 212.8, "failed": 12, "key": "stripe.com/stripe", "label": "Stripe", "success": 330, "total": 342, "trend": [ 40, 52, 47, 61, 58, 84 ] } ] ], "items": { "$ref": "#/components/schemas/UsageTopRow" }, "title": "Top", "type": "array" }, "until": { "description": "End of the window, in Unix epoch seconds (exclusive).", "examples": [ 1769903999 ], "title": "Until", "type": "integer" } }, "required": [ "since", "until", "bucket_seconds", "group_by", "stats", "buckets", "top" ], "title": "UsageResponse", "type": "object" }, "UsageStatsBlock": { "description": "Overall usage statistics for a time window.", "examples": [ { "active_now": 0, "avg_ms": 245.6, "failed": 80, "p50_ms": 180.0, "p95_ms": 720.0, "pending": 0, "success": 1200, "total": 1280 } ], "properties": { "active_now": { "description": "Reserved count of in-flight executions; currently always 0.", "examples": [ 0 ], "title": "Active Now", "type": "integer" }, "avg_ms": { "description": "Mean execution duration in milliseconds; 0 when there were no executions.", "examples": [ 245.6 ], "title": "Avg Ms", "type": "number" }, "failed": { "description": "Number of those executions that failed.", "examples": [ 80 ], "title": "Failed", "type": "integer" }, "p50_ms": { "anyOf": [ { "type": "number" }, { "type": "null" } ], "description": "Median execution duration in milliseconds; null when not available.", "examples": [ 180.0 ], "title": "P50 Ms" }, "p95_ms": { "anyOf": [ { "type": "number" }, { "type": "null" } ], "description": "95th-percentile execution duration in milliseconds; null when not available.", "examples": [ 720.0 ], "title": "P95 Ms" }, "pending": { "description": "Reserved count of pending executions; currently always 0.", "examples": [ 0 ], "title": "Pending", "type": "integer" }, "success": { "description": "Number of those executions that completed.", "examples": [ 1200 ], "title": "Success", "type": "integer" }, "total": { "description": "Number of executions started in the window.", "examples": [ 1280 ], "title": "Total", "type": "integer" } }, "required": [ "total", "success", "failed", "pending", "avg_ms", "p50_ms", "p95_ms", "active_now" ], "title": "UsageStatsBlock", "type": "object" }, "UsageTopRow": { "description": "Top entity row with sparkline trend.", "examples": [ { "avg_ms": 212.8, "failed": 12, "key": "stripe.com/stripe", "label": "Stripe", "success": 330, "total": 342, "trend": [ 40, 52, 47, 61, 58, 84 ] } ], "properties": { "avg_ms": { "description": "Mean execution duration for this entity, in milliseconds.", "examples": [ 212.8 ], "title": "Avg Ms", "type": "number" }, "failed": { "description": "Number of those executions that failed.", "examples": [ 12 ], "title": "Failed", "type": "integer" }, "key": { "description": "Grouping key for the row: `vendor/name` for `api`, the toolkit or credential ID, or `actor_type/actor_id` for `agent`; `unknown` when the value is missing.", "examples": [ "stripe.com/stripe" ], "title": "Key", "type": "string" }, "label": { "description": "Display label for the row.", "examples": [ "Stripe" ], "title": "Label", "type": "string" }, "success": { "description": "Number of those executions that completed.", "examples": [ 330 ], "title": "Success", "type": "integer" }, "total": { "description": "Number of executions for this entity in the window.", "examples": [ 342 ], "title": "Total", "type": "integer" }, "trend": { "description": "Execution counts for this entity across equal segments of the window, oldest first.", "examples": [ [ 40, 52, 47, 61, 58, 84 ] ], "items": { "type": "integer" }, "title": "Trend", "type": "array" } }, "required": [ "key", "label", "total", "success", "failed", "avg_ms", "trend" ], "title": "UsageTopRow", "type": "object" }, "UserCreateRequest": { "description": "Request body for creating a new user.", "examples": [ { "email": "ada@example.com", "first_name": "Ada", "last_name": "Lovelace", "permissions": [ "users:read", "agents:read" ] } ], "properties": { "email": { "description": "Email address of the new user; must be unique.", "examples": [ "ada@example.com" ], "maxLength": 320, "minLength": 1, "title": "Email", "type": "string" }, "first_name": { "description": "First name of the new user.", "examples": [ "Ada" ], "maxLength": 255, "minLength": 1, "title": "First Name", "type": "string" }, "last_name": { "description": "Last name of the new user.", "examples": [ "Lovelace" ], "maxLength": 255, "minLength": 1, "title": "Last Name", "type": "string" }, "permissions": { "default": [], "description": "Permissions to assign to the new user; the caller may only grant permissions they hold. Defaults to none.", "examples": [ [ "users:read", "agents:read" ] ], "items": { "type": "string" }, "title": "Permissions", "type": "array" } }, "required": [ "email", "first_name", "last_name" ], "title": "UserCreateRequest", "type": "object" }, "UserCreatedResponse": { "description": "Response after user creation including invite token.", "examples": [ { "invite_expires_at": "2026-01-22T09:30:00Z", "invite_token": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk", "user": { "active": true, "auth_provider": "external", "created_at": "2026-01-15T09:30:00Z", "email": "ada@example.com", "external_subject_id": "auth0|6568b3984d1c238dbe7e2e29", "first_name": "Ada", "id": "usr_6968b3987ee4c3ec0b4ee3b9", "invite_state": "accepted", "last_name": "Lovelace", "must_change_password": false, "name": "Ada Lovelace", "permissions": { "assigned": [ "users:write", "agents:read" ], "effective": [ { "implied_by": "users:write", "name": "users:read" } ] }, "updated_at": "2026-01-20T14:05:00Z" } } ], "properties": { "invite_expires_at": { "description": "When the invite token expires (RFC 3339).", "examples": [ "2026-01-22T09:30:00Z" ], "format": "date-time", "title": "Invite Expires At", "type": "string" }, "invite_token": { "description": "One-time invite token the user redeems to set a password.", "examples": [ "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" ], "title": "Invite Token", "type": "string", "x-sensitive": true }, "user": { "$ref": "#/components/schemas/UserResponse", "examples": [ { "active": true, "auth_provider": "external", "created_at": "2026-01-15T09:30:00Z", "email": "ada@example.com", "external_subject_id": "auth0|6568b3984d1c238dbe7e2e29", "first_name": "Ada", "id": "usr_6968b3987ee4c3ec0b4ee3b9", "invite_state": "accepted", "last_name": "Lovelace", "must_change_password": false, "name": "Ada Lovelace", "permissions": { "assigned": [ "users:write", "agents:read" ], "effective": [ { "implied_by": "users:write", "name": "users:read" } ] }, "updated_at": "2026-01-20T14:05:00Z" } ] } }, "required": [ "user", "invite_token", "invite_expires_at" ], "title": "UserCreatedResponse", "type": "object" }, "UserListResponse": { "description": "Paginated list of users.", "examples": [ { "data": [ { "active": true, "auth_provider": "external", "created_at": "2026-01-15T09:30:00Z", "email": "ada@example.com", "external_subject_id": "auth0|6568b3984d1c238dbe7e2e29", "first_name": "Ada", "id": "usr_6968b3987ee4c3ec0b4ee3b9", "invite_state": "accepted", "last_name": "Lovelace", "must_change_password": false, "name": "Ada Lovelace", "permissions": { "assigned": [ "users:write", "agents:read" ], "effective": [ { "implied_by": "users:write", "name": "users:read" } ] }, "updated_at": "2026-01-20T14:05:00Z" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } ], "properties": { "data": { "description": "The page of users.", "examples": [ [ { "active": true, "auth_provider": "external", "created_at": "2026-01-15T09:30:00Z", "email": "ada@example.com", "external_subject_id": "auth0|6568b3984d1c238dbe7e2e29", "first_name": "Ada", "id": "usr_6968b3987ee4c3ec0b4ee3b9", "invite_state": "accepted", "last_name": "Lovelace", "must_change_password": false, "name": "Ada Lovelace", "permissions": { "assigned": [ "users:write", "agents:read" ], "effective": [ { "implied_by": "users:write", "name": "users:read" } ] }, "updated_at": "2026-01-20T14:05:00Z" } ] ], "items": { "$ref": "#/components/schemas/UserResponse" }, "title": "Data", "type": "array" }, "has_more": { "description": "Whether more results exist after this page.", "examples": [ true ], "title": "Has More", "type": "boolean" }, "next_cursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Cursor for the next page; null when there are no more results.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Next Cursor" } }, "required": [ "data", "has_more" ], "title": "UserListResponse", "type": "object" }, "UserResponse": { "description": "User representation in API responses.", "examples": [ { "active": true, "auth_provider": "external", "created_at": "2026-01-15T09:30:00Z", "email": "ada@example.com", "external_subject_id": "auth0|6568b3984d1c238dbe7e2e29", "first_name": "Ada", "id": "usr_6968b3987ee4c3ec0b4ee3b9", "invite_state": "accepted", "last_name": "Lovelace", "must_change_password": false, "name": "Ada Lovelace", "permissions": { "assigned": [ "users:write", "agents:read" ], "effective": [ { "implied_by": "users:write", "name": "users:read" } ] }, "updated_at": "2026-01-20T14:05:00Z" } ], "properties": { "active": { "description": "Whether the user account is enabled.", "examples": [ true ], "title": "Active", "type": "boolean" }, "auth_provider": { "description": "How the user authenticates: `local` (password) or `external`.", "examples": [ "external" ], "title": "Auth Provider", "type": "string" }, "created_at": { "description": "When the user was created (RFC 3339).", "examples": [ "2026-01-15T09:30:00Z" ], "format": "date-time", "title": "Created At", "type": "string" }, "email": { "description": "Email address of the user.", "examples": [ "ada@example.com" ], "title": "Email", "type": "string" }, "external_subject_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Subject ID from the external identity provider; null for local users.", "examples": [ "auth0|6568b3984d1c238dbe7e2e29" ], "title": "External Subject Id" }, "first_name": { "description": "First name of the user.", "examples": [ "Ada" ], "title": "First Name", "type": "string" }, "id": { "description": "Unique ID of the user.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "Id", "type": "string" }, "invite_state": { "description": "Invitation state: `pending`, `redeemed`, `accepted` or `expired`. `expired` means a pending invite whose token has lapsed and should be reissued.", "examples": [ "accepted" ], "title": "Invite State", "type": "string" }, "last_name": { "description": "Last name of the user.", "examples": [ "Lovelace" ], "title": "Last Name", "type": "string" }, "must_change_password": { "description": "Whether the user must change their password at next use.", "examples": [ false ], "title": "Must Change Password", "type": "boolean" }, "name": { "description": "Full display name: first name and last name.", "examples": [ "Ada Lovelace" ], "title": "Name", "type": "string" }, "permissions": { "$ref": "#/components/schemas/Permissions", "examples": [ { "assigned": [ "users:write", "agents:read" ], "effective": [ { "implied_by": "users:write", "name": "users:read" } ] } ] }, "updated_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "When the user was last updated (RFC 3339); null if never updated.", "examples": [ "2026-01-20T14:05:00Z" ], "title": "Updated At" } }, "required": [ "id", "email", "first_name", "last_name", "name", "active", "auth_provider", "invite_state", "must_change_password", "permissions", "created_at" ], "title": "UserResponse", "type": "object" }, "UserUpdateRequest": { "description": "Request body for updating a user.", "examples": [ { "email": "ada.lovelace@example.com", "first_name": "Ada", "last_name": "Lovelace" } ], "properties": { "email": { "anyOf": [ { "maxLength": 320, "minLength": 1, "type": "string" }, { "type": "null" } ], "description": "New email address; must be unique. Null means no change.", "examples": [ "ada.lovelace@example.com" ], "title": "Email" }, "first_name": { "anyOf": [ { "maxLength": 255, "minLength": 1, "type": "string" }, { "type": "null" } ], "description": "New first name; null means no change.", "examples": [ "Ada" ], "title": "First Name" }, "last_name": { "anyOf": [ { "maxLength": 255, "minLength": 1, "type": "string" }, { "type": "null" } ], "description": "New last name; null means no change.", "examples": [ "Lovelace" ], "title": "Last Name" } }, "title": "UserUpdateRequest", "type": "object" }, "VendorListResponse": { "description": "The vendors the caller can connect a credential for.", "examples": [ { "data": [ { "catalog_api_id": "github.com/api.github.com", "display_name": "GitHub", "entry_id": "oar_6968b39821e5f89a6975f501", "flow_kinds": [ "authorization_code" ], "key": "github", "name": "MyOrg GitHub", "registration_id": "oar_6968b39821e5f89a6975f501", "source": "db", "vendor": "github.com/api.github.com" } ] } ], "properties": { "data": { "description": "The connectable vendors.", "examples": [ [ { "catalog_api_id": "github.com/api.github.com", "display_name": "GitHub", "entry_id": "oar_6968b39821e5f89a6975f501", "flow_kinds": [ "authorization_code" ], "key": "github", "name": "MyOrg GitHub", "registration_id": "oar_6968b39821e5f89a6975f501", "source": "db", "vendor": "github.com/api.github.com" } ] ], "items": { "$ref": "#/components/schemas/VendorSummaryResponse" }, "title": "Data", "type": "array" } }, "required": [ "data" ], "title": "VendorListResponse", "type": "object" }, "VendorSummaryResponse": { "description": "A vendor, or one admin registration for it, that the caller can connect to.", "examples": [ { "catalog_api_id": "github.com/api.github.com", "display_name": "GitHub", "entry_id": "oar_6968b39821e5f89a6975f501", "flow_kinds": [ "authorization_code" ], "key": "github", "name": "MyOrg GitHub", "registration_id": "oar_6968b39821e5f89a6975f501", "source": "db", "vendor": "github.com/api.github.com" } ], "properties": { "catalog_api_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Catalog API (`/`) the registration signs in to; null for platform-shipped vendors.", "examples": [ "github.com/api.github.com" ], "title": "Catalog Api Id" }, "display_name": { "description": "Vendor's display name (e.g. 'Gmail').", "examples": [ "GitHub" ], "title": "Display Name", "type": "string" }, "entry_id": { "description": "Stable per-row key: the registration ID for admin registrations, else the vendor key.", "examples": [ "oar_6968b39821e5f89a6975f501" ], "title": "Entry Id", "type": "string" }, "flow_kinds": { "description": "OAuth flow kinds this row supports (`authorization_code`, `device_authorization`).", "examples": [ [ "authorization_code" ] ], "items": { "type": "string" }, "title": "Flow Kinds", "type": "array" }, "key": { "description": "Vendor registry key shared by every registration for the vendor.", "examples": [ "github" ], "title": "Key", "type": "string" }, "name": { "description": "Label for this row: the registration name for admin registrations, else the display name.", "examples": [ "MyOrg GitHub" ], "title": "Name", "type": "string" }, "registration_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ID of the admin OAuth app registration behind this row; null for platform-shipped vendors.", "examples": [ "oar_6968b39821e5f89a6975f501" ], "title": "Registration Id" }, "source": { "description": "Where the row came from: `db` for an admin registration, `config` for a platform-shipped vendor.", "enum": [ "db", "config" ], "examples": [ "db" ], "title": "Source", "type": "string" }, "vendor": { "description": "Fully-qualified vendor ID (`/`) when known; otherwise the vendor key.", "examples": [ "github.com/api.github.com" ], "title": "Vendor", "type": "string" } }, "required": [ "entry_id", "key", "vendor", "display_name", "name", "source", "flow_kinds" ], "title": "VendorSummaryResponse", "type": "object" }, "VersionResponse": { "description": "The running app version and the latest release known to this backend.", "examples": [ { "current": "0.42.2", "latest": "0.43.0", "update_available": true } ], "properties": { "current": { "description": "The version of jentic-one currently running on this backend.", "examples": [ "0.42.2" ], "title": "Current", "type": "string" }, "latest": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "The latest published release of jentic-one, without a leading 'v'. Null when the backend can't determine it (update check disabled, air-gapped, a remote backend, or GitHub was unreachable).", "examples": [ "0.43.0" ], "title": "Latest" }, "update_available": { "description": "True when `latest` is a newer release than `current`. Matches the verdict `jenticctl update` would print.", "examples": [ true ], "title": "Update Available", "type": "boolean" } }, "required": [ "current", "update_available" ], "title": "VersionResponse", "type": "object" } }, "securitySchemes": { "BearerAuth": { "description": "Opaque bearer access token (prefixed `at_`), sent as `Authorization: Bearer `. It is **not** a JWT — it is a random string validated server-side by lookup, so it cannot be decoded by the client.\n\nObtain one from `POST /oauth/token` using the grant for your actor type:\n- **Agents** — `grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer` with a JWT assertion signed by the key registered via `POST /register` (the JWT is the *assertion*, not the resulting access token).\n- **Users** — `grant_type=authorization_code` (interactive) or `grant_type=password`; refresh either with `grant_type=refresh_token`.\n\nPer-endpoint permission and actor-type requirements are not modelled in this document (OpenAPI cannot faithfully express the OR-of-permissions / `org:admin` bypass / service-layer enforcement); see `GET /reference/endpoints.json` for the authoritative authorization reference.", "scheme": "bearer", "type": "http" }, "OAuth2": { "description": "OAuth 2.0 authorization code flow with PKCE (`S256` only), run by this deployment's authorization server. The resulting access token is the same opaque bearer token `BearerAuth` describes, sent as `Authorization: Bearer `.\n\nScopes are permission names, plus the OpenID Connect identity scopes. A request for scopes beyond the client's allowed scopes is rejected with `invalid_scope`, and a token is never enforced beyond its client's allowed scopes or the consent grant. Agents normally authenticate with the JWT-bearer grant instead — see `BearerAuth`.", "flows": { "authorizationCode": { "authorizationUrl": "/authorize", "refreshUrl": "/oauth/token", "scopes": { "agents:read": "Read agent configuration and status.", "agents:write": "Create, update, and delete agents.", "apis:read": "Read API definitions and metadata.", "apis:write": "Import, update, and delete API definitions and their revisions.", "audit:read": "Read audit log entries.", "capabilities:execute": "Execute capabilities via the broker.", "capabilities:read": "Read capability metadata.", "catalog:import": "Import an API from the public catalog into the local registry.", "config:read": "Read runtime platform configuration.", "config:write": "Create and update runtime platform configuration.", "credentials:connect": "Start and poll an integration connect session (agent-driven SSO). Cannot read tokens or manage other credentials.", "credentials:read": "Read credential metadata.", "credentials:write": "Create, update, and delete credentials.", "email": "Include the user's email address in the ID token.", "events:read": "Read platform events.", "events:write": "Manage platform events.", "executions:read": "Read execution records.", "jobs:read": "Read job status and results.", "jobs:write": "Cancel and manage async jobs.", "oauth-clients:read": "Read OAuth client registrations.", "oauth-clients:write": "Create, update, disable, and rotate secrets of OAuth clients.", "openid": "Issue an OpenID Connect ID token identifying the user.", "org:admin": "Full organisation administrator access.", "overlays:confirm": "Confirm a pending overlay, rewriting the API's served spec (operator action; not granted to agents by default).", "owner:agents:read": "Read agents owned by the agent's creator.", "owner:credentials:read": "Read credentials owned by the agent's creator.", "owner:resources:read": "Read resources owned by the agent's creator (umbrella).", "profile": "Include the user's display name in the ID token.", "users:read": "Read user profiles and permissions.", "users:write": "Create, update, and disable users." }, "tokenUrl": "/oauth/token" } }, "type": "oauth2" } } }, "info": { "contact": { "email": "support@jentic.com", "name": "Jentic Platform Team", "url": "https://jentic.com/" }, "description": "## Overview ##\nThe **Jentic Control Plane API** is the unified HTTP surface of the\nJentic platform's control plane — every administrative and\nmetadata-facing endpoint outside the Broker data plane.\n\nThe control plane is the administrative counterpart to the\n[Broker](../broker/swagger) data plane: where the Broker executes\nupstream API calls on behalf of agents, the control plane is where\nhumans, operators, and agents configure *what* the Broker is\nallowed to do, *for whom*, *with which credentials*, *against\nwhich registered APIs*, and *with what telemetry retained*.\n\n## Components ##\nHigh-level components for the control plane API.\n- **[Core / Access](#tag/Credentials)** — credentials, direct\n agent↔credential bindings, and PBAC grants and runtime params. Owns *who can\n call what, with which secret*.\n- **[Registry](#tag/APIs)** — registered APIs, immutable\n revisions, operations, search, lookup. Owns *what APIs are\n registered for this deployment and what they look like at any\n given revision*.\n- **[Admin / Audit](#tag/Users)** — users, permissions,\n execution telemetry, async-job tracker, and dashboard event\n stream. Owns *who can sign in with what permissions* together\n with *what actually happened* — the human roster, the\n append-only records of brokered executions, the unified\n `Job` resource that both Registry imports and Broker\n async-execution calls feed into, and a curated `/events`\n surface for dashboards and operators.\n\n## Authentication ##\n\nToday the platform ships a local username + password identity\nprovider for human users, alongside agent identity (Dynamic Client\nRegistration + RFC 7523 JWT-bearer assertions) — every authenticated operation expects\n`Authorization: Bearer ` (`BearerAuth`, an opaque `at_`\ntoken) except `GET /health`, `POST /auth/login`,\n`POST /users:create-admin`, and `POST /users:redeem-invite`.\nHuman tokens are issued by `POST /auth/login` with a fixed 1-hour\nTTL and can be re-minted before expiry via `POST /auth/refresh`\n(sliding session, bounded by an absolute window —\n`admin.auth.session_ttl_seconds`, 12 hours by default); agents\nobtain tokens from `POST /oauth/token` (see\n`BearerAuth`). The `permissions` claim on a token is a snapshot at\nissue time; permission changes take effect at the next re-issue —\nthe next refresh or re-login (≤ 1 hour with the default TTL).\n\nThe platform ships **no default credentials**. On a fresh\ninstall the users table is empty, so `GET /health` returns\n`setup_required: true` with `next_step: create_admin`. The\noperator creates the first administrator with `POST\n/users:create-admin {email, password}` — a one-time,\nunauthenticated, self-closing endpoint: it succeeds only while\nthe users table is empty and returns `410 setup_already_complete`\nonce any user exists (a single-row setup sentinel is the\nconcurrency backstop, so two racing callers — even with different\nemails — cannot both bootstrap). It grants `org:admin`, sets the operator's chosen\npassword (so `must_change_password` is **false** — no forced\nrotation), and returns a ready-to-use `LoginResponse`\n(auto-login). After the first user exists `setup_required` flips\nto `false`. See the **Users** tag for the full onboarding\nwalkthrough.\n\nExternal SSO providers (Okta, AWS Cognito, Auth0, Azure AD)\nplug in via the `User.auth_provider: external` hook plus an\n`external_subject_id` mapping; no concrete provider ships in\nthis revision. Agent identity (separate from human users) uses\nDynamic Client Registration (`POST /register`) with the agent's\nJWKS, then RFC 7523 JWT-bearer assertions exchanged at\n`POST /oauth/token` for an opaque access token.\n\n## Cross-cutting conventions\n\n- Every API reference uses the loose\n `APIReference(vendor, name, version)` data structure. There is no\n foreign key between Core, Registry, and Admin / Audit — the\n tuple is the only join.\n- **Error shape.** Every error response is RFC 9457 Problem\n Details (`application/problem+json`) using the shared\n `ProblemDetails` schema from\n [jentic/api-problem-details](https://github.com/jentic/api-problem-details).\n Field-level validation failures (`422`) populate `errors[]`;\n transport-level conditions reuse the same shape with status-\n and `type`-specific payloads.\n- **JSON casing.** Field names in request and response bodies are\n `snake_case` throughout, including discriminator values\n (`type: api_key`, `type: bearer_token`, …). The one historical\n camelCase exception is the OpenAPI keyword `apiKey` itself when\n it appears in re-exported `securitySchemes.type` values; that's\n an OpenAPI artefact, not platform style.\n- **Pagination.** List endpoints are cursor-paginated with opaque\n `next_cursor` round-trips. `has_more=false` means done. List\n envelopes are intentionally slim — `{data, has_more,\n next_cursor}` — and **do not** carry HAL-style `_links` (no\n `self`, `next`, or `prev`); cursors are forward-only and\n `next_cursor` already encodes the next page. Individual resource\n responses still use `_links` where it carries non-trivial\n information (e.g. `Job._links.result`, `AsyncQueuedResponse._links.self`,\n `Event._links`).\n- **Authentication.** All operations require `Authorization:\n Bearer ` — an opaque access token (prefixed `at_`, not a\n JWT), obtained from `POST /oauth/token` (see `BearerAuth` for the\n per-actor grants) — except the unauthenticated\n `GET /health`, `POST /auth/login`, `POST /users:create-admin`,\n and `POST /users:redeem-invite`. See the `Users` tag for the\n first-run setup and invite-redemption flows.\n- **Header namespace.** All Jentic-specific HTTP headers — request\n and response, broker and control-plane — live under the\n `Jentic-*` namespace **without** the legacy `X-` prefix\n (RFC 6648 deprecates `X-` for new protocols). `Jentic-*` is\n unambiguously a platform header; anything else on a brokered\n response belongs to the upstream API. Standard headers\n (`Authorization`, `Prefer`, `Idempotency-Key`, `Accept`,\n `traceparent`, `tracestate`) keep their RFC names.\n- **Append-only audit.** Admin / Audit records are never mutated\n after the fact; retention is enforced via purge policy, not\n edit.\n- **Trace correlation.** Every Broker call records a W3C\n `trace_id` on its `ExecutionRecord` and on any `Event` derived\n from it. To walk the executions you can see under one logical request, use\n `GET /executions?trace_id=…`.\n- **Event stream.** The dashboard / operator UI consumes the\n `/events` resource (paginated list + SSE stream). Some events\n are informational, some require action — see the `Events` tag.\n- **Revision pinning.** Every `Api` carries one `published`\n revision (`current_revision_id`) plus zero or more `draft` and\n `archived` siblings. The Broker's hot path resolves against\n `current_revision_id` by default; agents can target a specific\n `draft` revision per call via the Broker's `Jentic-Revision`\n header. Control-plane reads (`Search`, `Inspect`,\n `Lookup`) accept matching `revision_id` / `revision_pins`\n parameters so dashboards can preview an unpromoted revision\n before flipping `:promote`.\n- **ID prefixes.** Resource identifiers use a stable short prefix.\n Treat the prefix as part of the ID — never strip it. The\n complete table:\n\n | Prefix | Resource | Notes |\n |---|---|---|\n | `tk_` | Toolkit ID | Retired (theme-5): the toolkit surface and its tables are gone (Phase 6b). Ids still appear in historical records (execution attribution, audit). |\n | `ck_` | Toolkit-key record | Retired (theme-5): key records are gone with the toolkit tables (Phase 6b). Ids survive only in audit history. |\n | `cred_` | Credential ID | |\n | `exec_` | Execution record | Returned in the `Jentic-Execution-Id` response header on every brokered call. |\n | `job_` | Async job | UUIDs also accepted on inputs for backward compatibility. |\n | `evt_` | Event | ULID-shaped. |\n | `op_` | Registered operation | |\n | `rev_` | API revision | ULID-shaped. |\n | `usr_` | User | Org member. Resolves via `GET /users/{user_id}`. Used in `decided_by` and similar audit references. |\n | `inv_` | Invite token | One-time token issued at user creation. Plaintext value shown **once** at issue / re-issue; `:redeem-invite` consumes it. |\n | `areq_` | Access request (retired) | Retired (theme 7): the access-request flow is gone. Ids still appear in stored audit/event records. |\n | `note_` | Note | ULID-shaped. Free-form annotation attached to a registry resource — see the `Notes` tag. |\n | `ovr_` | Overlay | ULID-shaped. OpenAPI Overlay 1.0 document attached to an `Api` aggregate — see the `Overlays` tag. |\n | `jntc_live_` | Plaintext toolkit API key value (retired) | Never issued anymore. A value migrated before Phase 6b keeps authenticating — as its successor agent — until the deprecation window closes (no earlier than 2026-12-01); rotate holders to the successor agent's `jak_` key. |\n | `sak_` | Plaintext service-account API key value (retired) | Retired in 0.41: refused with `401` (the detail names the retirement). Each service account was migrated to an agent; mint a `jak_` key for that agent. |\n\n Surfaces still being designed (agent identity, OAuth brokers)\n will add their own prefixes when they land.\n", "license": { "identifier": "Apache-2.0", "name": "Apache-2.0" }, "summary": "HTTP surface of the Jentic platform's control plane — Core / Access (credentials, direct agent bindings), Registry (registered APIs, operations, search), and Admin / Audit (execution telemetry, async jobs).", "title": "Jentic Control Plane API", "version": "0.43.0" }, "openapi": "3.1.0", "paths": { "/actors": { "description": "`GET`: List users and agents.", "get": { "description": "List users and agents with the minimal fields needed to label them.\n\nEach entry gives `id`, `actor_type` (`user` or `agent`), display `name`\nand `active`. Requires `users:read`. Results are scoped to the caller:\n`org:admin` lists everyone; anyone else lists only themselves and the\nagents they may see (their own, or with `owner:agents:read` their owner's\nagents). Cursor-paginated (`cursor`, `limit`). To label specific ids you\nalready hold, use `GET /actors/lookup`.", "operationId": "listActors", "parameters": [ { "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": { "example": { "summary": "Opaque cursor from a previous page", "value": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } }, "in": "query", "name": "cursor", "required": false, "schema": { "anyOf": [ { "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "type": "string" }, { "type": "null" } ], "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Cursor" } }, { "description": "Maximum number of actors to return (1-5000, default 1000).", "examples": { "example": { "summary": "Example query value for `limit`", "value": 25 } }, "in": "query", "name": "limit", "required": false, "schema": { "default": 1000, "description": "Maximum number of actors to return (1-5000, default 1000).", "examples": [ 25 ], "maximum": 5000, "minimum": 1, "title": "Limit", "type": "integer" } } ], "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "active": true, "actor_type": "user", "created_at": "2026-01-15T09:30:00Z", "id": "usr_6968b3987ee4c3ec0b4ee3b9", "name": "Ada Lovelace" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" }, "schema": { "$ref": "#/components/schemas/ActorListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List users and agents", "tags": [ "Actors" ] }, "summary": "List users and agents" }, "/actors/lookup": { "description": "`GET`: Resolve actor names by id.", "get": { "description": "Resolve user and agent ids to display names.\n\nPass each id as a repeated `id` parameter. Returns `id`, `actor_type`,\n`name` and `active` for each id the caller may see. Any signed-in caller\nmay call it, so a UI can label the owners, approvers and actors it\nalready holds by id without `users:read`.\n\nUsers resolve for every caller. Agents resolve only when visible to the\ncaller: itself, its own agents, its owner's agents with\n`owner:agents:read`, or every agent for `org:admin`. Ids that match no\nvisible actor are silently left out rather than reported as errors.\nListing the whole directory needs `users:read` on `GET /actors`.", "operationId": "lookupActors", "parameters": [ { "description": "Actor id to resolve; repeat the parameter for several ids (at most 100 per call, each at most 64 characters).", "examples": { "example": { "summary": "Example query value for `id`", "value": [ "agnt_6968b3984d1c238dbe7e2e29", "usr_6968b3987ee4c3ec0b4ee3b9" ] } }, "in": "query", "name": "id", "required": true, "schema": { "description": "Actor id to resolve; repeat the parameter for several ids (at most 100 per call, each at most 64 characters).", "examples": [ [ "agnt_6968b3984d1c238dbe7e2e29", "usr_6968b3987ee4c3ec0b4ee3b9" ] ], "items": { "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "maxLength": 64, "type": "string" }, "maxItems": 100, "minItems": 1, "title": "Id", "type": "array" } } ], "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "active": true, "actor_type": "user", "id": "usr_2abc", "name": "Ada Lovelace" } ] }, "schema": { "$ref": "#/components/schemas/ActorLookupResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Resolve actor names by id", "tags": [ "Actors" ] }, "summary": "Resolve actor names by id" }, "/admin/config/providers": { "description": "`GET`: List credential provider configs.", "get": { "description": "List all stored provider configs, with secret fields redacted.", "operationId": "listProviderConfigs", "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "config": { "client_id": "client_abc123", "client_secret": "***", "environment": "production", "kind": "pipedream", "project_id": "proj_abc123" }, "created_at": "2026-06-29T12:00:00Z", "name": "pipedream", "updated_at": "2026-06-29T12:00:00Z" } ] }, "schema": { "$ref": "#/components/schemas/ProviderConfigListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List credential provider configs", "tags": [ "Configuration" ] }, "summary": "List credential provider configs" }, "/admin/config/providers/{name}": { "description": "`PUT`: Set a credential provider config. `GET`: Get a credential provider config.", "get": { "description": "Get a stored provider config by name, with secret fields redacted.", "operationId": "getProviderConfig", "parameters": [ { "description": "Provider name, e.g. `pipedream`.", "examples": { "example": { "summary": "Credential provider name", "value": "pipedream" } }, "in": "path", "name": "name", "required": true, "schema": { "description": "Provider name, e.g. `pipedream`.", "examples": [ "pipedream" ], "title": "Name", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "config": { "client_id": "client_abc123", "client_secret": "***", "environment": "production", "kind": "pipedream", "project_id": "proj_abc123" }, "created_at": "2026-06-29T12:00:00Z", "name": "pipedream", "updated_at": "2026-06-29T12:00:00Z" }, "schema": { "$ref": "#/components/schemas/ProviderConfigResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get a credential provider config", "tags": [ "Configuration" ] }, "put": { "description": "Set (create or update) a credential provider config at runtime.\n\nThe payload is validated by provider name (e.g. ``pipedream``). Secret fields\nare encrypted at rest. A successful write rebuilds the in-process provider\nregistry so the change takes effect without a restart. The response redacts\nsecret fields.", "operationId": "setProviderConfig", "parameters": [ { "description": "Provider name, e.g. `pipedream`.", "examples": { "example": { "summary": "Credential provider name", "value": "pipedream" } }, "in": "path", "name": "name", "required": true, "schema": { "description": "Provider name, e.g. `pipedream`.", "examples": [ "pipedream" ], "title": "Name", "type": "string" } } ], "requestBody": { "content": { "application/json": { "example": { "config": { "client_id": "client_abc123", "client_secret": "", "environment": "production", "project_id": "proj_abc123" } }, "schema": { "$ref": "#/components/schemas/ProviderConfigSetRequest" } } }, "description": "Request body for setting a provider config.\n\nFields are provider-specific and validated server-side by provider name.\nFor ``pipedream`` the recognised fields are ``project_id``, ``client_id``,\n``client_secret`` (write-only), and optional ``environment``,\n``connect_base_url``, ``expiry_skew_seconds``.", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "config": { "client_id": "client_abc123", "client_secret": "***", "environment": "production", "kind": "pipedream", "project_id": "proj_abc123" }, "created_at": "2026-06-29T12:00:00Z", "name": "pipedream", "updated_at": "2026-06-29T12:00:00Z" }, "schema": { "$ref": "#/components/schemas/ProviderConfigResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Set a credential provider config", "tags": [ "Configuration" ] }, "summary": "Set a credential provider config; Get a credential provider config" }, "/admin/health": { "description": "`GET`: Health.", "get": { "description": "Return admin service health status.", "operationId": "health", "responses": { "200": { "content": { "application/json": { "example": { "next_step": "create_admin", "setup_required": true, "status": "ok", "surface": "admin" }, "schema": { "$ref": "#/components/schemas/HealthResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [], "summary": "Health", "tags": [ "System" ] }, "summary": "Health" }, "/admin/oauth-clients": { "description": "`POST`: Register OAuth client. `GET`: List OAuth clients.", "get": { "description": "List all registered OAuth clients, optionally filtered by approval status.", "operationId": "listOauthClients", "parameters": [ { "description": "Whether to include inactive (disabled, pending or denied) clients; defaults to false.", "examples": { "example": { "summary": "Example query value for `include_inactive`", "value": true } }, "in": "query", "name": "include_inactive", "required": false, "schema": { "default": false, "description": "Whether to include inactive (disabled, pending or denied) clients; defaults to false.", "examples": [ true ], "title": "Include Inactive", "type": "boolean" } }, { "description": "Filter by approval lifecycle state: pending, approved, or denied. Filtering on pending or denied implies include_inactive=true — those rows are always inactive until approved.", "examples": { "example": { "summary": "Example query value for `approval_status`", "value": "pending" } }, "in": "query", "name": "approval_status", "required": false, "schema": { "anyOf": [ { "examples": [ "pending" ], "type": "string" }, { "type": "null" } ], "description": "Filter by approval lifecycle state: pending, approved, or denied. Filtering on pending or denied implies include_inactive=true — those rows are always inactive until approved.", "examples": [ "pending" ], "title": "Approval Status" } } ], "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "active": true, "active_grant_count": 0, "allowed_scopes": [ "agents:read", "credentials:read" ], "approval_status": "approved", "client_id": "oc_abc123...", "consent_model": "user", "created_at": "2026-08-18T12:00:00Z", "created_by": "usr_abc123", "description": "My application production deployment", "id": "oac_2NxYz...", "name": "my-app-production", "redirect_uris": [ "https://app.example.com/auth/callback" ], "registration_source": "admin", "require_consent": true, "software_id": "com.example.my-app", "token_endpoint_auth_method": "client_secret_basic", "updated_at": "2026-08-18T12:00:00Z" } ] }, "schema": { "$ref": "#/components/schemas/OAuthClientListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List OAuth clients", "tags": [ "OAuth Clients" ] }, "post": { "description": "Register a new OAuth client for third-party application integration.\n\nThe generated ``client_id`` and ``client_secret`` are returned in the\nresponse. The secret is shown only once — store it securely.", "operationId": "createOauthClient", "requestBody": { "content": { "application/json": { "example": { "description": "My application production deployment", "name": "my-app-production", "redirect_uris": [ "https://app.example.com/auth/callback" ], "require_consent": true }, "schema": { "$ref": "#/components/schemas/OAuthClientCreateRequest" } } }, "description": "Request body for creating an OAuth client.", "required": true }, "responses": { "201": { "content": { "application/json": { "example": { "active": true, "active_grant_count": 0, "allowed_scopes": [ "agents:read", "credentials:read" ], "approval_status": "approved", "client_id": "oc_abc123...", "client_secret": "", "consent_model": "user", "created_at": "2026-08-18T12:00:00Z", "created_by": "usr_abc123", "description": "My application production deployment", "id": "oac_2NxYz...", "name": "my-app-production", "redirect_uris": [ "https://app.example.com/auth/callback" ], "registration_source": "admin", "require_consent": true, "software_id": "com.example.my-app", "token_endpoint_auth_method": "client_secret_basic", "updated_at": "2026-08-18T12:00:00Z" }, "schema": { "$ref": "#/components/schemas/OAuthClientCreateResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Register OAuth client", "tags": [ "OAuth Clients" ] }, "summary": "Register OAuth client; List OAuth clients" }, "/admin/oauth-clients/{id}": { "delete": { "description": "Disable an OAuth client — the reversible kill switch (sets active=false).\n\nDisabled clients can no longer initiate authorization flows and their\noutstanding tokens stop resolving. Re-enable by patching ``active: true``.\nThe row is kept; this is not a delete.", "operationId": "deactivateOauthClient", "parameters": [ { "description": "Record ID of the OAuth client (`oac_…`), not its public `client_id`.", "examples": { "example": { "summary": "OAuth client record ID", "value": "oac_6968b39840a935d9f7e2714b" } }, "in": "path", "name": "id", "required": true, "schema": { "description": "Record ID of the OAuth client (`oac_…`), not its public `client_id`.", "examples": [ "oac_6968b39840a935d9f7e2714b" ], "title": "Id", "type": "string" } } ], "responses": { "204": { "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Disable OAuth client", "tags": [ "OAuth Clients" ] }, "description": "`GET`: Get OAuth client. `PATCH`: Update OAuth client. `DELETE`: Disable OAuth client.", "get": { "description": "Get an OAuth client by its internal ID.", "operationId": "getOauthClient", "parameters": [ { "description": "Record ID of the OAuth client (`oac_…`), not its public `client_id`.", "examples": { "example": { "summary": "OAuth client record ID", "value": "oac_6968b39840a935d9f7e2714b" } }, "in": "path", "name": "id", "required": true, "schema": { "description": "Record ID of the OAuth client (`oac_…`), not its public `client_id`.", "examples": [ "oac_6968b39840a935d9f7e2714b" ], "title": "Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "active": true, "active_grant_count": 0, "allowed_scopes": [ "agents:read", "credentials:read" ], "approval_status": "approved", "client_id": "oc_abc123...", "consent_model": "user", "created_at": "2026-08-18T12:00:00Z", "created_by": "usr_abc123", "description": "My application production deployment", "id": "oac_2NxYz...", "name": "my-app-production", "redirect_uris": [ "https://app.example.com/auth/callback" ], "registration_source": "admin", "require_consent": true, "software_id": "com.example.my-app", "token_endpoint_auth_method": "client_secret_basic", "updated_at": "2026-08-18T12:00:00Z" }, "schema": { "$ref": "#/components/schemas/OAuthClientResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get OAuth client", "tags": [ "OAuth Clients" ] }, "patch": { "description": "Update an OAuth client's name, description, redirect_uris, or active status.", "operationId": "updateOauthClient", "parameters": [ { "description": "Record ID of the OAuth client (`oac_…`), not its public `client_id`.", "examples": { "example": { "summary": "OAuth client record ID", "value": "oac_6968b39840a935d9f7e2714b" } }, "in": "path", "name": "id", "required": true, "schema": { "description": "Record ID of the OAuth client (`oac_…`), not its public `client_id`.", "examples": [ "oac_6968b39840a935d9f7e2714b" ], "title": "Id", "type": "string" } } ], "requestBody": { "content": { "application/json": { "example": { "active": true, "allowed_scopes": [ "apis:read", "capabilities:execute" ], "description": "Billing assistant production deployment", "name": "billing-assistant-prod", "redirect_uris": [ "https://client.example.com/oauth/callback" ], "require_consent": true }, "schema": { "$ref": "#/components/schemas/OAuthClientUpdateRequest" } } }, "description": "Request body for updating an OAuth client.", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "active": true, "active_grant_count": 0, "allowed_scopes": [ "agents:read", "credentials:read" ], "approval_status": "approved", "client_id": "oc_abc123...", "consent_model": "user", "created_at": "2026-08-18T12:00:00Z", "created_by": "usr_abc123", "description": "My application production deployment", "id": "oac_2NxYz...", "name": "my-app-production", "redirect_uris": [ "https://app.example.com/auth/callback" ], "registration_source": "admin", "require_consent": true, "software_id": "com.example.my-app", "token_endpoint_auth_method": "client_secret_basic", "updated_at": "2026-08-18T12:00:00Z" }, "schema": { "$ref": "#/components/schemas/OAuthClientResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Update OAuth client", "tags": [ "OAuth Clients" ] }, "summary": "Get OAuth client; Update OAuth client; Disable OAuth client" }, "/admin/oauth-clients/{id}/rotate-secret": { "description": "`POST`: Rotate client secret.", "post": { "description": "Generate a new client secret. The previous secret is immediately invalidated.\n\nThe new secret is shown only once — store it securely.", "operationId": "rotateOauthClientSecret", "parameters": [ { "description": "Record ID of the OAuth client (`oac_…`), not its public `client_id`.", "examples": { "example": { "summary": "OAuth client record ID", "value": "oac_6968b39840a935d9f7e2714b" } }, "in": "path", "name": "id", "required": true, "schema": { "description": "Record ID of the OAuth client (`oac_…`), not its public `client_id`.", "examples": [ "oac_6968b39840a935d9f7e2714b" ], "title": "Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "client_secret": "example-client-secret" }, "schema": { "$ref": "#/components/schemas/OAuthClientRotateSecretResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Rotate client secret", "tags": [ "OAuth Clients" ] }, "summary": "Rotate client secret" }, "/admin/oauth-clients/{id}:approve": { "description": "`POST`: Approve OAuth client.", "post": { "description": "Approve an OAuth client — sets approval_status=approved and active=true.\n\nAlso re-approves a previously denied client (deny is reversible; rows are\nnever deleted, so the client's cached client_id becomes valid again).", "operationId": "approveOauthClient", "parameters": [ { "description": "Record ID of the OAuth client (`oac_…`), not its public `client_id`.", "examples": { "example": { "summary": "OAuth client record ID", "value": "oac_6968b39840a935d9f7e2714b" } }, "in": "path", "name": "id", "required": true, "schema": { "description": "Record ID of the OAuth client (`oac_…`), not its public `client_id`.", "examples": [ "oac_6968b39840a935d9f7e2714b" ], "title": "Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "active": true, "active_grant_count": 0, "allowed_scopes": [ "agents:read", "credentials:read" ], "approval_status": "approved", "client_id": "oc_abc123...", "consent_model": "user", "created_at": "2026-08-18T12:00:00Z", "created_by": "usr_abc123", "description": "My application production deployment", "id": "oac_2NxYz...", "name": "my-app-production", "redirect_uris": [ "https://app.example.com/auth/callback" ], "registration_source": "admin", "require_consent": true, "software_id": "com.example.my-app", "token_endpoint_auth_method": "client_secret_basic", "updated_at": "2026-08-18T12:00:00Z" }, "schema": { "$ref": "#/components/schemas/OAuthClientResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Approve OAuth client", "tags": [ "OAuth Clients" ] }, "summary": "Approve OAuth client" }, "/admin/oauth-clients/{id}:delete": { "description": "`POST`: Delete OAuth client.", "post": { "description": "Permanently delete an OAuth client. This cannot be undone.\n\nTerminal, unlike the reversible kill switch (``DELETE`` on this\nresource, which only sets ``active=false``): every active grant is\nrevoked, every token carrying the client's lineage is revoked, and the\nregistration row is removed — connected applications are fully\ndisconnected. The audit trail survives. A client that later re-registers\nvia dynamic client registration is a NEW registration and re-enters the\napproval queue as pending; it is never re-attached to the deleted one.", "operationId": "deleteOauthClient", "parameters": [ { "description": "Record ID of the OAuth client (`oac_…`), not its public `client_id`.", "examples": { "example": { "summary": "OAuth client record ID", "value": "oac_6968b39840a935d9f7e2714b" } }, "in": "path", "name": "id", "required": true, "schema": { "description": "Record ID of the OAuth client (`oac_…`), not its public `client_id`.", "examples": [ "oac_6968b39840a935d9f7e2714b" ], "title": "Id", "type": "string" } } ], "responses": { "204": { "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Delete OAuth client", "tags": [ "OAuth Clients" ] }, "summary": "Delete OAuth client" }, "/admin/oauth-clients/{id}:deny": { "description": "`POST`: Deny OAuth client.", "post": { "description": "Deny an OAuth client — sets approval_status=denied and active=false.\n\nThe row is retained so a later approve can reverse the decision.", "operationId": "denyOauthClient", "parameters": [ { "description": "Record ID of the OAuth client (`oac_…`), not its public `client_id`.", "examples": { "example": { "summary": "OAuth client record ID", "value": "oac_6968b39840a935d9f7e2714b" } }, "in": "path", "name": "id", "required": true, "schema": { "description": "Record ID of the OAuth client (`oac_…`), not its public `client_id`.", "examples": [ "oac_6968b39840a935d9f7e2714b" ], "title": "Id", "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "anyOf": [ { "$ref": "#/components/schemas/OAuthClientDenyRequest" }, { "type": "null" } ], "title": "Body" } } }, "description": "Request payload for the `denyOauthClient` operation." }, "responses": { "200": { "content": { "application/json": { "example": { "active": true, "active_grant_count": 0, "allowed_scopes": [ "agents:read", "credentials:read" ], "approval_status": "approved", "client_id": "oc_abc123...", "consent_model": "user", "created_at": "2026-08-18T12:00:00Z", "created_by": "usr_abc123", "description": "My application production deployment", "id": "oac_2NxYz...", "name": "my-app-production", "redirect_uris": [ "https://app.example.com/auth/callback" ], "registration_source": "admin", "require_consent": true, "software_id": "com.example.my-app", "token_endpoint_auth_method": "client_secret_basic", "updated_at": "2026-08-18T12:00:00Z" }, "schema": { "$ref": "#/components/schemas/OAuthClientResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Deny OAuth client", "tags": [ "OAuth Clients" ] }, "summary": "Deny OAuth client" }, "/admin/oauth-grants": { "description": "`GET`: List OAuth grants.", "get": { "description": "List consent→agent grants across all clients and agents.\n\nThe admin cross-view over the grant registry: filter by client, agent,\nconsenting user, or status. Each item carries the client's display name\nand redirect-URI origin plus the consenting ``user_id`` — after an agent\nownership transfer the grant stays with the original consenter, so this\ncolumn is how an admin spots stranded grants.\n\nScoped to the caller: org admins see every grant. Anyone else sees grants\nthey consented to and grants bound to agents they own.", "operationId": "listOauthGrants", "parameters": [ { "description": "Filter by the client's public client_id.", "examples": { "example": { "summary": "Public OAuth client_id", "value": "oc_Xk3vQ9mT2pLw8RzN5bYc1HdF7gJs4AeU" } }, "in": "query", "name": "client_id", "required": false, "schema": { "anyOf": [ { "examples": [ "oc_Xk3vQ9mT2pLw8RzN5bYc1HdF7gJs4AeU" ], "type": "string" }, { "type": "null" } ], "description": "Filter by the client's public client_id.", "examples": [ "oc_Xk3vQ9mT2pLw8RzN5bYc1HdF7gJs4AeU" ], "title": "Client Id" } }, { "description": "Filter by bound agent.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "query", "name": "agent_id", "required": false, "schema": { "anyOf": [ { "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "type": "string" }, { "type": "null" } ], "description": "Filter by bound agent.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id" } }, { "description": "Filter by consenting user.", "examples": { "example": { "summary": "User ID", "value": "usr_6968b3987ee4c3ec0b4ee3b9" } }, "in": "query", "name": "user_id", "required": false, "schema": { "anyOf": [ { "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "type": "string" }, { "type": "null" } ], "description": "Filter by consenting user.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "User Id" } }, { "description": "Filter by grant lifecycle state.", "examples": { "example": { "summary": "Example query value for `status`", "value": "active" } }, "in": "query", "name": "status", "required": false, "schema": { "anyOf": [ { "enum": [ "active", "revoked" ], "examples": [ "active" ], "type": "string" }, { "type": "null" } ], "description": "Filter by grant lifecycle state.", "examples": [ "active" ], "title": "Status" } }, { "description": "Maximum number of grants to return (1-200, default 50).", "examples": { "example": { "summary": "Example query value for `limit`", "value": 25 } }, "in": "query", "name": "limit", "required": false, "schema": { "default": 50, "description": "Maximum number of grants to return (1-200, default 50).", "examples": [ 25 ], "maximum": 200, "minimum": 1, "title": "Limit", "type": "integer" } }, { "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": { "example": { "summary": "Opaque cursor from a previous page", "value": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } }, "in": "query", "name": "cursor", "required": false, "schema": { "anyOf": [ { "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "type": "string" }, { "type": "null" } ], "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Cursor" } } ], "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "agent_status": "active", "can_revoke": true, "client_name": "billing-assistant-prod", "client_origin": "https://client.example.com", "created_at": "2026-01-15T09:30:00Z", "id": "ocg_6968b3985e21c5fdf643025d", "last_used_at": "2026-01-19T08:12:00Z", "oauth_client_id": "oc_Xk3vQ9mT2pLw8RzN5bYc1HdF7gJs4AeU", "revoked_at": "2026-01-20T14:05:00Z", "scopes": [ "apis:read", "capabilities:execute" ], "status": "revoked", "user_id": "usr_6968b3987ee4c3ec0b4ee3b9" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" }, "schema": { "$ref": "#/components/schemas/OAuthGrantAdminListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List OAuth grants", "tags": [ "OAuth" ] }, "summary": "List OAuth grants" }, "/agents": { "description": "`POST`: Create an agent. `GET`: List visible agents.", "get": { "description": "List the agents the caller can see, newest first.\n\nVisibility is scoped to the caller: `org:admin` sees every agent; anyone\nelse sees the agents they own. An agent caller also sees itself, and with\n`owner:agents:read` its owner's agents. Filter by lifecycle `status`\n(`pending`, `active`, `rejected`, `disabled`, `archived`). Results are\ncursor-paginated: pass `next_cursor` from the previous page as `cursor`\nwhile `has_more` is true.", "operationId": "listAgents", "parameters": [ { "description": "Cursor from a previous page's `next_cursor`; omit for the first page.", "examples": { "example": { "summary": "Opaque cursor from a previous page", "value": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } }, "in": "query", "name": "cursor", "required": false, "schema": { "anyOf": [ { "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "type": "string" }, { "type": "null" } ], "description": "Cursor from a previous page's `next_cursor`; omit for the first page.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Cursor" } }, { "description": "Maximum number of agents to return (1-200, default 50).", "examples": { "example": { "summary": "Example query value for `limit`", "value": 25 } }, "in": "query", "name": "limit", "required": false, "schema": { "default": 50, "description": "Maximum number of agents to return (1-200, default 50).", "examples": [ 25 ], "maximum": 200, "minimum": 1, "title": "Limit", "type": "integer" } }, { "description": "Only return agents in this lifecycle status: `pending`, `active`, `rejected`, `disabled` or `archived`.", "examples": { "example": { "summary": "Example query value for `status`", "value": "active" } }, "in": "query", "name": "status", "required": false, "schema": { "anyOf": [ { "examples": [ "active" ], "type": "string" }, { "type": "null" } ], "description": "Only return agents in this lifecycle status: `pending`, `active`, `rejected`, `disabled` or `archived`.", "examples": [ "active" ], "title": "Status" } } ], "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "approved_at": "2026-01-15T09:45:00Z", "approved_by": "usr_6968b3987ee4c3ec0b4ee3b9", "created_at": "2026-01-15T09:30:00Z", "denial_reason": "Requested permissions exceed the agent's stated purpose.", "denied_by": "usr_6968b3987ee4c3ec0b4ee3b9", "description": "Reconciles Stripe invoices against the ledger every night.", "has_api_key": true, "id": "agnt_6968b3984d1c238dbe7e2e29", "name": "invoice-reconciler", "owner_id": "usr_6968b3987ee4c3ec0b4ee3b9", "parent_agent_id": "agnt_6968b3984d1c238dbe7e2e29", "registered_by": "usr_6968b3987ee4c3ec0b4ee3b9", "status": "active" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" }, "schema": { "$ref": "#/components/schemas/AgentListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List visible agents", "tags": [ "Agents" ] }, "post": { "description": "Create an agent owned by the caller.\n\nThe agent is `active` immediately and owned by the caller. Supply `name`\n(required), an optional `description`, and optional `permissions`. When\n`permissions` is omitted the agent gets the default agent permission set.\nWhen supplied, every permission must be one the caller may grant (see\n`grantable_by_caller` on `GET /permissions`); otherwise the request fails\nwith 403 (`agent_permission_not_grantable`). Returns the created agent.\n\nThe agent has no way to authenticate yet. Follow up with\n`POST /agents/{agent_id}:generate-api-key` (or `PUT /agents/{agent_id}/jwks`\nfor JWT-bearer), and bind credentials with `POST /agents/{agent_id}/credentials`.", "operationId": "createAgent", "requestBody": { "content": { "application/json": { "example": { "description": "Reconciles Stripe invoices against the ledger every night.", "name": "invoice-reconciler", "permissions": [ "apis:read", "capabilities:execute" ] }, "schema": { "$ref": "#/components/schemas/AgentCreateRequest" } } }, "description": "Request body for creating an agent manually.", "required": true }, "responses": { "201": { "content": { "application/json": { "example": { "approved_at": "2026-01-15T09:45:00Z", "approved_by": "usr_6968b3987ee4c3ec0b4ee3b9", "created_at": "2026-01-15T09:30:00Z", "denial_reason": "Requested permissions exceed the agent's stated purpose.", "denied_by": "usr_6968b3987ee4c3ec0b4ee3b9", "description": "Reconciles Stripe invoices against the ledger every night.", "has_api_key": true, "id": "agnt_6968b3984d1c238dbe7e2e29", "name": "invoice-reconciler", "owner_id": "usr_6968b3987ee4c3ec0b4ee3b9", "parent_agent_id": "agnt_6968b3984d1c238dbe7e2e29", "registered_by": "usr_6968b3987ee4c3ec0b4ee3b9", "status": "active" }, "schema": { "$ref": "#/components/schemas/AgentResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Create an agent", "tags": [ "Agents" ] }, "summary": "Create an agent; List visible agents" }, "/agents/{agent_id}": { "delete": { "description": "Archive an agent — or, with ``purge=true``, hard-delete it.\n\nArchive keeps the row for history, but the action is not reversible and\nthe agent's authority is swept: permission grants, credential bindings, and\nOAuth consent grants are revoked. For the reversible kill switch use\n``:disable`` / ``:enable`` instead.\n\nPurge removes the agent and its authority and session rows; it archives\nfirst if needed, so the agent's authority is gone before any cleanup runs,\nand a failed purge leaves the agent archived and can be retried. Archive\nreturns 409 for an already-archived agent; purge accepts any status.", "operationId": "archiveAgent", "parameters": [ { "description": "ID of the agent.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the agent.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } }, { "description": "Default false: the agent is archived (terminal-but-kept; its row stays for history). true hard-deletes the agent from any status, together with its tokens, consent grants, permission grants and rules, bindings and connect sessions, and cancels its queued and running jobs. History (audit entries, events, execution records, finished jobs, notes) and the credentials it created are kept; once the agent is gone that history is visible to org:admin only.", "examples": { "example": { "summary": "Example query value for `purge`", "value": true } }, "in": "query", "name": "purge", "required": false, "schema": { "default": false, "description": "Default false: the agent is archived (terminal-but-kept; its row stays for history). true hard-deletes the agent from any status, together with its tokens, consent grants, permission grants and rules, bindings and connect sessions, and cancels its queued and running jobs. History (audit entries, events, execution records, finished jobs, notes) and the credentials it created are kept; once the agent is gone that history is visible to org:admin only.", "examples": [ true ], "title": "Purge", "type": "boolean" } } ], "responses": { "204": { "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Archive Agent", "tags": [ "Agents" ] }, "description": "`GET`: Get an agent. `PATCH`: Update an agent. `DELETE`: Archive Agent.", "get": { "description": "Get one agent's profile and lifecycle state.\n\nReturns the agent's name, description, owner, `status`, approval or\ndenial details, and whether it currently has an API key (`has_api_key`).\nReadable by the agent itself, its owner, and `org:admin`; an agent outside\nthe caller's visibility answers 404.", "operationId": "getAgent", "parameters": [ { "description": "ID of the agent.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the agent.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "approved_at": "2026-01-15T09:45:00Z", "approved_by": "usr_6968b3987ee4c3ec0b4ee3b9", "created_at": "2026-01-15T09:30:00Z", "denial_reason": "Requested permissions exceed the agent's stated purpose.", "denied_by": "usr_6968b3987ee4c3ec0b4ee3b9", "description": "Reconciles Stripe invoices against the ledger every night.", "has_api_key": true, "id": "agnt_6968b3984d1c238dbe7e2e29", "name": "invoice-reconciler", "owner_id": "usr_6968b3987ee4c3ec0b4ee3b9", "parent_agent_id": "agnt_6968b3984d1c238dbe7e2e29", "registered_by": "usr_6968b3987ee4c3ec0b4ee3b9", "status": "active" }, "schema": { "$ref": "#/components/schemas/AgentResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get an agent", "tags": [ "Agents" ] }, "patch": { "description": "Partially update an agent's `name`, `description` or `owner_id`.\n\nOnly the fields present in the body change; an empty body returns the\nagent unchanged. Allowed for the agent's owner or an `org:admin` (anyone\nelse gets 404). Changing `owner_id` transfers ownership, is\n`org:admin`-only, and revokes every active OAuth client grant bound to\nthe agent, so the new owner must re-consent any connected client. The\nagent's API key, permissions and credential bindings are unaffected. An\narchived agent cannot be updated (409). Returns the updated agent.", "operationId": "updateAgent", "parameters": [ { "description": "ID of the agent.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the agent.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } } ], "requestBody": { "content": { "application/json": { "example": { "description": "Reconciles Stripe invoices against the ledger every night.", "name": "invoice-reconciler", "owner_id": "usr_6968b3987ee4c3ec0b4ee3b9" }, "schema": { "$ref": "#/components/schemas/AgentPatchRequest" } } }, "description": "Request body for partially updating an agent.", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "approved_at": "2026-01-15T09:45:00Z", "approved_by": "usr_6968b3987ee4c3ec0b4ee3b9", "created_at": "2026-01-15T09:30:00Z", "denial_reason": "Requested permissions exceed the agent's stated purpose.", "denied_by": "usr_6968b3987ee4c3ec0b4ee3b9", "description": "Reconciles Stripe invoices against the ledger every night.", "has_api_key": true, "id": "agnt_6968b3984d1c238dbe7e2e29", "name": "invoice-reconciler", "owner_id": "usr_6968b3987ee4c3ec0b4ee3b9", "parent_agent_id": "agnt_6968b3984d1c238dbe7e2e29", "registered_by": "usr_6968b3987ee4c3ec0b4ee3b9", "status": "active" }, "schema": { "$ref": "#/components/schemas/AgentResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Update an agent", "tags": [ "Agents" ] }, "summary": "Get an agent; Update an agent; Archive Agent" }, "/agents/{agent_id}/api-key": { "description": "`GET`: Get an agent's API key metadata.", "get": { "description": "Describe an agent's API key without revealing it.\n\nReturns the key record's `id`, `status` (`active`, or `revoked` once\nrevoked), `created_at`, `rotated_at` and `created_by`. The plaintext key\nis never returned — it is shown once, by `:generate-api-key`. Metadata\nstays available after revocation; the body is `null` if the agent never\nhad a key. Allowed for the agent's owner or an `org:admin`.", "operationId": "getAgentApiKeyInfo", "parameters": [ { "description": "ID of the agent.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the agent.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "schema": { "anyOf": [ { "$ref": "#/components/schemas/ApiKeyInfoResponse" }, { "type": "null" } ], "title": "Response Getagentapikeyinfo" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get an agent's API key metadata", "tags": [ "Agents" ] }, "summary": "Get an agent's API key metadata" }, "/agents/{agent_id}/api-key/history": { "description": "`GET`: Get an agent's API key history.", "get": { "description": "List recent API key rotations and revocations for an agent.\n\nEach entry gives the audit `action`, its `reason` (key rotated or key\nrevoked), the acting `actor_id`, and `occurred_at`. Drawn from the agent's\n50 most recent audit entries, newest first, so very old key events may\nnot appear; it is not paginated. Allowed for the agent's owner or an\n`org:admin`.", "operationId": "getAgentApiKeyHistory", "parameters": [ { "description": "ID of the agent.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the agent.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "action": "rotate", "actor_id": "usr_6968b3987ee4c3ec0b4ee3b9", "id": "aud_6968b3984275d71e90f7f09f", "occurred_at": "2026-01-20T14:00:00Z", "reason": "api_key_rotated" } ] }, "schema": { "$ref": "#/components/schemas/ApiKeyHistoryResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get an agent's API key history", "tags": [ "Agents" ] }, "summary": "Get an agent's API key history" }, "/agents/{agent_id}/credentials": { "description": "`GET`: List an agent's credential bindings. `POST`: Bind a credential to an agent.", "get": { "description": "List the credentials bound directly to an agent.\n\nEach binding names the credential, the API it serves, when it was bound,\nwhether it is `suspended` (and why), and any attached permission\n`rule_set_id`. Credential secrets are never returned. Readable by the\nagent itself, its owner, and `org:admin` (404 otherwise). The list is not\npaginated.", "operationId": "listAgentCredentials", "parameters": [ { "description": "ID of the agent.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the agent.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "bound_at": "2026-01-15T09:30:00Z", "credential_id": "cred_6968b39855d91a3561684b32", "id": "acb_6968b3989a4f1c2e7d3b5a60", "name": "Stripe production key", "rule_set_id": "prs_6968b3987c22b63e87e79f05", "serves": [ { "api_name": "stripe", "api_vendor": "stripe.com", "api_version": "2024-04-10" } ], "suspended": false, "suspended_reason": "api_deleted" } ] }, "schema": { "$ref": "#/components/schemas/CredentialBindingListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List an agent's credential bindings", "tags": [ "Agents" ] }, "post": { "description": "Let an agent use a credential by binding it directly.\n\nA new binding starts with no permission rules, so the agent can make no\ncalls with it until rules are set or a rule set is attached. The caller\nmust be able to see the agent and must own the credential (or hold\n`org:admin`). A credential that does not exist or that the caller does\nnot own returns 404; binding the same credential twice returns 409\n(`credential_binding_conflict`).\nReturns the new binding.", "operationId": "bindAgentCredential", "parameters": [ { "description": "ID of the agent.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the agent.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } } ], "requestBody": { "content": { "application/json": { "example": { "credential_id": "cred_6968b39855d91a3561684b32" }, "schema": { "$ref": "#/components/schemas/CredentialBindRequest" } } }, "description": "Request body for directly binding a credential to an agent.", "required": true }, "responses": { "201": { "content": { "application/json": { "example": { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "bound_at": "2026-01-15T09:30:00Z", "credential_id": "cred_6968b39855d91a3561684b32", "id": "acb_6968b3989a4f1c2e7d3b5a60", "name": "Stripe production key", "rule_set_id": "prs_6968b3987c22b63e87e79f05", "serves": [ { "api_name": "stripe", "api_vendor": "stripe.com", "api_version": "2024-04-10" } ], "suspended": false, "suspended_reason": "api_deleted" }, "schema": { "$ref": "#/components/schemas/CredentialBindingResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Bind a credential to an agent", "tags": [ "Agents" ] }, "summary": "List an agent's credential bindings; Bind a credential to an agent" }, "/agents/{agent_id}/credentials/{credential_id}": { "delete": { "description": "Stop an agent using a credential: suspend the binding, or purge it.\n\nBy default the binding is **suspended**: the agent loses access at once,\nbut the binding and its permission rules are kept, and\n`POST /agents/{agent_id}/credentials/{credential_id}:resume` restores it.\nWith `purge=true` the binding and its inline permission rules are deleted\noutright, so a later re-bind starts from deny-all. An agent may suspend\nits own binding but not purge it. Both modes are audited. Returns 204; a\nmissing binding returns 404.", "operationId": "unbindAgentCredential", "parameters": [ { "description": "ID of the agent.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the agent.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } }, { "description": "ID of the credential bound to the agent.", "examples": { "example": { "summary": "Credential ID", "value": "cred_6968b39855d91a3561684b32" } }, "in": "path", "name": "credential_id", "required": true, "schema": { "description": "ID of the credential bound to the agent.", "examples": [ "cred_6968b39855d91a3561684b32" ], "title": "Credential Id", "type": "string" } }, { "description": "Default false: the binding is suspended (reversible; its permission rules survive and :resume restores access). true deletes the binding row outright, together with its inline permission rules.", "examples": { "example": { "summary": "Example query value for `purge`", "value": true } }, "in": "query", "name": "purge", "required": false, "schema": { "default": false, "description": "Default false: the binding is suspended (reversible; its permission rules survive and :resume restores access). true deletes the binding row outright, together with its inline permission rules.", "examples": [ true ], "title": "Purge", "type": "boolean" } } ], "responses": { "204": { "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Suspend or remove a credential binding", "tags": [ "Agents" ] }, "description": "`DELETE`: Suspend or remove a credential binding.", "summary": "Suspend or remove a credential binding" }, "/agents/{agent_id}/credentials/{credential_id}:resume": { "description": "`POST`: Resume a suspended credential binding.", "post": { "description": "Restore an agent's access to a credential whose binding was suspended.\n\nReverses the default (non-purge) unbind; a purged binding is gone and must\nbe bound again instead. Because resuming re-grants the credential, the\ncaller must own the credential (or hold `org:admin`) as well as see the\nagent, and an agent cannot resume its own binding. Returns the binding;\n404 when no binding exists.", "operationId": "resumeAgentCredentialBinding", "parameters": [ { "description": "ID of the agent.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the agent.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } }, { "description": "ID of the credential bound to the agent.", "examples": { "example": { "summary": "Credential ID", "value": "cred_6968b39855d91a3561684b32" } }, "in": "path", "name": "credential_id", "required": true, "schema": { "description": "ID of the credential bound to the agent.", "examples": [ "cred_6968b39855d91a3561684b32" ], "title": "Credential Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "bound_at": "2026-01-15T09:30:00Z", "credential_id": "cred_6968b39855d91a3561684b32", "id": "acb_6968b3989a4f1c2e7d3b5a60", "name": "Stripe production key", "rule_set_id": "prs_6968b3987c22b63e87e79f05", "serves": [ { "api_name": "stripe", "api_vendor": "stripe.com", "api_version": "2024-04-10" } ], "suspended": false, "suspended_reason": "api_deleted" }, "schema": { "$ref": "#/components/schemas/CredentialBindingResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Resume a suspended credential binding", "tags": [ "Agents" ] }, "summary": "Resume a suspended credential binding" }, "/agents/{agent_id}/jwks": { "description": "`PUT`: Update Agent Jwks.", "put": { "description": "Update an agent's JWKS (public keys for JWT-bearer authentication).\n\nThe JWKS must contain at least one Ed25519 public key and must not contain\nany private key material. This enables the agent to authenticate via\nJWT-bearer assertions signed with the corresponding private key.", "operationId": "updateAgentJwks", "parameters": [ { "description": "ID of the agent.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the agent.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } } ], "requestBody": { "content": { "application/json": { "example": { "jwks": { "keys": [ { "crv": "Ed25519", "kid": "agent-key-1", "kty": "OKP", "x": "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo" } ] } }, "schema": { "$ref": "#/components/schemas/JwksUpdateRequest" } } }, "description": "Request body for updating an agent's JWKS (public keys).\n\nThe JWKS must contain at least one Ed25519 public key and must not\ncontain any private key material.", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "approved_at": "2026-01-15T09:45:00Z", "approved_by": "usr_6968b3987ee4c3ec0b4ee3b9", "created_at": "2026-01-15T09:30:00Z", "denial_reason": "Requested permissions exceed the agent's stated purpose.", "denied_by": "usr_6968b3987ee4c3ec0b4ee3b9", "description": "Reconciles Stripe invoices against the ledger every night.", "has_api_key": true, "id": "agnt_6968b3984d1c238dbe7e2e29", "name": "invoice-reconciler", "owner_id": "usr_6968b3987ee4c3ec0b4ee3b9", "parent_agent_id": "agnt_6968b3984d1c238dbe7e2e29", "registered_by": "usr_6968b3987ee4c3ec0b4ee3b9", "status": "active" }, "schema": { "$ref": "#/components/schemas/AgentResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Update Agent Jwks", "tags": [ "Agents" ] }, "summary": "Update Agent Jwks" }, "/agents/{agent_id}/oauth-grants": { "description": "`GET`: List an agent's connected OAuth clients.", "get": { "description": "List the OAuth clients a user has consented to act as this agent.\n\nEach grant gives the client's display name and redirect-URI origin, the\ngranted scopes, the consenting user, its `status`, created and last-used\ntimestamps, and `can_revoke` for the caller. Filter by `status`\n(`active` or `revoked`); results are cursor-paginated. Allowed for the\nagent's owner or an admin. An agent the caller cannot see answers 404,\nthe same as one that does not exist. Revoke a grant with\n`POST /oauth-grants/{grant_id}:revoke`.", "operationId": "listAgentOauthGrants", "parameters": [ { "description": "ID of the agent.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the agent.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } }, { "description": "Filter by grant lifecycle state.", "examples": { "example": { "summary": "Example query value for `status`", "value": "active" } }, "in": "query", "name": "status", "required": false, "schema": { "anyOf": [ { "enum": [ "active", "revoked" ], "examples": [ "active" ], "type": "string" }, { "type": "null" } ], "description": "Filter by grant lifecycle state.", "examples": [ "active" ], "title": "Status" } }, { "description": "Maximum number of grants to return (1-200, default 50).", "examples": { "example": { "summary": "Example query value for `limit`", "value": 25 } }, "in": "query", "name": "limit", "required": false, "schema": { "default": 50, "description": "Maximum number of grants to return (1-200, default 50).", "examples": [ 25 ], "maximum": 200, "minimum": 1, "title": "Limit", "type": "integer" } }, { "description": "Cursor from a previous page's `next_cursor`; omit for the first page.", "examples": { "example": { "summary": "Opaque cursor from a previous page", "value": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } }, "in": "query", "name": "cursor", "required": false, "schema": { "anyOf": [ { "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "type": "string" }, { "type": "null" } ], "description": "Cursor from a previous page's `next_cursor`; omit for the first page.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Cursor" } } ], "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "agent_status": "active", "can_revoke": true, "client_name": "Cursor", "client_origin": "https://client.example.com", "created_at": "2026-01-15T09:30:00Z", "id": "ocg_6968b3985e21c5fdf643025d", "last_used_at": "2026-01-24T08:15:00Z", "oauth_client_id": "oc_Xk3vQ9mT2pLw8RzN5bYc1HdF7gJs4AeU", "revoked_at": "2026-01-25T16:00:00Z", "scopes": [ "apis:read", "capabilities:execute" ], "status": "revoked", "user_id": "usr_6968b3987ee4c3ec0b4ee3b9" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" }, "schema": { "$ref": "#/components/schemas/OAuthGrantListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List an agent's connected OAuth clients", "tags": [ "Agents" ] }, "summary": "List an agent's connected OAuth clients" }, "/agents/{agent_id}/permissions": { "description": "`GET`: Get Agent Permissions. `PUT`: Replace Agent Permissions.", "get": { "description": "List permissions granted to an agent.", "operationId": "getAgentPermissions", "parameters": [ { "description": "ID of the agent.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the agent.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "permissions": [ "apis:read", "capabilities:execute" ] }, "schema": { "$ref": "#/components/schemas/AgentPermissionsResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get Agent Permissions", "tags": [ "Agents" ] }, "put": { "description": "Replace all permissions for an agent.", "operationId": "replaceAgentPermissions", "parameters": [ { "description": "ID of the agent.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the agent.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } } ], "requestBody": { "content": { "application/json": { "example": { "permissions": [ "apis:read", "capabilities:execute" ] }, "schema": { "$ref": "#/components/schemas/AgentPermissionsRequest" } } }, "description": "Request body for replacing an agent's permissions.", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "permissions": [ "apis:read", "capabilities:execute" ] }, "schema": { "$ref": "#/components/schemas/AgentPermissionsResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Replace Agent Permissions", "tags": [ "Agents" ] }, "summary": "Get Agent Permissions; Replace Agent Permissions" }, "/agents/{agent_id}:approve": { "description": "`POST`: Approve Agent.", "post": { "description": "Approve a pending agent.\n\nAllowed for the agent's owner or an ``org:admin``. An agent with no owner\n(an unclaimed self-registration) can be approved only by an ``org:admin``,\nwho becomes its owner. Any other caller gets a 404, whatever the agent's\nstatus, so the response does not reveal agents outside the caller's\nownership.", "operationId": "approveAgent", "parameters": [ { "description": "ID of the agent.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the agent.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "approved_at": "2026-01-15T09:45:00Z", "approved_by": "usr_6968b3987ee4c3ec0b4ee3b9", "created_at": "2026-01-15T09:30:00Z", "denial_reason": "Requested permissions exceed the agent's stated purpose.", "denied_by": "usr_6968b3987ee4c3ec0b4ee3b9", "description": "Reconciles Stripe invoices against the ledger every night.", "has_api_key": true, "id": "agnt_6968b3984d1c238dbe7e2e29", "name": "invoice-reconciler", "owner_id": "usr_6968b3987ee4c3ec0b4ee3b9", "parent_agent_id": "agnt_6968b3984d1c238dbe7e2e29", "registered_by": "usr_6968b3987ee4c3ec0b4ee3b9", "status": "active" }, "schema": { "$ref": "#/components/schemas/AgentResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Approve Agent", "tags": [ "Agents" ] }, "summary": "Approve Agent" }, "/agents/{agent_id}:claim": { "description": "`POST`: Claim Agent.", "post": { "description": "Claim ownership of a self-registered agent using its claim token.\n\nAuthenticated by the platform bearer token but requires **no** agent\npermission — the single-use claim token minted at ``/register`` is the proof,\nso the registering human (even a plain member) can take ownership. Sets\n``owner_id`` to the caller; the existing scoping + approve paths then apply.\n\nRestricted to ``USER`` actors: ``Agent.owner_id`` is a FK to ``users.id``, so\nonly a human can own an agent. The ``require_actor_type`` gate rejects a\nnon-user actor (an agent) at the boundary with a 403;\n``AgentService.claim`` re-checks the same invariant as defense-in-depth.\n\n``allow_expired_password=True`` is intentional (matching ``GET /agents/{id}``):\nclaiming is an onboarding step a brand-new user may hit before they have\nrotated a temporary password, so a must-change-password state must not block\nit. The claim only sets ownership — it grants no permissions and cannot act as the\nagent — so allowing it under an expired password is low-risk.", "operationId": "claimAgent", "parameters": [ { "description": "ID of the agent.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the agent.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } } ], "requestBody": { "content": { "application/json": { "example": { "token": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" }, "schema": { "$ref": "#/components/schemas/ClaimRequest" } } }, "description": "Request body for claiming ownership of a self-registered agent.", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "approved_at": "2026-01-15T09:45:00Z", "approved_by": "usr_6968b3987ee4c3ec0b4ee3b9", "created_at": "2026-01-15T09:30:00Z", "denial_reason": "Requested permissions exceed the agent's stated purpose.", "denied_by": "usr_6968b3987ee4c3ec0b4ee3b9", "description": "Reconciles Stripe invoices against the ledger every night.", "has_api_key": true, "id": "agnt_6968b3984d1c238dbe7e2e29", "name": "invoice-reconciler", "owner_id": "usr_6968b3987ee4c3ec0b4ee3b9", "parent_agent_id": "agnt_6968b3984d1c238dbe7e2e29", "registered_by": "usr_6968b3987ee4c3ec0b4ee3b9", "status": "active" }, "schema": { "$ref": "#/components/schemas/AgentResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Claim Agent", "tags": [ "Agents" ] }, "summary": "Claim Agent" }, "/agents/{agent_id}:deny": { "description": "`POST`: Deny Agent.", "post": { "description": "Deny a pending agent.\n\nSame authorization as approve: the agent's owner or an ``org:admin``, and\nonly an ``org:admin`` for an agent with no owner. Any other caller gets a\n404.", "operationId": "denyAgent", "parameters": [ { "description": "ID of the agent.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the agent.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } } ], "requestBody": { "content": { "application/json": { "example": { "reason": "Requested permissions exceed the agent's stated purpose." }, "schema": { "$ref": "#/components/schemas/DenyRequest" } } }, "description": "Request body for denying an agent.", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "approved_at": "2026-01-15T09:45:00Z", "approved_by": "usr_6968b3987ee4c3ec0b4ee3b9", "created_at": "2026-01-15T09:30:00Z", "denial_reason": "Requested permissions exceed the agent's stated purpose.", "denied_by": "usr_6968b3987ee4c3ec0b4ee3b9", "description": "Reconciles Stripe invoices against the ledger every night.", "has_api_key": true, "id": "agnt_6968b3984d1c238dbe7e2e29", "name": "invoice-reconciler", "owner_id": "usr_6968b3987ee4c3ec0b4ee3b9", "parent_agent_id": "agnt_6968b3984d1c238dbe7e2e29", "registered_by": "usr_6968b3987ee4c3ec0b4ee3b9", "status": "active" }, "schema": { "$ref": "#/components/schemas/AgentResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Deny Agent", "tags": [ "Agents" ] }, "summary": "Deny Agent" }, "/agents/{agent_id}:disable": { "description": "`POST`: Disable Agent.", "post": { "description": "Disable an active agent.", "operationId": "disableAgent", "parameters": [ { "description": "ID of the agent.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the agent.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } } ], "responses": { "204": { "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Disable Agent", "tags": [ "Agents" ] }, "summary": "Disable Agent" }, "/agents/{agent_id}:enable": { "description": "`POST`: Enable Agent.", "post": { "description": "Enable a disabled agent.", "operationId": "enableAgent", "parameters": [ { "description": "ID of the agent.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the agent.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } } ], "responses": { "204": { "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Enable Agent", "tags": [ "Agents" ] }, "summary": "Enable Agent" }, "/agents/{agent_id}:generate-api-key": { "description": "`POST`: Generate Agent Api Key.", "post": { "description": "Generate a new API key for an active agent. Rotates any existing key.", "operationId": "generateAgentApiKey", "parameters": [ { "description": "ID of the agent.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the agent.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "key": "jak_example-secret" }, "schema": { "$ref": "#/components/schemas/ApiKeyResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Generate Agent Api Key", "tags": [ "Agents" ] }, "summary": "Generate Agent Api Key" }, "/agents/{agent_id}:revoke-api-key": { "description": "`POST`: Revoke Agent Api Key.", "post": { "description": "Revoke an agent's API key without generating a new one.", "operationId": "revokeAgentApiKey", "parameters": [ { "description": "ID of the agent.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the agent.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } } ], "responses": { "204": { "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Revoke Agent Api Key", "tags": [ "Agents" ] }, "summary": "Revoke Agent Api Key" }, "/apis": { "description": "`GET`: List Apis. `POST`: Import Apis.", "get": { "description": "List locally registered APIs with optional vendor filter and pagination.\n\nThis is the **imported** registry — APIs present in this deployment. The\npublic catalog of importable-but-not-yet-imported APIs is a separate surface\n(``GET /catalog``); the two are not blended.", "operationId": "listApis", "parameters": [ { "description": "Only return APIs from this vendor.", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "query", "name": "vendor", "required": false, "schema": { "anyOf": [ { "examples": [ "stripe.com" ], "type": "string" }, { "type": "null" } ], "description": "Only return APIs from this vendor.", "examples": [ "stripe.com" ], "title": "Vendor" } }, { "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": { "example": { "summary": "Opaque cursor from a previous page", "value": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } }, "in": "query", "name": "cursor", "required": false, "schema": { "anyOf": [ { "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "type": "string" }, { "type": "null" } ], "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Cursor" } }, { "description": "Maximum number of APIs to return (1-200).", "examples": { "example": { "summary": "Example query value for `limit`", "value": 25 } }, "in": "query", "name": "limit", "required": false, "schema": { "default": 50, "description": "Maximum number of APIs to return (1-200).", "examples": [ 25 ], "maximum": 200, "minimum": 1, "title": "Limit", "type": "integer" } } ], "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "_links": { "current_revision": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/revisions/3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "revisions": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/revisions", "self": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10" }, "api": { "host": "api.stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "catalog_api_id": "stripe.com", "created_at": "2026-01-10T08:00:00Z", "current_revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "description": "Online payments platform: charges, customers, subscriptions and payouts.", "display_name": "Stripe", "icon_url": "https://stripe.com/favicon.ico", "operation_count": 412, "origin": "catalog", "revision_count": 2, "security_schemes": [ "http" ], "source_url": "https://raw.githubusercontent.com/jentic/jentic-public-apis/main/apis/openapi/stripe.com/main/2024-04-10/openapi.json", "update_available": false, "updated_at": "2026-01-15T09:30:00Z" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" }, "schema": { "$ref": "#/components/schemas/ApiListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List Apis", "tags": [ "APIs" ] }, "post": { "description": "Import OpenAPI/Arazzo content as new API revisions (async).", "operationId": "importApis", "requestBody": { "content": { "application/json": { "example": { "sources": [ { "api_name": "stripe", "submitted_by": "usr_6968b3987ee4c3ec0b4ee3b9", "type": "url", "url": "https://raw.githubusercontent.com/jentic/jentic-public-apis/main/apis/openapi/stripe.com/main/2024-04-10/openapi.json", "vendor": "stripe.com", "version": "2024-04-10" } ] }, "schema": { "$ref": "#/components/schemas/ApiImportRequest" } } }, "description": "Wrapper for a batch of import sources.", "required": true }, "responses": { "202": { "content": { "application/json": { "schema": {} } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Import Apis", "tags": [ "APIs" ] }, "summary": "List Apis; Import Apis" }, "/apis/{vendor}/{name}/{version}": { "delete": { "description": "Delete an API and all its revisions.", "operationId": "deleteApi", "parameters": [ { "description": "Vendor of the API.", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "path", "name": "vendor", "required": true, "schema": { "description": "Vendor of the API.", "examples": [ "stripe.com" ], "title": "Vendor", "type": "string" } }, { "description": "Name of the API.", "examples": { "example": { "summary": "API name", "value": "stripe" } }, "in": "path", "name": "name", "required": true, "schema": { "description": "Name of the API.", "examples": [ "stripe" ], "title": "Name", "type": "string" } }, { "description": "Version of the API.", "examples": { "example": { "summary": "API version", "value": "2024-04-10" } }, "in": "path", "name": "version", "required": true, "schema": { "description": "Version of the API.", "examples": [ "2024-04-10" ], "title": "Version", "type": "string" } } ], "responses": { "204": { "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "409": { "content": { "application/problem+json": { "example": { "detail": "The request conflicts with the current state of the resource.", "instance": "/example/path", "status": 409, "title": "Conflict", "type": "conflict" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "The API can't be deleted because another record still references it (type `api_delete_blocked`). Nothing was deleted." }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Delete Api", "tags": [ "APIs" ] }, "description": "`GET`: Get Api. `PATCH`: Update Api. `DELETE`: Delete Api.", "get": { "description": "Retrieve a single API by its (vendor, name, version) identity.", "operationId": "getApi", "parameters": [ { "description": "Vendor of the API.", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "path", "name": "vendor", "required": true, "schema": { "description": "Vendor of the API.", "examples": [ "stripe.com" ], "title": "Vendor", "type": "string" } }, { "description": "Name of the API.", "examples": { "example": { "summary": "API name", "value": "stripe" } }, "in": "path", "name": "name", "required": true, "schema": { "description": "Name of the API.", "examples": [ "stripe" ], "title": "Name", "type": "string" } }, { "description": "Version of the API.", "examples": { "example": { "summary": "API version", "value": "2024-04-10" } }, "in": "path", "name": "version", "required": true, "schema": { "description": "Version of the API.", "examples": [ "2024-04-10" ], "title": "Version", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "_links": { "current_revision": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/revisions/3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "revisions": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/revisions", "self": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10" }, "api": { "host": "api.stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "catalog_api_id": "stripe.com", "created_at": "2026-01-10T08:00:00Z", "current_revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "description": "Online payments platform: charges, customers, subscriptions and payouts.", "display_name": "Stripe", "icon_url": "https://stripe.com/favicon.ico", "operation_count": 412, "origin": "catalog", "revision_count": 2, "security_schemes": [ "http" ], "source_url": "https://raw.githubusercontent.com/jentic/jentic-public-apis/main/apis/openapi/stripe.com/main/2024-04-10/openapi.json", "update_available": false, "updated_at": "2026-01-15T09:30:00Z" }, "schema": { "$ref": "#/components/schemas/ApiResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get Api", "tags": [ "APIs" ] }, "patch": { "description": "Partially update an API's presentation fields.", "operationId": "updateApi", "parameters": [ { "description": "Vendor of the API.", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "path", "name": "vendor", "required": true, "schema": { "description": "Vendor of the API.", "examples": [ "stripe.com" ], "title": "Vendor", "type": "string" } }, { "description": "Name of the API.", "examples": { "example": { "summary": "API name", "value": "stripe" } }, "in": "path", "name": "name", "required": true, "schema": { "description": "Name of the API.", "examples": [ "stripe" ], "title": "Name", "type": "string" } }, { "description": "Version of the API.", "examples": { "example": { "summary": "API version", "value": "2024-04-10" } }, "in": "path", "name": "version", "required": true, "schema": { "description": "Version of the API.", "examples": [ "2024-04-10" ], "title": "Version", "type": "string" } } ], "requestBody": { "content": { "application/json": { "example": { "description": "Online payments platform: charges, customers, subscriptions and payouts.", "display_name": "Stripe", "icon_url": "https://stripe.com/favicon.ico" }, "schema": { "$ref": "#/components/schemas/ApiUpdateRequest" } } }, "description": "Partial update payload for an API's presentation fields.", "required": true }, "responses": { "200": { "content": { "application/json": { "schema": {} } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Update Api", "tags": [ "APIs" ] }, "summary": "Get Api; Update Api; Delete Api" }, "/apis/{vendor}/{name}/{version}/openapi": { "description": "`GET`: Get Api Spec.", "get": { "description": "Download the OpenAPI spec for the API's current (live) revision.", "operationId": "getApiSpec", "parameters": [ { "description": "Vendor of the API.", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "path", "name": "vendor", "required": true, "schema": { "description": "Vendor of the API.", "examples": [ "stripe.com" ], "title": "Vendor", "type": "string" } }, { "description": "Name of the API.", "examples": { "example": { "summary": "API name", "value": "stripe" } }, "in": "path", "name": "name", "required": true, "schema": { "description": "Name of the API.", "examples": [ "stripe" ], "title": "Name", "type": "string" } }, { "description": "Version of the API.", "examples": { "example": { "summary": "API version", "value": "2024-04-10" } }, "in": "path", "name": "version", "required": true, "schema": { "description": "Version of the API.", "examples": [ "2024-04-10" ], "title": "Version", "type": "string" } }, { "description": "Reserved for applying overlays at read time; currently has no effect, as confirmed overlays are already part of the stored document.", "examples": { "example": { "summary": "Example query value for `overlays`", "value": false } }, "in": "query", "name": "overlays", "required": false, "schema": { "default": true, "description": "Reserved for applying overlays at read time; currently has no effect, as confirmed overlays are already part of the stored document.", "examples": [ false ], "title": "Overlays", "type": "boolean" } } ], "responses": { "200": { "content": { "application/json": { "schema": {} } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get Api Spec", "tags": [ "API Spec" ] }, "summary": "Get Api Spec" }, "/apis/{vendor}/{name}/{version}/operations": { "description": "`GET`: List the operations an API currently serves.", "get": { "description": "List every operation in the API's current (live) revision.\n\nEach row gives the operation's id, method, path, name, description, tags,\n`deprecated` flag, and an `inspect` link for its full detail. Rows come in\na stable, unranked order and are cursor-paginated (`cursor`, `limit`).\nUse this to browse an API exhaustively; to find operations by intent,\nuse `GET /search` instead. 404 (`no_current_revision`) when the API has no live\nrevision.", "operationId": "listApiOperations", "parameters": [ { "description": "Vendor of the API.", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "path", "name": "vendor", "required": true, "schema": { "description": "Vendor of the API.", "examples": [ "stripe.com" ], "title": "Vendor", "type": "string" } }, { "description": "Name of the API.", "examples": { "example": { "summary": "API name", "value": "stripe" } }, "in": "path", "name": "name", "required": true, "schema": { "description": "Name of the API.", "examples": [ "stripe" ], "title": "Name", "type": "string" } }, { "description": "Version of the API.", "examples": { "example": { "summary": "API version", "value": "2024-04-10" } }, "in": "path", "name": "version", "required": true, "schema": { "description": "Version of the API.", "examples": [ "2024-04-10" ], "title": "Version", "type": "string" } }, { "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": { "example": { "summary": "Opaque cursor from a previous page", "value": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } }, "in": "query", "name": "cursor", "required": false, "schema": { "anyOf": [ { "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "type": "string" }, { "type": "null" } ], "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Cursor" } }, { "description": "Maximum number of operations to return (1-200).", "examples": { "example": { "summary": "Example query value for `limit`", "value": 25 } }, "in": "query", "name": "limit", "required": false, "schema": { "default": 50, "description": "Maximum number of operations to return (1-200).", "examples": [ 25 ], "maximum": 200, "minimum": 1, "title": "Limit", "type": "integer" } } ], "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "_links": { "inspect": "https://jentic.example.com/inspect?operation_id=op_f92d69f1621f381bce8aaff47053c61b069ffe34&revision_id=3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" }, "api": { "host": "api.stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "deprecated": false, "description": "Returns a list of charges you've previously created, newest first.", "method": "GET", "name": "List all charges", "operation_id": "op_f92d69f1621f381bce8aaff47053c61b069ffe34", "path": "/v1/charges", "revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "tags": [ "Charges" ] } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" }, "schema": { "$ref": "#/components/schemas/OperationSummaryListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List the operations an API currently serves", "tags": [ "API Operations" ] }, "summary": "List the operations an API currently serves" }, "/apis/{vendor}/{name}/{version}/overlays": { "description": "`POST`: Submit an OpenAPI overlay. `GET`: List an API's overlays.", "get": { "description": "List the overlays submitted against an API, newest first.\n\nEach overlay gives its `status` — `pending` (awaiting review), `confirmed`\n(applied to the served spec) or `deprecated` (retired) — and links to the\nactions valid in that state. Filter with `status`. Results are\ncursor-paginated: pass `next_cursor` as `cursor` while `has_more` is\ntrue.", "operationId": "listOverlays", "parameters": [ { "description": "Vendor of the API.", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "path", "name": "vendor", "required": true, "schema": { "description": "Vendor of the API.", "examples": [ "stripe.com" ], "title": "Vendor", "type": "string" } }, { "description": "Name of the API.", "examples": { "example": { "summary": "API name", "value": "stripe" } }, "in": "path", "name": "name", "required": true, "schema": { "description": "Name of the API.", "examples": [ "stripe" ], "title": "Name", "type": "string" } }, { "description": "Version of the API.", "examples": { "example": { "summary": "API version", "value": "2024-04-10" } }, "in": "path", "name": "version", "required": true, "schema": { "description": "Version of the API.", "examples": [ "2024-04-10" ], "title": "Version", "type": "string" } }, { "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": { "example": { "summary": "Opaque cursor from a previous page", "value": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } }, "in": "query", "name": "cursor", "required": false, "schema": { "anyOf": [ { "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "type": "string" }, { "type": "null" } ], "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Cursor" } }, { "description": "Maximum number of overlays to return (1-200).", "examples": { "example": { "summary": "Example query value for `limit`", "value": 25 } }, "in": "query", "name": "limit", "required": false, "schema": { "default": 50, "description": "Maximum number of overlays to return (1-200).", "examples": [ 25 ], "maximum": 200, "minimum": 1, "title": "Limit", "type": "integer" } }, { "description": "Only return overlays in this status: `pending`, `confirmed` or `deprecated`.", "examples": { "example": { "summary": "Example query value for `status`", "value": "confirmed" } }, "in": "query", "name": "status", "required": false, "schema": { "anyOf": [ { "examples": [ "confirmed" ], "type": "string" }, { "type": "null" } ], "description": "Only return overlays in this status: `pending`, `confirmed` or `deprecated`.", "examples": [ "confirmed" ], "title": "Status" } } ], "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "_links": { "api": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10", "confirm": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a:confirm", "deprecate": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a", "rollback": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a:rollback", "self": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a" }, "api_id": "debfc9ff-7c37-4a09-801a-575bd4963ddd", "confirmed_at": "2026-01-15T10:05:00Z", "confirmed_by_execution_id": "exec_6968b3982706c619fe73f0cf", "confirmed_revision_id": "6992059c-0abd-4d22-bd07-5287e1bf5e6a", "contributed_by": "docs-review-agent", "created_at": "2026-01-15T09:30:00Z", "created_by": "agnt_6968b3984d1c238dbe7e2e29", "deprecated_at": "2026-01-17T16:45:00Z", "deprecated_reason": "rollback", "document": { "actions": [ { "target": "$.paths['/v1/charges'].get", "update": { "summary": "List all charges, newest first" } } ], "info": { "title": "Clarify charges listing", "version": "1.0.0" }, "overlay": "1.0.0" }, "id": "ovr_6968b398ae1c9a6e2fe6520a", "status": "deprecated", "superseded_revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "target_revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "updated_at": "2026-01-17T16:45:00Z" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" }, "schema": { "$ref": "#/components/schemas/OverlayListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List an API's overlays", "tags": [ "Overlays" ] }, "post": { "description": "Propose a change to an API's spec as an OpenAPI Overlay document.\n\nAn overlay is a list of `actions` that patch the API's OpenAPI document —\nfor example correcting a description or adding a missing parameter.\nSubmitting stores it as `pending`; it changes nothing until an operator\nconfirms it (`:confirm`). Optionally pin it to a `target_revision_id` and\nrecord a `contributed_by` label. The document must be a JSON object with\nan `actions` array (at most 512 actions, 1 MB), else 422\n(`invalid_overlay_document`). Requires `apis:write`. Returns the overlay.", "operationId": "submitOverlay", "parameters": [ { "description": "Vendor of the API.", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "path", "name": "vendor", "required": true, "schema": { "description": "Vendor of the API.", "examples": [ "stripe.com" ], "title": "Vendor", "type": "string" } }, { "description": "Name of the API.", "examples": { "example": { "summary": "API name", "value": "stripe" } }, "in": "path", "name": "name", "required": true, "schema": { "description": "Name of the API.", "examples": [ "stripe" ], "title": "Name", "type": "string" } }, { "description": "Version of the API.", "examples": { "example": { "summary": "API version", "value": "2024-04-10" } }, "in": "path", "name": "version", "required": true, "schema": { "description": "Version of the API.", "examples": [ "2024-04-10" ], "title": "Version", "type": "string" } } ], "requestBody": { "content": { "application/json": { "example": { "contributed_by": "docs-review-agent", "document": { "actions": [ { "target": "$.paths['/v1/charges'].get", "update": { "summary": "List all charges, newest first" } } ], "info": { "title": "Clarify charges listing", "version": "1.0.0" }, "overlay": "1.0.0" }, "target_revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" }, "schema": { "$ref": "#/components/schemas/OverlaySubmitRequest" } } }, "description": "Payload for submitting a new overlay.", "required": true }, "responses": { "201": { "content": { "application/json": { "example": { "_links": { "api": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10", "confirm": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a:confirm", "deprecate": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a", "rollback": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a:rollback", "self": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a" }, "api_id": "debfc9ff-7c37-4a09-801a-575bd4963ddd", "confirmed_at": "2026-01-15T10:05:00Z", "confirmed_by_execution_id": "exec_6968b3982706c619fe73f0cf", "confirmed_revision_id": "6992059c-0abd-4d22-bd07-5287e1bf5e6a", "contributed_by": "docs-review-agent", "created_at": "2026-01-15T09:30:00Z", "created_by": "agnt_6968b3984d1c238dbe7e2e29", "deprecated_at": "2026-01-17T16:45:00Z", "deprecated_reason": "rollback", "document": { "actions": [ { "target": "$.paths['/v1/charges'].get", "update": { "summary": "List all charges, newest first" } } ], "info": { "title": "Clarify charges listing", "version": "1.0.0" }, "overlay": "1.0.0" }, "id": "ovr_6968b398ae1c9a6e2fe6520a", "status": "deprecated", "superseded_revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "target_revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "updated_at": "2026-01-17T16:45:00Z" }, "schema": { "$ref": "#/components/schemas/OverlayResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Submit an OpenAPI overlay", "tags": [ "Overlays" ] }, "summary": "Submit an OpenAPI overlay; List an API's overlays" }, "/apis/{vendor}/{name}/{version}/overlays/{overlay_id}": { "delete": { "description": "Retire an overlay so it is no longer offered for confirmation.\n\nThe overlay moves to `deprecated` but is kept, and remains readable for\nhistory; nothing is deleted. Deprecating does not rewrite the served\nspec: to undo a confirmed overlay's change, use `:rollback`. Requires\n`apis:write`. Returns 204.", "operationId": "deprecateOverlay", "parameters": [ { "description": "Vendor of the API.", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "path", "name": "vendor", "required": true, "schema": { "description": "Vendor of the API.", "examples": [ "stripe.com" ], "title": "Vendor", "type": "string" } }, { "description": "Name of the API.", "examples": { "example": { "summary": "API name", "value": "stripe" } }, "in": "path", "name": "name", "required": true, "schema": { "description": "Name of the API.", "examples": [ "stripe" ], "title": "Name", "type": "string" } }, { "description": "Version of the API.", "examples": { "example": { "summary": "API version", "value": "2024-04-10" } }, "in": "path", "name": "version", "required": true, "schema": { "description": "Version of the API.", "examples": [ "2024-04-10" ], "title": "Version", "type": "string" } }, { "description": "ID of the overlay.", "examples": { "example": { "summary": "Overlay ID", "value": "ovr_6968b398ae1c9a6e2fe6520a" } }, "in": "path", "name": "overlay_id", "required": true, "schema": { "description": "ID of the overlay.", "examples": [ "ovr_6968b398ae1c9a6e2fe6520a" ], "title": "Overlay Id", "type": "string" } } ], "responses": { "204": { "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Deprecate an overlay", "tags": [ "Overlays" ] }, "description": "`GET`: Get Overlay. `PATCH`: Edit an overlay. `DELETE`: Deprecate an overlay.", "get": { "description": "Retrieve a single overlay by ID.", "operationId": "getOverlay", "parameters": [ { "description": "Vendor of the API.", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "path", "name": "vendor", "required": true, "schema": { "description": "Vendor of the API.", "examples": [ "stripe.com" ], "title": "Vendor", "type": "string" } }, { "description": "Name of the API.", "examples": { "example": { "summary": "API name", "value": "stripe" } }, "in": "path", "name": "name", "required": true, "schema": { "description": "Name of the API.", "examples": [ "stripe" ], "title": "Name", "type": "string" } }, { "description": "Version of the API.", "examples": { "example": { "summary": "API version", "value": "2024-04-10" } }, "in": "path", "name": "version", "required": true, "schema": { "description": "Version of the API.", "examples": [ "2024-04-10" ], "title": "Version", "type": "string" } }, { "description": "ID of the overlay.", "examples": { "example": { "summary": "Overlay ID", "value": "ovr_6968b398ae1c9a6e2fe6520a" } }, "in": "path", "name": "overlay_id", "required": true, "schema": { "description": "ID of the overlay.", "examples": [ "ovr_6968b398ae1c9a6e2fe6520a" ], "title": "Overlay Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "_links": { "api": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10", "confirm": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a:confirm", "deprecate": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a", "rollback": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a:rollback", "self": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a" }, "api_id": "debfc9ff-7c37-4a09-801a-575bd4963ddd", "confirmed_at": "2026-01-15T10:05:00Z", "confirmed_by_execution_id": "exec_6968b3982706c619fe73f0cf", "confirmed_revision_id": "6992059c-0abd-4d22-bd07-5287e1bf5e6a", "contributed_by": "docs-review-agent", "created_at": "2026-01-15T09:30:00Z", "created_by": "agnt_6968b3984d1c238dbe7e2e29", "deprecated_at": "2026-01-17T16:45:00Z", "deprecated_reason": "rollback", "document": { "actions": [ { "target": "$.paths['/v1/charges'].get", "update": { "summary": "List all charges, newest first" } } ], "info": { "title": "Clarify charges listing", "version": "1.0.0" }, "overlay": "1.0.0" }, "id": "ovr_6968b398ae1c9a6e2fe6520a", "status": "deprecated", "superseded_revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "target_revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "updated_at": "2026-01-17T16:45:00Z" }, "schema": { "$ref": "#/components/schemas/OverlayResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get Overlay", "tags": [ "Overlays" ] }, "patch": { "description": "Change an overlay's `document` or `target_revision_id`.\n\nWhat the edit does depends on the overlay's state:\n\n- **Pending** (or confirmed but not yet applied): the stored overlay is\n updated; the served spec is untouched. Requires `apis:write`.\n- **Confirmed and live**: the edited document is re-applied over the\n overlay's original base and the result replaces the API's served spec.\n This also requires `overlays:confirm`, else 403\n (`overlay_rematerialize_forbidden`). It is refused with 409 if the\n overlay is no longer the live revision, or\n (`overlay_rollback_target_missing`) if no clean base was recorded.\n\nReturns the updated overlay.", "operationId": "updateOverlay", "parameters": [ { "description": "Vendor of the API.", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "path", "name": "vendor", "required": true, "schema": { "description": "Vendor of the API.", "examples": [ "stripe.com" ], "title": "Vendor", "type": "string" } }, { "description": "Name of the API.", "examples": { "example": { "summary": "API name", "value": "stripe" } }, "in": "path", "name": "name", "required": true, "schema": { "description": "Name of the API.", "examples": [ "stripe" ], "title": "Name", "type": "string" } }, { "description": "Version of the API.", "examples": { "example": { "summary": "API version", "value": "2024-04-10" } }, "in": "path", "name": "version", "required": true, "schema": { "description": "Version of the API.", "examples": [ "2024-04-10" ], "title": "Version", "type": "string" } }, { "description": "ID of the overlay.", "examples": { "example": { "summary": "Overlay ID", "value": "ovr_6968b398ae1c9a6e2fe6520a" } }, "in": "path", "name": "overlay_id", "required": true, "schema": { "description": "ID of the overlay.", "examples": [ "ovr_6968b398ae1c9a6e2fe6520a" ], "title": "Overlay Id", "type": "string" } } ], "requestBody": { "content": { "application/json": { "example": { "document": { "actions": [ { "target": "$.paths['/v1/charges'].get", "update": { "summary": "List all charges, newest first" } } ], "info": { "title": "Clarify charges listing", "version": "1.0.0" }, "overlay": "1.0.0" }, "target_revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" }, "schema": { "$ref": "#/components/schemas/OverlayUpdateRequest" } } }, "description": "Payload for updating an existing overlay.", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "_links": { "api": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10", "confirm": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a:confirm", "deprecate": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a", "rollback": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a:rollback", "self": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a" }, "api_id": "debfc9ff-7c37-4a09-801a-575bd4963ddd", "confirmed_at": "2026-01-15T10:05:00Z", "confirmed_by_execution_id": "exec_6968b3982706c619fe73f0cf", "confirmed_revision_id": "6992059c-0abd-4d22-bd07-5287e1bf5e6a", "contributed_by": "docs-review-agent", "created_at": "2026-01-15T09:30:00Z", "created_by": "agnt_6968b3984d1c238dbe7e2e29", "deprecated_at": "2026-01-17T16:45:00Z", "deprecated_reason": "rollback", "document": { "actions": [ { "target": "$.paths['/v1/charges'].get", "update": { "summary": "List all charges, newest first" } } ], "info": { "title": "Clarify charges listing", "version": "1.0.0" }, "overlay": "1.0.0" }, "id": "ovr_6968b398ae1c9a6e2fe6520a", "status": "deprecated", "superseded_revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "target_revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "updated_at": "2026-01-17T16:45:00Z" }, "schema": { "$ref": "#/components/schemas/OverlayResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Edit an overlay", "tags": [ "Overlays" ] }, "summary": "Get Overlay; Edit an overlay; Deprecate an overlay" }, "/apis/{vendor}/{name}/{version}/overlays/{overlay_id}:confirm": { "description": "`POST`: Confirm an overlay and apply it to the served spec.", "post": { "description": "Apply a pending overlay, producing a new current revision of the API.\n\nThe base spec is re-imported with the overlay applied and the result is\npromoted to the API's current revision, so it is what the API now serves.\nThe overlay becomes `confirmed`. Confirming an already-applied overlay is\na no-op that returns it unchanged; a deprecated overlay is refused with\n409 (`overlay_conflict`), and an overlay whose actions cannot be applied\nwith 409 (`overlay_apply_conflict`).\n\nRequires `overlays:confirm` (implied by `org:admin`): contributors submit\noverlays with `apis:write`, and an operator reviews and confirms them.\nAgents cannot grant themselves this permission. Returns the overlay.", "operationId": "confirmOverlay", "parameters": [ { "description": "Vendor of the API.", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "path", "name": "vendor", "required": true, "schema": { "description": "Vendor of the API.", "examples": [ "stripe.com" ], "title": "Vendor", "type": "string" } }, { "description": "Name of the API.", "examples": { "example": { "summary": "API name", "value": "stripe" } }, "in": "path", "name": "name", "required": true, "schema": { "description": "Name of the API.", "examples": [ "stripe" ], "title": "Name", "type": "string" } }, { "description": "Version of the API.", "examples": { "example": { "summary": "API version", "value": "2024-04-10" } }, "in": "path", "name": "version", "required": true, "schema": { "description": "Version of the API.", "examples": [ "2024-04-10" ], "title": "Version", "type": "string" } }, { "description": "ID of the overlay.", "examples": { "example": { "summary": "Overlay ID", "value": "ovr_6968b398ae1c9a6e2fe6520a" } }, "in": "path", "name": "overlay_id", "required": true, "schema": { "description": "ID of the overlay.", "examples": [ "ovr_6968b398ae1c9a6e2fe6520a" ], "title": "Overlay Id", "type": "string" } } ], "requestBody": { "content": { "application/json": { "example": { "execution_id": "exec_6968b3982706c619fe73f0cf" }, "schema": { "$ref": "#/components/schemas/OverlayConfirmRequest" } } }, "description": "Payload for confirming an overlay.", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "_links": { "api": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10", "confirm": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a:confirm", "deprecate": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a", "rollback": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a:rollback", "self": "https://jentic.example.com/apis/stripe.com/stripe/2024-04-10/overlays/ovr_6968b398ae1c9a6e2fe6520a" }, "api_id": "debfc9ff-7c37-4a09-801a-575bd4963ddd", "confirmed_at": "2026-01-15T10:05:00Z", "confirmed_by_execution_id": "exec_6968b3982706c619fe73f0cf", "confirmed_revision_id": "6992059c-0abd-4d22-bd07-5287e1bf5e6a", "contributed_by": "docs-review-agent", "created_at": "2026-01-15T09:30:00Z", "created_by": "agnt_6968b3984d1c238dbe7e2e29", "deprecated_at": "2026-01-17T16:45:00Z", "deprecated_reason": "rollback", "document": { "actions": [ { "target": "$.paths['/v1/charges'].get", "update": { "summary": "List all charges, newest first" } } ], "info": { "title": "Clarify charges listing", "version": "1.0.0" }, "overlay": "1.0.0" }, "id": "ovr_6968b398ae1c9a6e2fe6520a", "status": "deprecated", "superseded_revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "target_revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c", "updated_at": "2026-01-17T16:45:00Z" }, "schema": { "$ref": "#/components/schemas/OverlayResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Confirm an overlay and apply it to the served spec", "tags": [ "Overlays" ] }, "summary": "Confirm an overlay and apply it to the served spec" }, "/apis/{vendor}/{name}/{version}/overlays/{overlay_id}:rollback": { "description": "`POST`: Roll back a confirmed overlay.", "post": { "description": "Undo a confirmed overlay by restoring the revision it replaced.\n\nThe overlay's revision is archived and the revision it superseded becomes\nthe API's current revision again, so the served spec reverts, and the\noverlay is marked `deprecated`. Requires `overlays:confirm`, like\nconfirming.\n\nPreconditions: the overlay is `confirmed`, its revision is still the\nlive one, and the revision it replaced is still restorable. Otherwise\nnothing changes and 409 is returned: `overlay_conflict`,\n`overlay_rollback_target_missing`, or `host_owned_by_other_vendor` when\nanother vendor's live API now serves one of the restored revision's\nhosts. Returns 204.", "operationId": "rollbackOverlay", "parameters": [ { "description": "Vendor of the API.", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "path", "name": "vendor", "required": true, "schema": { "description": "Vendor of the API.", "examples": [ "stripe.com" ], "title": "Vendor", "type": "string" } }, { "description": "Name of the API.", "examples": { "example": { "summary": "API name", "value": "stripe" } }, "in": "path", "name": "name", "required": true, "schema": { "description": "Name of the API.", "examples": [ "stripe" ], "title": "Name", "type": "string" } }, { "description": "Version of the API.", "examples": { "example": { "summary": "API version", "value": "2024-04-10" } }, "in": "path", "name": "version", "required": true, "schema": { "description": "Version of the API.", "examples": [ "2024-04-10" ], "title": "Version", "type": "string" } }, { "description": "ID of the overlay.", "examples": { "example": { "summary": "Overlay ID", "value": "ovr_6968b398ae1c9a6e2fe6520a" } }, "in": "path", "name": "overlay_id", "required": true, "schema": { "description": "ID of the overlay.", "examples": [ "ovr_6968b398ae1c9a6e2fe6520a" ], "title": "Overlay Id", "type": "string" } } ], "responses": { "204": { "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Roll back a confirmed overlay", "tags": [ "Overlays" ] }, "summary": "Roll back a confirmed overlay" }, "/apis/{vendor}/{name}/{version}/revisions": { "description": "`GET`: List an API's revisions.", "get": { "description": "List every revision imported for an API, newest first.\n\nEach revision gives its `state` (`draft`, `published`, `imported` or\n`archived`), whether it `is_current` (the one served), its source, spec\ndigest, operation count and lifecycle timestamps, plus links to the\nactions valid in its state. Repeat `state` to filter by several states.\nResults are cursor-paginated: pass `next_cursor` as `cursor` while\n`has_more` is true. Fetch one revision with\n`GET /apis/{vendor}/{name}/{version}/revisions/{revision_id}`.", "operationId": "listApiRevisions", "parameters": [ { "description": "Vendor of the API.", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "path", "name": "vendor", "required": true, "schema": { "description": "Vendor of the API.", "examples": [ "stripe.com" ], "title": "Vendor", "type": "string" } }, { "description": "Name of the API.", "examples": { "example": { "summary": "API name", "value": "stripe" } }, "in": "path", "name": "name", "required": true, "schema": { "description": "Name of the API.", "examples": [ "stripe" ], "title": "Name", "type": "string" } }, { "description": "Version of the API.", "examples": { "example": { "summary": "API version", "value": "2024-04-10" } }, "in": "path", "name": "version", "required": true, "schema": { "description": "Version of the API.", "examples": [ "2024-04-10" ], "title": "Version", "type": "string" } }, { "description": "Only return revisions in these states; repeat to match several.", "examples": { "example": { "summary": "Example query value for `state`", "value": [ "published" ] } }, "in": "query", "name": "state", "required": false, "schema": { "anyOf": [ { "examples": [ [ "published" ] ], "items": { "examples": [ "published" ], "type": "string" }, "type": "array" }, { "type": "null" } ], "description": "Only return revisions in these states; repeat to match several.", "examples": [ [ "published" ] ], "title": "State" } }, { "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": { "example": { "summary": "Opaque cursor from a previous page", "value": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } }, "in": "query", "name": "cursor", "required": false, "schema": { "anyOf": [ { "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "type": "string" }, { "type": "null" } ], "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Cursor" } }, { "description": "Maximum number of revisions to return (1-200).", "examples": { "example": { "summary": "Example query value for `limit`", "value": 25 } }, "in": "query", "name": "limit", "required": false, "schema": { "default": 50, "description": "Maximum number of revisions to return (1-200).", "examples": [ 25 ], "maximum": 200, "minimum": 1, "title": "Limit", "type": "integer" } } ], "responses": { "200": { "content": { "application/json": { "schema": {} } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List an API's revisions", "tags": [ "APIs" ] }, "summary": "List an API's revisions" }, "/apis/{vendor}/{name}/{version}/revisions/{revision_id}": { "delete": { "description": "Permanently delete an archived revision.\n\nOnly an `archived` revision can be deleted — archive it first; any other\nstate is refused with 409 (`revision_state_conflict`). Deletion cannot\nbe undone. Requires `apis:write`. Returns 204.", "operationId": "deleteRevision", "parameters": [ { "description": "Vendor of the API.", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "path", "name": "vendor", "required": true, "schema": { "description": "Vendor of the API.", "examples": [ "stripe.com" ], "title": "Vendor", "type": "string" } }, { "description": "Name of the API.", "examples": { "example": { "summary": "API name", "value": "stripe" } }, "in": "path", "name": "name", "required": true, "schema": { "description": "Name of the API.", "examples": [ "stripe" ], "title": "Name", "type": "string" } }, { "description": "Version of the API.", "examples": { "example": { "summary": "API version", "value": "2024-04-10" } }, "in": "path", "name": "version", "required": true, "schema": { "description": "Version of the API.", "examples": [ "2024-04-10" ], "title": "Version", "type": "string" } }, { "description": "ID of the API revision.", "examples": { "example": { "summary": "Revision ID (UUID)", "value": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" } }, "in": "path", "name": "revision_id", "required": true, "schema": { "description": "ID of the API revision.", "examples": [ "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" ], "title": "Revision Id", "type": "string" } } ], "responses": { "204": { "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Delete an archived API revision", "tags": [ "APIs" ] }, "description": "`GET`: Get an API revision. `DELETE`: Delete an archived API revision.", "get": { "description": "Get one revision's metadata and lifecycle state.\n\nReturns the same fields as an entry in the revision list: `state`,\n`is_current`, source, spec digest, operation count, timestamps, and links\nto the actions valid in its state. This is metadata only — download the\nspec itself from `.../revisions/{revision_id}/openapi`. 404 if the API or\nrevision does not exist.", "operationId": "getApiRevision", "parameters": [ { "description": "Vendor of the API.", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "path", "name": "vendor", "required": true, "schema": { "description": "Vendor of the API.", "examples": [ "stripe.com" ], "title": "Vendor", "type": "string" } }, { "description": "Name of the API.", "examples": { "example": { "summary": "API name", "value": "stripe" } }, "in": "path", "name": "name", "required": true, "schema": { "description": "Name of the API.", "examples": [ "stripe" ], "title": "Name", "type": "string" } }, { "description": "Version of the API.", "examples": { "example": { "summary": "API version", "value": "2024-04-10" } }, "in": "path", "name": "version", "required": true, "schema": { "description": "Version of the API.", "examples": [ "2024-04-10" ], "title": "Version", "type": "string" } }, { "description": "ID of the API revision.", "examples": { "example": { "summary": "Revision ID (UUID)", "value": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" } }, "in": "path", "name": "revision_id", "required": true, "schema": { "description": "ID of the API revision.", "examples": [ "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" ], "title": "Revision Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "schema": {} } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get an API revision", "tags": [ "APIs" ] }, "summary": "Get an API revision; Delete an archived API revision" }, "/apis/{vendor}/{name}/{version}/revisions/{revision_id}/openapi": { "description": "`GET`: Download an API revision's OpenAPI document.", "get": { "description": "Download the stored OpenAPI document of one revision.\n\nChoose the format with `Accept`: `application/json` (the default), or\n`application/openapi+yaml` / `application/yaml`; anything else returns\n406. The response carries `Content-Disposition: attachment` with a\n`.json` or `.yaml` filename. The document is served exactly as stored —\na revision produced by confirming an overlay already includes it, so the\n`overlays` flag currently has no effect.", "operationId": "getApiRevisionSpec", "parameters": [ { "description": "Vendor of the API.", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "path", "name": "vendor", "required": true, "schema": { "description": "Vendor of the API.", "examples": [ "stripe.com" ], "title": "Vendor", "type": "string" } }, { "description": "Name of the API.", "examples": { "example": { "summary": "API name", "value": "stripe" } }, "in": "path", "name": "name", "required": true, "schema": { "description": "Name of the API.", "examples": [ "stripe" ], "title": "Name", "type": "string" } }, { "description": "Version of the API.", "examples": { "example": { "summary": "API version", "value": "2024-04-10" } }, "in": "path", "name": "version", "required": true, "schema": { "description": "Version of the API.", "examples": [ "2024-04-10" ], "title": "Version", "type": "string" } }, { "description": "ID of the API revision.", "examples": { "example": { "summary": "Revision ID (UUID)", "value": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" } }, "in": "path", "name": "revision_id", "required": true, "schema": { "description": "ID of the API revision.", "examples": [ "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" ], "title": "Revision Id", "type": "string" } }, { "description": "Reserved for applying overlays at read time; currently has no effect, as confirmed overlays are already part of the stored document.", "examples": { "example": { "summary": "Example query value for `overlays`", "value": false } }, "in": "query", "name": "overlays", "required": false, "schema": { "default": true, "description": "Reserved for applying overlays at read time; currently has no effect, as confirmed overlays are already part of the stored document.", "examples": [ false ], "title": "Overlays", "type": "boolean" } } ], "responses": { "200": { "content": { "application/json": { "schema": {} } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Download an API revision's OpenAPI document", "tags": [ "API Spec" ] }, "summary": "Download an API revision's OpenAPI document" }, "/apis/{vendor}/{name}/{version}/revisions/{revision_id}/operations": { "description": "`GET`: List the operations in an API revision.", "get": { "description": "List every operation in one specific revision, live or not.\n\nSame rows, ordering and cursor pagination as the live-revision listing,\nbut for the named revision, so you can review a draft before promoting\nit or compare against an archived one. Follow each row's `inspect` link\nfor full detail. 404 if the API or revision does not exist.", "operationId": "listApiRevisionOperations", "parameters": [ { "description": "Vendor of the API.", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "path", "name": "vendor", "required": true, "schema": { "description": "Vendor of the API.", "examples": [ "stripe.com" ], "title": "Vendor", "type": "string" } }, { "description": "Name of the API.", "examples": { "example": { "summary": "API name", "value": "stripe" } }, "in": "path", "name": "name", "required": true, "schema": { "description": "Name of the API.", "examples": [ "stripe" ], "title": "Name", "type": "string" } }, { "description": "Version of the API.", "examples": { "example": { "summary": "API version", "value": "2024-04-10" } }, "in": "path", "name": "version", "required": true, "schema": { "description": "Version of the API.", "examples": [ "2024-04-10" ], "title": "Version", "type": "string" } }, { "description": "ID of the API revision.", "examples": { "example": { "summary": "Revision ID (UUID)", "value": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" } }, "in": "path", "name": "revision_id", "required": true, "schema": { "description": "ID of the API revision.", "examples": [ "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" ], "title": "Revision Id", "type": "string" } }, { "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": { "example": { "summary": "Opaque cursor from a previous page", "value": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } }, "in": "query", "name": "cursor", "required": false, "schema": { "anyOf": [ { "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "type": "string" }, { "type": "null" } ], "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Cursor" } }, { "description": "Maximum number of operations to return (1-200).", "examples": { "example": { "summary": "Example query value for `limit`", "value": 25 } }, "in": "query", "name": "limit", "required": false, "schema": { "default": 50, "description": "Maximum number of operations to return (1-200).", "examples": [ 25 ], "maximum": 200, "minimum": 1, "title": "Limit", "type": "integer" } } ], "responses": { "200": { "content": { "application/json": { "schema": {} } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List the operations in an API revision", "tags": [ "API Operations" ] }, "summary": "List the operations in an API revision" }, "/apis/{vendor}/{name}/{version}/revisions/{revision_id}:archive": { "description": "`POST`: Archive an API revision.", "post": { "description": "Retire a `draft` or `imported` revision without deleting it.\n\nThe revision moves to `archived` and is kept for reference; it can then\nbe deleted. If it was the API's current revision, the API is left with\nno live revision until another is promoted. A revision in any other\nstate is refused with 409 (`revision_state_conflict`). Requires\n`apis:write`. Returns the archived revision.", "operationId": "archiveRevision", "parameters": [ { "description": "Vendor of the API.", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "path", "name": "vendor", "required": true, "schema": { "description": "Vendor of the API.", "examples": [ "stripe.com" ], "title": "Vendor", "type": "string" } }, { "description": "Name of the API.", "examples": { "example": { "summary": "API name", "value": "stripe" } }, "in": "path", "name": "name", "required": true, "schema": { "description": "Name of the API.", "examples": [ "stripe" ], "title": "Name", "type": "string" } }, { "description": "Version of the API.", "examples": { "example": { "summary": "API version", "value": "2024-04-10" } }, "in": "path", "name": "version", "required": true, "schema": { "description": "Version of the API.", "examples": [ "2024-04-10" ], "title": "Version", "type": "string" } }, { "description": "ID of the API revision.", "examples": { "example": { "summary": "Revision ID (UUID)", "value": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" } }, "in": "path", "name": "revision_id", "required": true, "schema": { "description": "ID of the API revision.", "examples": [ "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" ], "title": "Revision Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "schema": {} } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Archive an API revision", "tags": [ "APIs" ] }, "summary": "Archive an API revision" }, "/apis/{vendor}/{name}/{version}/revisions/{revision_id}:promote": { "description": "`POST`: Promote Revision.", "post": { "description": "Promote a draft revision to published, archiving the current one.\n\nIf the draft declares different server hosts than the API's current (or last\nlive) revision, or serves a host over plaintext http that was https-only, and\nthe API has credentials bound to agents, the caller also needs\n``credentials:write``; otherwise the promote is refused with 403\n``host_change_requires_operator``.", "operationId": "promoteRevision", "parameters": [ { "description": "Vendor of the API.", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "path", "name": "vendor", "required": true, "schema": { "description": "Vendor of the API.", "examples": [ "stripe.com" ], "title": "Vendor", "type": "string" } }, { "description": "Name of the API.", "examples": { "example": { "summary": "API name", "value": "stripe" } }, "in": "path", "name": "name", "required": true, "schema": { "description": "Name of the API.", "examples": [ "stripe" ], "title": "Name", "type": "string" } }, { "description": "Version of the API.", "examples": { "example": { "summary": "API version", "value": "2024-04-10" } }, "in": "path", "name": "version", "required": true, "schema": { "description": "Version of the API.", "examples": [ "2024-04-10" ], "title": "Version", "type": "string" } }, { "description": "ID of the API revision.", "examples": { "example": { "summary": "Revision ID (UUID)", "value": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" } }, "in": "path", "name": "revision_id", "required": true, "schema": { "description": "ID of the API revision.", "examples": [ "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" ], "title": "Revision Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "schema": {} } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Promote Revision", "tags": [ "APIs" ] }, "summary": "Promote Revision" }, "/apis/{vendor}/{name}/{version}/security-schemes": { "description": "`GET`: List security schemes for an API.", "get": { "description": "List security schemes (with OAuth2 flow URLs) for the API's current revision.", "operationId": "listApiSecuritySchemes", "parameters": [ { "description": "Vendor of the API.", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "path", "name": "vendor", "required": true, "schema": { "description": "Vendor of the API.", "examples": [ "stripe.com" ], "title": "Vendor", "type": "string" } }, { "description": "Name of the API.", "examples": { "example": { "summary": "API name", "value": "stripe" } }, "in": "path", "name": "name", "required": true, "schema": { "description": "Name of the API.", "examples": [ "stripe" ], "title": "Name", "type": "string" } }, { "description": "Version of the API.", "examples": { "example": { "summary": "API version", "value": "2024-04-10" } }, "in": "path", "name": "version", "required": true, "schema": { "description": "Version of the API.", "examples": [ "2024-04-10" ], "title": "Version", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "bearer_format": "JWT", "description": "Use your secret API key as the bearer token.", "flows": [ { "authorization_url": "https://connect.stripe.com/oauth/authorize", "flow_type": "authorizationCode", "refresh_url": "https://connect.stripe.com/oauth/token", "scopes": { "read_only": "Read-only access", "read_write": "Read and write access" }, "token_url": "https://connect.stripe.com/oauth/token" } ], "in_location": "header", "name": "bearerAuth", "open_id_connect_url": "https://accounts.example.com/.well-known/openid-configuration", "param_name": "X-API-Key", "scheme": "bearer", "type": "http" } ] }, "schema": { "$ref": "#/components/schemas/SecuritySchemeListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List security schemes for an API", "tags": [ "APIs" ] }, "summary": "List security schemes for an API" }, "/audit": { "description": "`GET`: List Audit Entries.", "get": { "description": "List audit entries with optional filters.\n\nScoped to the caller: their own entries plus those made by agents they own.\nOrg admins see every entry.", "operationId": "listAuditEntries", "parameters": [ { "description": "Only return entries for this target type; must be sent together with `target_id`.", "examples": { "example": { "summary": "Example query value for `target_type`", "value": "agent" } }, "in": "query", "name": "target_type", "required": false, "schema": { "anyOf": [ { "$ref": "#/components/schemas/AuditTargetType" }, { "type": "null" } ], "description": "Only return entries for this target type; must be sent together with `target_id`.", "examples": [ "agent" ], "title": "Target Type" } }, { "description": "Only return entries for this target ID; must be sent together with `target_type`.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "query", "name": "target_id", "required": false, "schema": { "anyOf": [ { "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "type": "string" }, { "type": "null" } ], "description": "Only return entries for this target ID; must be sent together with `target_type`.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Target Id" } }, { "description": "Only return entries made by this actor.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "query", "name": "actor_id", "required": false, "schema": { "anyOf": [ { "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "type": "string" }, { "type": "null" } ], "description": "Only return entries made by this actor.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Actor Id" } }, { "description": "Only return entries initiated from this surface, e.g. `dashboard` or `cli`.", "examples": { "example": { "summary": "Example query value for `origin`", "value": "dashboard" } }, "in": "query", "name": "origin", "required": false, "schema": { "anyOf": [ { "examples": [ "dashboard" ], "type": "string" }, { "type": "null" } ], "description": "Only return entries initiated from this surface, e.g. `dashboard` or `cli`.", "examples": [ "dashboard" ], "title": "Origin" } }, { "description": "Only return entries that occurred at or after this time (RFC 3339).", "examples": { "example": { "summary": "Start of a time window (RFC 3339)", "value": "2026-01-01T00:00:00Z" } }, "in": "query", "name": "since", "required": false, "schema": { "anyOf": [ { "examples": [ "2026-01-01T00:00:00Z" ], "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "Only return entries that occurred at or after this time (RFC 3339).", "examples": [ "2026-01-01T00:00:00Z" ], "title": "Since" } }, { "description": "Only return entries that occurred at or before this time (RFC 3339).", "examples": { "example": { "summary": "End of a time window (RFC 3339)", "value": "2026-01-31T23:59:59Z" } }, "in": "query", "name": "until", "required": false, "schema": { "anyOf": [ { "examples": [ "2026-01-31T23:59:59Z" ], "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "Only return entries that occurred at or before this time (RFC 3339).", "examples": [ "2026-01-31T23:59:59Z" ], "title": "Until" } }, { "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": { "example": { "summary": "Opaque cursor from a previous page", "value": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } }, "in": "query", "name": "cursor", "required": false, "schema": { "anyOf": [ { "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "type": "string" }, { "type": "null" } ], "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Cursor" } }, { "description": "Maximum number of entries to return (1-200, default 50).", "examples": { "example": { "summary": "Example query value for `limit`", "value": 25 } }, "in": "query", "name": "limit", "required": false, "schema": { "default": 50, "description": "Maximum number of entries to return (1-200, default 50).", "examples": [ 25 ], "maximum": 200, "minimum": 1, "title": "Limit", "type": "integer" } } ], "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "action": "update", "actor_id": "usr_6968b3987ee4c3ec0b4ee3b9", "actor_session_id": "5f0c2a9e-3b7d-4c1a-9e8f-2d6b4a1c7e30", "actor_type": "user", "after": { "active": true, "name": "Stripe production key" }, "before": { "active": true, "name": "Stripe test key" }, "diff": { "added": {}, "modified": { "name": { "new": "Stripe production key", "old": "Stripe test key" } }, "removed": {} }, "id": "aud_6968b3984275d71e90f7f09f", "ip_address": "203.0.113.42", "job_id": "job_6968b3985e8c9902207afaeb", "occurred_at": "2026-01-15T09:30:00Z", "origin": "dashboard", "reason": "Rotated to the production key", "request_id": "req_6968b3984d1c238d", "target_id": "cred_6968b39855d91a3561684b32", "target_parent_id": "agnt_6968b3984d1c238dbe7e2e29", "target_type": "credential", "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_5) AppleWebKit/605.1.15" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" }, "schema": { "$ref": "#/components/schemas/AuditListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List Audit Entries", "tags": [ "Audit" ] }, "summary": "List Audit Entries" }, "/audit/{audit_id}": { "description": "`GET`: Get Audit Entry.", "get": { "description": "Get a single audit entry by ID.", "operationId": "getAuditEntry", "parameters": [ { "description": "ID of the audit entry.", "examples": { "example": { "summary": "Audit entry ID", "value": "aud_6968b3984275d71e90f7f09f" } }, "in": "path", "name": "audit_id", "required": true, "schema": { "description": "ID of the audit entry.", "examples": [ "aud_6968b3984275d71e90f7f09f" ], "title": "Audit Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "action": "update", "actor_id": "usr_6968b3987ee4c3ec0b4ee3b9", "actor_session_id": "5f0c2a9e-3b7d-4c1a-9e8f-2d6b4a1c7e30", "actor_type": "user", "after": { "active": true, "name": "Stripe production key" }, "before": { "active": true, "name": "Stripe test key" }, "diff": { "added": {}, "modified": { "name": { "new": "Stripe production key", "old": "Stripe test key" } }, "removed": {} }, "id": "aud_6968b3984275d71e90f7f09f", "ip_address": "203.0.113.42", "job_id": "job_6968b3985e8c9902207afaeb", "occurred_at": "2026-01-15T09:30:00Z", "origin": "dashboard", "reason": "Rotated to the production key", "request_id": "req_6968b3984d1c238d", "target_id": "cred_6968b39855d91a3561684b32", "target_parent_id": "agnt_6968b3984d1c238dbe7e2e29", "target_type": "credential", "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_5) AppleWebKit/605.1.15" }, "schema": { "$ref": "#/components/schemas/AuditResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get Audit Entry", "tags": [ "Audit" ] }, "summary": "Get Audit Entry" }, "/auth/idp": { "description": "`GET`: External IdP login descriptor.", "get": { "description": "Public capability hint: whether IdP login is enabled, and which provider.\n\nThe SPA reads this before login to decide whether to show a \"Continue with\n\" button. Unauthenticated and secret-free — it advertises only the\nenabled flag and the provider name (never client secrets or endpoints).", "operationId": "authIdpDescriptor", "responses": { "200": { "content": { "application/json": { "schema": { "additionalProperties": true, "title": "Response Authidpdescriptor", "type": "object" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [], "summary": "External IdP login descriptor", "tags": [ "Discovery" ] }, "summary": "External IdP login descriptor" }, "/auth/login": { "description": "`POST`: Log in.", "post": { "description": "Authenticate and return a JWT token bundle.", "operationId": "login", "requestBody": { "content": { "application/json": { "example": { "email": "ada@example.com", "password": "example-password" }, "schema": { "$ref": "#/components/schemas/LoginRequest" } } }, "description": "Credentials for login.", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "access_token": "example-access-token", "expires_in": 3600, "must_change_password": false, "token_type": "bearer" }, "schema": { "$ref": "#/components/schemas/LoginResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [], "summary": "Log in", "tags": [ "Users" ] }, "summary": "Log in" }, "/auth/refresh": { "description": "`POST`: Refresh session token.", "post": { "description": "Re-mint the caller's login JWT before it expires (sliding session).\n\nOnly user login JWTs are refreshable; permissions and the\n``must_change_password`` gate are re-read from the database at re-mint.\nRefusal modes: 401 ``session_expired`` once the original authentication is\nolder than the absolute window (``admin.auth.session_ttl_seconds``), 401\n``invalid_credentials`` for deactivated users, non-user tokens, or opaque\n(non-JWT) credentials. Clients should then send the user back to login.", "operationId": "refreshSession", "responses": { "200": { "content": { "application/json": { "example": { "access_token": "example-access-token", "expires_in": 3600, "must_change_password": false, "token_type": "bearer" }, "schema": { "$ref": "#/components/schemas/LoginResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Refresh session token", "tags": [ "Users" ] }, "summary": "Refresh session token" }, "/catalog": { "description": "`GET`: List Catalog.", "get": { "description": "List a keyset page of browsable catalog entries (search/filter aware).\n\nThe catalog holds thousands of entries, so this is cursor-paginated like\n``GET /apis``: follow ``next_cursor`` until ``has_more`` is false.\n``catalog_total``/``registered_count``/``outdated_count`` count the whole\nmanifest, not the page, so the Discover status row stays stable while scrolling.", "operationId": "listCatalog", "parameters": [ { "description": "Search text matched against entry IDs; results are ranked by match quality.", "examples": { "example": { "summary": "Example query value for `q`", "value": "charges" } }, "in": "query", "name": "q", "required": false, "schema": { "anyOf": [ { "examples": [ "charges" ], "maxLength": 500, "type": "string" }, { "type": "null" } ], "description": "Search text matched against entry IDs; results are ranked by match quality.", "examples": [ "charges" ], "title": "Q" } }, { "description": "Only return entries already imported into the registry.", "examples": { "example": { "summary": "Example query value for `registered_only`", "value": true } }, "in": "query", "name": "registered_only", "required": false, "schema": { "default": false, "description": "Only return entries already imported into the registry.", "examples": [ true ], "title": "Registered Only", "type": "boolean" } }, { "description": "Only return entries not yet imported; cannot be combined with `registered_only` or `outdated_only`.", "examples": { "example": { "summary": "Example query value for `unregistered_only`", "value": false } }, "in": "query", "name": "unregistered_only", "required": false, "schema": { "default": false, "description": "Only return entries not yet imported; cannot be combined with `registered_only` or `outdated_only`.", "examples": [ false ], "title": "Unregistered Only", "type": "boolean" } }, { "description": "Only return imported entries with an upstream update available.", "examples": { "example": { "summary": "Example query value for `outdated_only`", "value": true } }, "in": "query", "name": "outdated_only", "required": false, "schema": { "default": false, "description": "Only return imported entries with an upstream update available.", "examples": [ true ], "title": "Outdated Only", "type": "boolean" } }, { "description": "Treat entries whose update notification is snoozed as outdated.", "examples": { "example": { "summary": "Example query value for `include_snoozed`", "value": true } }, "in": "query", "name": "include_snoozed", "required": false, "schema": { "default": false, "description": "Treat entries whose update notification is snoozed as outdated.", "examples": [ true ], "title": "Include Snoozed", "type": "boolean" } }, { "description": "Opaque cursor from a previous page's `next_cursor`; keep the other filters unchanged while paging.", "examples": { "example": { "summary": "Opaque cursor from a previous page", "value": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } }, "in": "query", "name": "cursor", "required": false, "schema": { "anyOf": [ { "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "type": "string" }, { "type": "null" } ], "description": "Opaque cursor from a previous page's `next_cursor`; keep the other filters unchanged while paging.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Cursor" } }, { "description": "Maximum number of entries to return (1-200).", "examples": { "example": { "summary": "Example query value for `limit`", "value": 25 } }, "in": "query", "name": "limit", "required": false, "schema": { "default": 50, "description": "Maximum number of entries to return (1-200).", "examples": [ 25 ], "maximum": 200, "minimum": 1, "title": "Limit", "type": "integer" } } ], "responses": { "200": { "content": { "application/json": { "example": { "catalog_total": 5231, "data": [], "has_more": true, "manifest_age_seconds": 3600, "next_cursor": "eyJpZCI6ICJzdHJpcGUuY29tIn0=", "registered_count": 12 }, "schema": { "$ref": "#/components/schemas/CatalogListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List Catalog", "tags": [ "Catalog" ] }, "summary": "List Catalog" }, "/catalog/{api_id}": { "description": "`GET`: Get Catalog Entry.", "get": { "description": "Retrieve a single catalog entry by api_id.", "operationId": "getCatalogEntry", "parameters": [ { "description": "Catalog identity of the API (`domain[/sub-api]`); send any `/` unencoded.", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "path", "name": "api_id", "required": true, "schema": { "description": "Catalog identity of the API (`domain[/sub-api]`); send any `/` unencoded.", "examples": [ "stripe.com" ], "title": "Api Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "_links": { "import": "/catalog/stripe.com:import", "operations": "/catalog/stripe.com/operations", "self": "/catalog/stripe.com" }, "api_id": "stripe.com", "path": "apis/openapi/stripe.com", "registered": false, "spec_url": "https://raw.githubusercontent.com/jentic/jentic-public-apis/main/apis/openapi/stripe.com/main/2024-01-01/openapi.json", "vendor": "stripe.com" }, "schema": { "$ref": "#/components/schemas/CatalogEntryResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get Catalog Entry", "tags": [ "Catalog" ] }, "summary": "Get Catalog Entry" }, "/catalog/{api_id}/operations": { "description": "`GET`: Preview Catalog Operations.", "get": { "description": "Preview the operations of a catalog entry's spec (capped, offset-paginated).\n\n``tag`` and ``q`` filter the spec's operations server-side before windowing,\nso the UI's search box covers every operation in the spec and pages the\nfiltered set via ``offset``/``limit`` (\"Load more\").", "operationId": "previewCatalogOperations", "parameters": [ { "description": "Catalog identity of the API (`domain[/sub-api]`); send any `/` unencoded.", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "path", "name": "api_id", "required": true, "schema": { "description": "Catalog identity of the API (`domain[/sub-api]`); send any `/` unencoded.", "examples": [ "stripe.com" ], "title": "Api Id", "type": "string" } }, { "description": "Number of matching operations to skip.", "examples": { "example": { "summary": "Example query value for `offset`", "value": 0 } }, "in": "query", "name": "offset", "required": false, "schema": { "default": 0, "description": "Number of matching operations to skip.", "examples": [ 0 ], "minimum": 0, "title": "Offset", "type": "integer" } }, { "description": "Maximum number of operations to return (0-200).", "examples": { "example": { "summary": "Example query value for `limit`", "value": 25 } }, "in": "query", "name": "limit", "required": false, "schema": { "default": 200, "description": "Maximum number of operations to return (0-200).", "examples": [ 25 ], "maximum": 200, "minimum": 0, "title": "Limit", "type": "integer" } }, { "description": "Only return operations with a tag containing this text (case-insensitive).", "examples": { "example": { "summary": "Example query value for `tag`", "value": "Charges" } }, "in": "query", "name": "tag", "required": false, "schema": { "anyOf": [ { "examples": [ "Charges" ], "type": "string" }, { "type": "null" } ], "description": "Only return operations with a tag containing this text (case-insensitive).", "examples": [ "Charges" ], "title": "Tag" } }, { "description": "Only return operations whose method, path, summary or operation ID contains this text (case-insensitive).", "examples": { "example": { "summary": "Example query value for `q`", "value": "charges" } }, "in": "query", "name": "q", "required": false, "schema": { "anyOf": [ { "examples": [ "charges" ], "maxLength": 500, "type": "string" }, { "type": "null" } ], "description": "Only return operations whose method, path, summary or operation ID contains this text (case-insensitive).", "examples": [ "charges" ], "title": "Q" } } ], "responses": { "200": { "content": { "application/json": { "example": { "data": [], "info": { "description": "Payments.", "title": "Stripe", "version": "2024-01-01" }, "offset": 0, "security_schemes": {}, "total": 42, "truncated": true }, "schema": { "$ref": "#/components/schemas/OperationPreviewListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Preview Catalog Operations", "tags": [ "Catalog" ] }, "summary": "Preview Catalog Operations" }, "/catalog/{api_id}:import": { "description": "`POST`: Import Catalog Entry.", "post": { "description": "Enqueue an async import of a catalog entry into the local registry.", "operationId": "importCatalogEntry", "parameters": [ { "description": "Catalog identity of the API (`domain[/sub-api]`); send any `/` unencoded.", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "path", "name": "api_id", "required": true, "schema": { "description": "Catalog identity of the API (`domain[/sub-api]`); send any `/` unencoded.", "examples": [ "stripe.com" ], "title": "Api Id", "type": "string" } } ], "responses": { "202": { "content": { "application/json": { "example": { "_links": { "self": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb" }, "job_id": "job_6968b3985e8c9902207afaeb", "status": "queued" }, "schema": { "$ref": "#/components/schemas/ApiImportResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Import Catalog Entry", "tags": [ "Catalog" ] }, "summary": "Import Catalog Entry" }, "/catalog/{api_id}:snooze": { "description": "`POST`: Snooze Catalog Entry.", "post": { "description": "Snooze the outstanding update notification for a catalog entry (C1, #925).\n\nOperator action (``events:write``): quiet the \"update available\" badge for a\nknown-and-accepted upstream change without adopting it. Body is optional — omit or send\n``{\"snoozed_until\": null}`` to mute until a newer upstream digest lands (the primary\nper-API affordance); send an ISO-8601 ``snoozed_until`` for a time-boxed snooze. A\ngenuinely newer upstream change re-lights the badge automatically.", "operationId": "snoozeCatalogEntry", "parameters": [ { "description": "Catalog identity of the API (`domain[/sub-api]`); send any `/` unencoded.", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "path", "name": "api_id", "required": true, "schema": { "description": "Catalog identity of the API (`domain[/sub-api]`); send any `/` unencoded.", "examples": [ "stripe.com" ], "title": "Api Id", "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "anyOf": [ { "$ref": "#/components/schemas/CatalogSnoozeRequest" }, { "type": "null" } ], "title": "Body" } } }, "description": "Request payload for the `snoozeCatalogEntry` operation." }, "responses": { "204": { "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "409": { "content": { "application/problem+json": { "example": { "detail": "The request conflicts with the current state of the resource.", "instance": "/example/path", "status": 409, "title": "Conflict", "type": "conflict" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "The catalog entry has no outstanding update to snooze." }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Snooze Catalog Entry", "tags": [ "Catalog" ] }, "summary": "Snooze Catalog Entry" }, "/catalog/{api_id}:unsnooze": { "description": "`POST`: Unsnooze Catalog Entry.", "post": { "description": "Clear a snooze for a catalog entry (C1). Operator action (``events:write``).", "operationId": "unsnoozeCatalogEntry", "parameters": [ { "description": "Catalog identity of the API (`domain[/sub-api]`); send any `/` unencoded.", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "path", "name": "api_id", "required": true, "schema": { "description": "Catalog identity of the API (`domain[/sub-api]`); send any `/` unencoded.", "examples": [ "stripe.com" ], "title": "Api Id", "type": "string" } } ], "responses": { "204": { "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Unsnooze Catalog Entry", "tags": [ "Catalog" ] }, "summary": "Unsnooze Catalog Entry" }, "/catalog:refresh": { "description": "`POST`: Refresh Catalog.", "post": { "description": "Force a refresh of the catalog cache from the upstream manifest (org:admin).", "operationId": "refreshCatalog", "responses": { "200": { "content": { "application/json": { "example": { "count": 5231, "status": "refreshed" }, "schema": { "$ref": "#/components/schemas/CatalogRefreshResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Refresh Catalog", "tags": [ "Catalog" ] }, "summary": "Refresh Catalog" }, "/connect-sessions": { "description": "`GET`: List connect sessions.", "get": { "description": "List connect sessions with cursor-based pagination.\n\nRows are slim summaries scoped to the caller (initiator-owned;\n``org:admin`` sees all; a delegated agent holding\n``owner:credentials:read`` also sees its owner's sessions). The\n``poll_token`` capability is never included.", "operationId": "listConnectSessions", "parameters": [ { "description": "Filter by session state", "examples": { "example": { "summary": "Example query value for `state`", "value": "polling" } }, "in": "query", "name": "state", "required": false, "schema": { "anyOf": [ { "enum": [ "created", "awaiting_app", "polling", "connected" ], "examples": [ "polling" ], "type": "string" }, { "type": "null" } ], "description": "Filter by session state", "examples": [ "polling" ], "title": "State" } }, { "description": "Filter by vendor registry key", "examples": { "example": { "summary": "Vendor registry key", "value": "github" } }, "in": "query", "name": "vendor", "required": false, "schema": { "anyOf": [ { "examples": [ "github" ], "type": "string" }, { "type": "null" } ], "description": "Filter by vendor registry key", "examples": [ "github" ], "title": "Vendor" } }, { "description": "Opaque cursor from a previous page's next_cursor; omit for the first page.", "examples": { "example": { "summary": "Opaque cursor from a previous page", "value": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } }, "in": "query", "name": "cursor", "required": false, "schema": { "anyOf": [ { "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "type": "string" }, { "type": "null" } ], "description": "Opaque cursor from a previous page's next_cursor; omit for the first page.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Cursor" } }, { "description": "Maximum number of sessions to return (1-200, default 50).", "examples": { "example": { "summary": "Example query value for `limit`", "value": 25 } }, "in": "query", "name": "limit", "required": false, "schema": { "default": 50, "description": "Maximum number of sessions to return (1-200, default 50).", "examples": [ 25 ], "maximum": 200, "minimum": 1, "title": "Limit", "type": "integer" } } ], "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "connected_as": "octocat", "created_at": "2026-01-15T09:30:00Z", "credential_id": "cred_6968b39855d91a3561684b32", "error_code": "access_denied", "reason": "Needs read access to triage issues in the platform repo.", "requested_by_actor_id": "agnt_6968b3984d1c238dbe7e2e29", "session_id": "cs_6968b3983b8b91c75627bee5", "state": "connected", "vendor_display_name": "GitHub", "vendor_key": "github" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" }, "schema": { "$ref": "#/components/schemas/ConnectSessionListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List connect sessions", "tags": [ "Integrations" ] }, "summary": "List connect sessions" }, "/connect-sessions/{session_id}": { "description": "`GET`: Get review data for a connect session.", "get": { "description": "Data the review page needs: vendor display name, resolved flow, the\nscope catalog flagged with default/requested, current state, reason.\n\nGated by the session's ``poll_token`` capability (rides the approval\nURL / the ``:connect`` response), or by being the target agent's owner\nor ``org:admin`` — ``credentials:write`` alone must not read arbitrary\nsessions' review data. Missing session, token mismatch and a caller who\nis neither all surface as 403, matching ``/status`` (no session-id\nenumeration oracle).", "operationId": "getConnectSession", "parameters": [ { "description": "ID of the connect session.", "examples": { "example": { "summary": "Connect session ID", "value": "cs_6968b3983b8b91c75627bee5" } }, "in": "path", "name": "session_id", "required": true, "schema": { "description": "ID of the connect session.", "examples": [ "cs_6968b3983b8b91c75627bee5" ], "title": "Session Id", "type": "string" } }, { "description": "Opaque poll capability returned by :connect. Optional for the target agent's owner (with credentials:write and agents:write) and org:admin. Deliberately a query parameter: it rides the approval URL a human opens in a browser, where a header cannot be set. It is a short-lived, single-session capability, not a reusable credential, and it only scopes reads/actions on that one connect session.", "examples": { "example": { "summary": "Opaque flow handle", "value": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" } }, "in": "query", "name": "poll_token", "required": false, "schema": { "anyOf": [ { "examples": [ "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" ], "type": "string" }, { "type": "null" } ], "description": "Opaque poll capability returned by :connect. Optional for the target agent's owner (with credentials:write and agents:write) and org:admin. Deliberately a query parameter: it rides the approval URL a human opens in a browser, where a header cannot be set. It is a short-lived, single-session capability, not a reusable credential, and it only scopes reads/actions on that one connect session.", "examples": [ "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" ], "title": "Poll Token" } } ], "responses": { "200": { "content": { "application/json": { "schema": {} } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "409": { "content": { "application/problem+json": { "example": { "detail": "The request conflicts with the current state of the resource.", "instance": "/example/path", "status": 409, "title": "Conflict", "type": "conflict" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "The session's OAuth app changed; start a new session" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get review data for a connect session", "tags": [ "Integrations" ] }, "summary": "Get review data for a connect session" }, "/connect-sessions/{session_id}/status": { "description": "`GET`: Poll a connect session's status.", "get": { "description": "Poll the lifecycle status of a connect session.\n\nReturns the session's current ``status`` and, once it has connected, the\nresulting ``credential_id``, the account it ``connected_as``, and the\n``bound_scopes``; a failed session carries an ``error_code``. Agents and the\nSPA poll this after ``:connect`` until the status is terminal.\n\nAuth is intentionally lightweight: the caller must be authenticated with\n``credentials:connect`` or ``credentials:write``, but the real capability\nthat scopes the response is the session's ``poll_token`` (or being the\ntarget agent's owner / ``org:admin``). An agent handed the token by\n``:connect`` can poll without full session-read rights. A missing session,\na ``poll_token`` mismatch, and a caller who is neither all answer a uniform\n403, so the endpoint is not a session-id enumeration oracle.", "operationId": "pollConnectSessionStatus", "parameters": [ { "description": "ID of the connect session.", "examples": { "example": { "summary": "Connect session ID", "value": "cs_6968b3983b8b91c75627bee5" } }, "in": "path", "name": "session_id", "required": true, "schema": { "description": "ID of the connect session.", "examples": [ "cs_6968b3983b8b91c75627bee5" ], "title": "Session Id", "type": "string" } }, { "description": "Opaque poll capability returned by :connect. Optional for the target agent's owner (with credentials:write and agents:write) and org:admin. Deliberately a query parameter: it rides the approval URL a human opens in a browser, where a header cannot be set. It is a short-lived, single-session capability, not a reusable credential, and it only scopes reads/actions on that one connect session.", "examples": { "example": { "summary": "Opaque flow handle", "value": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" } }, "in": "query", "name": "poll_token", "required": false, "schema": { "anyOf": [ { "examples": [ "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" ], "type": "string" }, { "type": "null" } ], "description": "Opaque poll capability returned by :connect. Optional for the target agent's owner (with credentials:write and agents:write) and org:admin. Deliberately a query parameter: it rides the approval URL a human opens in a browser, where a header cannot be set. It is a short-lived, single-session capability, not a reusable credential, and it only scopes reads/actions on that one connect session.", "examples": [ "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" ], "title": "Poll Token" } } ], "responses": { "200": { "content": { "application/json": { "schema": {} } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Poll a connect session's status", "tags": [ "Integrations" ] }, "summary": "Poll a connect session's status" }, "/connect-sessions/{session_id}:cancel": { "description": "`POST`: Cancel an in-flight connect session.", "post": { "description": "Terminate a still-active session at the user's request.\n\nGated like ``/status`` — the ``poll_token`` the SPA already holds, or\nthe target agent's owner / ``org:admin`` without it.\n\nA still-existing but already-terminal session is a 204 no-op — a\n\"Cancel\" click racing the poll scanner doesn't error. A session\nthat has already been cascade-deleted (unhappy-terminal path in\n``_mark_terminal``) surfaces as 403, matching ``/status`` — the\ncaller can't distinguish \"gone\" from \"your poll_token is wrong\",\nwhich is the enumeration-oracle guard. The SPA's cancel-on-unmount\nis fire-and-forget and ``.catch``es the 403, so this doesn't leak\ninto the UX.", "operationId": "cancelConnectSession", "parameters": [ { "description": "ID of the connect session.", "examples": { "example": { "summary": "Connect session ID", "value": "cs_6968b3983b8b91c75627bee5" } }, "in": "path", "name": "session_id", "required": true, "schema": { "description": "ID of the connect session.", "examples": [ "cs_6968b3983b8b91c75627bee5" ], "title": "Session Id", "type": "string" } }, { "description": "Opaque poll capability returned by :connect. Optional for the target agent's owner (with credentials:write and agents:write) and org:admin. Deliberately a query parameter: it rides the approval URL a human opens in a browser, where a header cannot be set. It is a short-lived, single-session capability, not a reusable credential, and it only scopes reads/actions on that one connect session.", "examples": { "example": { "summary": "Opaque flow handle", "value": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" } }, "in": "query", "name": "poll_token", "required": false, "schema": { "anyOf": [ { "examples": [ "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" ], "type": "string" }, { "type": "null" } ], "description": "Opaque poll capability returned by :connect. Optional for the target agent's owner (with credentials:write and agents:write) and org:admin. Deliberately a query parameter: it rides the approval URL a human opens in a browser, where a header cannot be set. It is a short-lived, single-session capability, not a reusable credential, and it only scopes reads/actions on that one connect session.", "examples": [ "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" ], "title": "Poll Token" } } ], "responses": { "204": { "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Cancel an in-flight connect session", "tags": [ "Integrations" ] }, "summary": "Cancel an in-flight connect session" }, "/connect-sessions/{session_id}:confirm": { "description": "`POST`: Confirm a connect session.", "post": { "description": "Called by the review page after the human confirms selections.\n\nThe body's ``kind`` picks the variant (no ``kind`` is the OAuth\nvariant): OAuth scopes, a secret for a ``manual_*`` session\n(``api_key`` / ``bearer`` / ``basic``), the approver's own OAuth client\nfor an ``awaiting_app`` session, or a credential the approver already\nholds (``existing_credential``, ``reauthorize``). Secrets are write-only:\nthey never appear in a response, audit entry or log.\n\nShares the ``:connect`` per-actor rate bucket — this is the endpoint\nthat actually fires the vendor's device-authorization call, and a\nfailed ``begin`` leaves the session retryable, so it must not be\nfree to hammer during a vendor incident. Gated like the review read\n(``poll_token`` or owner / ``org:admin``; 403 otherwise).", "operationId": "confirmConnectSession", "parameters": [ { "description": "ID of the connect session.", "examples": { "example": { "summary": "Connect session ID", "value": "cs_6968b3983b8b91c75627bee5" } }, "in": "path", "name": "session_id", "required": true, "schema": { "description": "ID of the connect session.", "examples": [ "cs_6968b3983b8b91c75627bee5" ], "title": "Session Id", "type": "string" } }, { "description": "Opaque poll capability returned by :connect. Optional for the target agent's owner (with credentials:write and agents:write) and org:admin. Deliberately a query parameter: it rides the approval URL a human opens in a browser, where a header cannot be set. It is a short-lived, single-session capability, not a reusable credential, and it only scopes reads/actions on that one connect session.", "examples": { "example": { "summary": "Opaque flow handle", "value": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" } }, "in": "query", "name": "poll_token", "required": false, "schema": { "anyOf": [ { "examples": [ "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" ], "type": "string" }, { "type": "null" } ], "description": "Opaque poll capability returned by :connect. Optional for the target agent's owner (with credentials:write and agents:write) and org:admin. Deliberately a query parameter: it rides the approval URL a human opens in a browser, where a header cannot be set. It is a short-lived, single-session capability, not a reusable credential, and it only scopes reads/actions on that one connect session.", "examples": [ "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" ], "title": "Poll Token" } } ], "requestBody": { "content": { "application/json": { "schema": { "description": "How to complete the session, selected by `kind`. A body without `kind` is the `oauth` variant.", "discriminator": { "mapping": { "api_key": "#/components/schemas/ApiKeyConfirmSessionRequest", "basic": "#/components/schemas/BasicConfirmSessionRequest", "bearer": "#/components/schemas/BearerConfirmSessionRequest", "existing_credential": "#/components/schemas/ExistingCredentialConfirmSessionRequest", "oauth": "#/components/schemas/OAuthConfirmSessionRequest", "own_oauth_client": "#/components/schemas/OwnOAuthClientConfirmSessionRequest", "reauthorize": "#/components/schemas/ReauthorizeConfirmSessionRequest" }, "propertyName": "kind" }, "oneOf": [ { "$ref": "#/components/schemas/OAuthConfirmSessionRequest" }, { "$ref": "#/components/schemas/ApiKeyConfirmSessionRequest" }, { "$ref": "#/components/schemas/BearerConfirmSessionRequest" }, { "$ref": "#/components/schemas/BasicConfirmSessionRequest" }, { "$ref": "#/components/schemas/OwnOAuthClientConfirmSessionRequest" }, { "$ref": "#/components/schemas/ExistingCredentialConfirmSessionRequest" }, { "$ref": "#/components/schemas/ReauthorizeConfirmSessionRequest" } ], "title": "Body" } } }, "description": "How to complete the session, selected by `kind`. A body without `kind` is the `oauth` variant.", "required": true }, "responses": { "200": { "content": { "application/json": { "schema": {} } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "409": { "content": { "application/problem+json": { "example": { "detail": "The request conflicts with the current state of the resource.", "instance": "/example/path", "status": 409, "title": "Conflict", "type": "conflict" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Session not awaiting confirmation, its OAuth app, scheme or hosts changed, or the review is stale" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Confirm a connect session", "tags": [ "Integrations" ] }, "summary": "Confirm a connect session" }, "/connect-sessions/{session_id}:reject": { "description": "`POST`: Reject an agent's connect request.", "post": { "description": "End the session as rejected — the approve dialog's explicit Reject.\n\nOnly the target agent's owner (holding ``credentials:write`` and\n``agents:write``) or ``org:admin``; there is no poll-token path and an\nagent can never reject. Everyone else gets the uniform 403. The agent's\n``/status`` then reports ``failed`` with ``error_code: rejected``, and\nits repeat ``:connect`` for the same target answers 429\n``recently_rejected`` for the rejection cooldown. Closing the dialog\nwithout rejecting makes no call; an unmount cancel stays ``cancelled``.", "operationId": "rejectConnectSession", "parameters": [ { "description": "ID of the connect session.", "examples": { "example": { "summary": "Connect session ID", "value": "cs_6968b3983b8b91c75627bee5" } }, "in": "path", "name": "session_id", "required": true, "schema": { "description": "ID of the connect session.", "examples": [ "cs_6968b3983b8b91c75627bee5" ], "title": "Session Id", "type": "string" } } ], "responses": { "204": { "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Reject an agent's connect request", "tags": [ "Integrations" ] }, "summary": "Reject an agent's connect request" }, "/credentials": { "description": "`POST`: Create credential. `GET`: List credentials.", "get": { "description": "List credentials with cursor-based pagination.", "operationId": "listCredentials", "parameters": [ { "description": "Opaque cursor from a previous page's next_cursor; omit for the first page.", "examples": { "example": { "summary": "Opaque cursor from a previous page", "value": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } }, "in": "query", "name": "cursor", "required": false, "schema": { "anyOf": [ { "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "type": "string" }, { "type": "null" } ], "description": "Opaque cursor from a previous page's next_cursor; omit for the first page.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Cursor" } }, { "description": "Maximum number of credentials to return (1-200, default 50).", "examples": { "example": { "summary": "Example query value for `limit`", "value": 25 } }, "in": "query", "name": "limit", "required": false, "schema": { "default": 50, "description": "Maximum number of credentials to return (1-200, default 50).", "examples": [ 25 ], "maximum": 200, "minimum": 1, "title": "Limit", "type": "integer" } }, { "description": "Filter to credentials for this API vendor (exact match).", "examples": { "example": { "summary": "API vendor domain", "value": "stripe.com" } }, "in": "query", "name": "vendor", "required": false, "schema": { "anyOf": [ { "examples": [ "stripe.com" ], "type": "string" }, { "type": "null" } ], "description": "Filter to credentials for this API vendor (exact match).", "examples": [ "stripe.com" ], "title": "Vendor" } } ], "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "active": true, "api": { "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "created_at": "2026-01-15T09:30:00Z", "credential_id": "cred_01HZX9...", "details": { "field_name": "Authorization", "hint": "…live_abcd", "location": "header" }, "name": "Stripe live key", "provider": "static", "type": "api_key" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" }, "schema": { "$ref": "#/components/schemas/CredentialListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List credentials", "tags": [ "Credentials" ] }, "post": { "description": "Create a new credential. The secret is returned once and never readable again.", "operationId": "createCredential", "requestBody": { "content": { "application/json": { "schema": { "discriminator": { "mapping": { "api_key": "#/components/schemas/ApiKeyCreateRequest", "basic": "#/components/schemas/BasicAuthCreateRequest", "bearer_token": "#/components/schemas/BearerTokenCreateRequest", "no_auth": "#/components/schemas/NoAuthCreateRequest", "oauth2": "#/components/schemas/OAuth2CreateRequest", "sigv4": "#/components/schemas/Sigv4CreateRequest" }, "propertyName": "type" }, "oneOf": [ { "$ref": "#/components/schemas/BearerTokenCreateRequest" }, { "$ref": "#/components/schemas/ApiKeyCreateRequest" }, { "$ref": "#/components/schemas/BasicAuthCreateRequest" }, { "$ref": "#/components/schemas/OAuth2CreateRequest" }, { "$ref": "#/components/schemas/NoAuthCreateRequest" }, { "$ref": "#/components/schemas/Sigv4CreateRequest" } ], "title": "Body" } } }, "description": "Request payload for the `createCredential` operation.", "required": true }, "responses": { "201": { "content": { "application/json": { "example": { "credential": { "active": true, "api": { "name": "stripe", "vendor": "stripe-com", "version": "2024-04-10" }, "created_at": "2026-01-15T09:30:00Z", "credential_id": "cred_01HZX9...", "name": "Stripe live key", "provider": "static", "type": "api_key" }, "secret": { "key": "sk_live_…" } }, "schema": { "$ref": "#/components/schemas/CredentialCreateResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Create credential", "tags": [ "Credentials" ] }, "summary": "Create credential; List credentials" }, "/credentials/providers": { "description": "`GET`: List credential providers.", "get": { "description": "Return discovery metadata for all configured credential providers.", "operationId": "listProviders", "responses": { "200": { "content": { "application/json": { "example": { "providers": [ { "callback_url": "https://jentic.example.com/api/v1/credentials/oauth/callback", "configured": true, "id": "pipedream", "label": "Pipedream", "managed": true, "types": [ "oauth2", "api_key" ] } ] }, "schema": { "$ref": "#/components/schemas/ProviderDiscoveryResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List credential providers", "tags": [ "Credentials" ] }, "summary": "List credential providers" }, "/credentials/{credential_id}": { "delete": { "description": "Delete a credential.", "operationId": "deleteCredential", "parameters": [ { "description": "ID of the credential.", "examples": { "example": { "summary": "Credential ID", "value": "cred_6968b39855d91a3561684b32" } }, "in": "path", "name": "credential_id", "required": true, "schema": { "description": "ID of the credential.", "examples": [ "cred_6968b39855d91a3561684b32" ], "title": "Credential Id", "type": "string" } } ], "responses": { "204": { "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Delete credential", "tags": [ "Credentials" ] }, "description": "`GET`: Get credential. `PATCH`: Update or rotate credential. `DELETE`: Delete credential.", "get": { "description": "Get a single credential with redacted secrets.", "operationId": "getCredential", "parameters": [ { "description": "ID of the credential.", "examples": { "example": { "summary": "Credential ID", "value": "cred_6968b39855d91a3561684b32" } }, "in": "path", "name": "credential_id", "required": true, "schema": { "description": "ID of the credential.", "examples": [ "cred_6968b39855d91a3561684b32" ], "title": "Credential Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "active": true, "api": { "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "created_at": "2026-01-15T09:30:00Z", "credential_id": "cred_01HZX9...", "details": { "field_name": "Authorization", "hint": "…live_abcd", "location": "header" }, "name": "Stripe live key", "provider": "static", "type": "api_key" }, "schema": { "$ref": "#/components/schemas/CredentialRedactedResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get credential", "tags": [ "Credentials" ] }, "patch": { "description": "Update or rotate a credential.", "operationId": "updateCredential", "parameters": [ { "description": "ID of the credential.", "examples": { "example": { "summary": "Credential ID", "value": "cred_6968b39855d91a3561684b32" } }, "in": "path", "name": "credential_id", "required": true, "schema": { "description": "ID of the credential.", "examples": [ "cred_6968b39855d91a3561684b32" ], "title": "Credential Id", "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "discriminator": { "mapping": { "api_key": "#/components/schemas/ApiKeyUpdateRequest", "basic": "#/components/schemas/BasicAuthUpdateRequest", "bearer_token": "#/components/schemas/BearerTokenUpdateRequest", "oauth2": "#/components/schemas/OAuth2UpdateRequest", "sigv4": "#/components/schemas/Sigv4UpdateRequest" }, "propertyName": "type" }, "oneOf": [ { "$ref": "#/components/schemas/BearerTokenUpdateRequest" }, { "$ref": "#/components/schemas/ApiKeyUpdateRequest" }, { "$ref": "#/components/schemas/BasicAuthUpdateRequest" }, { "$ref": "#/components/schemas/OAuth2UpdateRequest" }, { "$ref": "#/components/schemas/Sigv4UpdateRequest" } ], "title": "Body" } } }, "description": "Request payload for the `updateCredential` operation.", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "active": true, "api": { "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "created_at": "2026-01-15T09:30:00Z", "credential_id": "cred_01HZX9...", "details": { "field_name": "Authorization", "hint": "…live_abcd", "location": "header" }, "name": "Stripe live key", "provider": "static", "type": "api_key" }, "schema": { "$ref": "#/components/schemas/CredentialRedactedResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Update or rotate credential", "tags": [ "Credentials" ] }, "summary": "Get credential; Update or rotate credential; Delete credential" }, "/credentials/{credential_id}/agents": { "description": "`GET`: List agents bound to credential.", "get": { "description": "List agents directly bound to a credential with cursor-based pagination.\n\nThe reverse lookup for the credential-detail \"Agents\" view (theme 5\nphase 1) — the direct-binding successor of the removed\n``GET /toolkits/{id}/agents``.\nSuspended bindings are included with their flag set.", "operationId": "listCredentialAgents", "parameters": [ { "description": "ID of the credential.", "examples": { "example": { "summary": "Credential ID", "value": "cred_6968b39855d91a3561684b32" } }, "in": "path", "name": "credential_id", "required": true, "schema": { "description": "ID of the credential.", "examples": [ "cred_6968b39855d91a3561684b32" ], "title": "Credential Id", "type": "string" } }, { "description": "Opaque cursor from a previous page's next_cursor; omit for the first page.", "examples": { "example": { "summary": "Opaque cursor from a previous page", "value": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } }, "in": "query", "name": "cursor", "required": false, "schema": { "anyOf": [ { "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "type": "string" }, { "type": "null" } ], "description": "Opaque cursor from a previous page's next_cursor; omit for the first page.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Cursor" } }, { "description": "Maximum number of agents to return (1-200, default 50).", "examples": { "example": { "summary": "Example query value for `limit`", "value": 25 } }, "in": "query", "name": "limit", "required": false, "schema": { "default": 50, "description": "Maximum number of agents to return (1-200, default 50).", "examples": [ 25 ], "maximum": 200, "minimum": 1, "title": "Limit", "type": "integer" } } ], "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "agent_name": "billing-assistant", "bound_at": "2026-01-15T09:30:00Z", "rule_set_id": "prs_6968b3987c22b63e87e79f05", "status": "active", "suspended": false } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" }, "schema": { "$ref": "#/components/schemas/CredentialAgentListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List agents bound to credential", "tags": [ "Credentials" ] }, "summary": "List agents bound to credential" }, "/credentials/{credential_id}/agents/{agent_id}/permissions": { "description": "`GET`: List binding permission rules. `PUT`: Replace binding permission rules. `PATCH`: Patch binding permission rules.", "get": { "description": "List the ordered PBAC rules for a direct `(agent, credential)` binding.", "operationId": "listAgentCredentialPermissions", "parameters": [ { "description": "ID of the credential.", "examples": { "example": { "summary": "Credential ID", "value": "cred_6968b39855d91a3561684b32" } }, "in": "path", "name": "credential_id", "required": true, "schema": { "description": "ID of the credential.", "examples": [ "cred_6968b39855d91a3561684b32" ], "title": "Credential Id", "type": "string" } }, { "description": "ID of the agent bound to the credential.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the agent bound to the credential.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "_comment": "Read-only access to charges.", "_system": false, "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] }, "schema": { "$ref": "#/components/schemas/PermissionRuleListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List binding permission rules", "tags": [ "Credentials" ] }, "patch": { "description": "Additively add and/or remove permission rules on a binding.", "operationId": "patchAgentCredentialPermissions", "parameters": [ { "description": "ID of the credential.", "examples": { "example": { "summary": "Credential ID", "value": "cred_6968b39855d91a3561684b32" } }, "in": "path", "name": "credential_id", "required": true, "schema": { "description": "ID of the credential.", "examples": [ "cred_6968b39855d91a3561684b32" ], "title": "Credential Id", "type": "string" } }, { "description": "ID of the agent bound to the credential.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the agent bound to the credential.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } } ], "requestBody": { "content": { "application/json": { "example": { "add": [ { "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ], "remove": [ 0, 2 ] }, "schema": { "$ref": "#/components/schemas/PermissionsPatchRequest" } } }, "description": "Patch permission rules — add and/or remove.", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "_comment": "Read-only access to charges.", "_system": false, "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] }, "schema": { "$ref": "#/components/schemas/PermissionRuleListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Patch binding permission rules", "tags": [ "Credentials" ] }, "put": { "description": "Replace the full set of permission rules for a binding (idempotent PUT).", "operationId": "replaceAgentCredentialPermissions", "parameters": [ { "description": "ID of the credential.", "examples": { "example": { "summary": "Credential ID", "value": "cred_6968b39855d91a3561684b32" } }, "in": "path", "name": "credential_id", "required": true, "schema": { "description": "ID of the credential.", "examples": [ "cred_6968b39855d91a3561684b32" ], "title": "Credential Id", "type": "string" } }, { "description": "ID of the agent bound to the credential.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the agent bound to the credential.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "items": { "$ref": "#/components/schemas/PermissionRuleSchema" }, "maxItems": 100, "title": "Body", "type": "array" } } }, "description": "Request payload for the `replaceAgentCredentialPermissions` operation.", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "_comment": "Read-only access to charges.", "_system": false, "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] }, "schema": { "$ref": "#/components/schemas/PermissionRuleListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Replace binding permission rules", "tags": [ "Credentials" ] }, "summary": "List binding permission rules; Replace binding permission rules; Patch binding permission rules" }, "/credentials/{credential_id}/agents/{agent_id}/permissions:test": { "description": "`POST`: Dry-run permission evaluation.", "post": { "description": "Answer \"what would the broker do for this request?\" without calling upstream.\n\nUnlike the toolkit `:test` there is **no vendor pooling**: the direct\nbinding's rules are one ordered first-match-wins list, so the result is\nexactly this binding's policy. Default-deny when nothing matches.", "operationId": "testAgentCredentialPermissions", "parameters": [ { "description": "ID of the credential.", "examples": { "example": { "summary": "Credential ID", "value": "cred_6968b39855d91a3561684b32" } }, "in": "path", "name": "credential_id", "required": true, "schema": { "description": "ID of the credential.", "examples": [ "cred_6968b39855d91a3561684b32" ], "title": "Credential Id", "type": "string" } }, { "description": "ID of the agent bound to the credential.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the agent bound to the credential.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } } ], "requestBody": { "content": { "application/json": { "example": { "method": "GET", "operation_id": "listCharges", "path": "/v1/charges" }, "schema": { "$ref": "#/components/schemas/PermissionTestRequest" } } }, "description": "Request body for :test — dry-run a request shape against the binding's rules.", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "allowed": true, "credential_id": "cred_6968b39855d91a3561684b32", "effect": "allow", "is_system": false, "matched": true, "rule_index": 0 }, "schema": { "$ref": "#/components/schemas/PermissionTestResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Dry-run permission evaluation", "tags": [ "Credentials" ] }, "summary": "Dry-run permission evaluation" }, "/credentials/{credential_id}/agents/{agent_id}/rule-set": { "delete": { "description": "Detach the binding's shared rule set — its inline rules apply again.\n\nIdempotent: detaching a binding already on inline rules is a no-op 204.", "operationId": "detachAgentCredentialRuleSet", "parameters": [ { "description": "ID of the credential.", "examples": { "example": { "summary": "Credential ID", "value": "cred_6968b39855d91a3561684b32" } }, "in": "path", "name": "credential_id", "required": true, "schema": { "description": "ID of the credential.", "examples": [ "cred_6968b39855d91a3561684b32" ], "title": "Credential Id", "type": "string" } }, { "description": "ID of the agent bound to the credential.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the agent bound to the credential.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } } ], "responses": { "204": { "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Detach rule set from binding", "tags": [ "Credentials" ] }, "description": "`PUT`: Attach rule set to binding. `DELETE`: Detach rule set from binding.", "put": { "description": "Point the binding at a shared rule set (idempotent PUT).\n\nWhile attached, the set's ordered list is the binding's effective policy\nand its inline rules are dormant — `permissions:test` evaluates the set.\nThe set must exist (404 `rule_set_not_found`). The caller must be the\nset's creator or an org admin, unless the set is curated (created by an\norg admin), which any caller who may write the binding's rules can\nattach; otherwise 403 `rule_set_attach_denied`. Re-attaching the set the\nbinding already points at is a no-op.", "operationId": "attachAgentCredentialRuleSet", "parameters": [ { "description": "ID of the credential.", "examples": { "example": { "summary": "Credential ID", "value": "cred_6968b39855d91a3561684b32" } }, "in": "path", "name": "credential_id", "required": true, "schema": { "description": "ID of the credential.", "examples": [ "cred_6968b39855d91a3561684b32" ], "title": "Credential Id", "type": "string" } }, { "description": "ID of the agent bound to the credential.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the agent bound to the credential.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } } ], "requestBody": { "content": { "application/json": { "example": { "rule_set_id": "prs_6968b3987c22b63e87e79f05" }, "schema": { "$ref": "#/components/schemas/RuleSetAttachRequest" } } }, "description": "Point a direct agent↔credential binding at a shared rule set.", "required": true }, "responses": { "204": { "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Attach rule set to binding", "tags": [ "Credentials" ] }, "summary": "Attach rule set to binding; Detach rule set from binding" }, "/credentials/{credential_id}/connect": { "description": "`POST`: Begin OAuth connect flow.", "post": { "description": "Initiate the OAuth connect flow for a credential.\n\nDiscriminates on the provider's returned challenge: OAuth2\nauthorization-code providers return an ``authorize_url`` for popup\nredirect; device-flow providers return ``user_code`` /\n``verification_uri`` for the RFC 8628 human step.", "operationId": "connectCredential", "parameters": [ { "description": "ID of the credential.", "examples": { "example": { "summary": "Credential ID", "value": "cred_6968b39855d91a3561684b32" } }, "in": "path", "name": "credential_id", "required": true, "schema": { "description": "ID of the credential.", "examples": [ "cred_6968b39855d91a3561684b32" ], "title": "Credential Id", "type": "string" } } ], "requestBody": { "content": { "application/json": { "example": { "extra": { "prompt": "consent" }, "scopes": [ "read_write" ] }, "schema": { "$ref": "#/components/schemas/ConnectRequestBody" } } }, "description": "Request body for initiating a credential connect flow.", "required": true }, "responses": { "200": { "content": { "application/json": { "schema": {} } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "409": { "content": { "application/problem+json": { "example": { "detail": "The request conflicts with the current state of the resource.", "instance": "/example/path", "status": 409, "title": "Conflict", "type": "conflict" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Credential is not connectable" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Begin OAuth connect flow", "tags": [ "Credentials" ] }, "summary": "Begin OAuth connect flow" }, "/error": { "description": "`GET`: Error Page.", "get": { "description": "Minimal error endpoint for browser-facing authorization failures.", "operationId": "errorPage", "parameters": [ { "description": "Error code to display; returned as-is in the response body.", "examples": { "example": { "summary": "Example query value for `error`", "value": "access_denied" } }, "in": "query", "name": "error", "required": false, "schema": { "default": "unknown_error", "description": "Error code to display; returned as-is in the response body.", "examples": [ "access_denied" ], "title": "Error", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "schema": { "additionalProperties": { "type": "string" }, "title": "Response Errorpage", "type": "object" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [], "summary": "Error Page", "tags": [ "OAuth" ] }, "summary": "Error Page" }, "/events": { "description": "`GET`: List Events.", "get": { "description": "List events with optional filters.", "operationId": "listEvents", "parameters": [ { "description": "Only return events of one of these types; repeat the parameter for several.", "examples": { "example": { "summary": "Example query value for `event_type`", "value": [ "import.completed" ] } }, "in": "query", "name": "event_type", "required": false, "schema": { "anyOf": [ { "examples": [ [ "import.completed" ] ], "items": { "examples": [ "import.completed" ], "type": "string" }, "type": "array" }, { "type": "null" } ], "description": "Only return events of one of these types; repeat the parameter for several.", "examples": [ [ "import.completed" ] ], "title": "Event Type" } }, { "description": "Only return events with one of these severities; repeat the parameter for several.", "examples": { "example": { "summary": "Example query value for `severity`", "value": [ "warning", "error" ] } }, "in": "query", "name": "severity", "required": false, "schema": { "anyOf": [ { "examples": [ [ "warning", "error" ] ], "items": { "$ref": "#/components/schemas/EventSeverity", "examples": [ "warning" ] }, "type": "array" }, { "type": "null" } ], "description": "Only return events with one of these severities; repeat the parameter for several.", "examples": [ [ "warning", "error" ] ], "title": "Severity" } }, { "description": "Only return events whose `requires_action` flag matches.", "examples": { "example": { "summary": "Example query value for `requires_action`", "value": true } }, "in": "query", "name": "requires_action", "required": false, "schema": { "anyOf": [ { "examples": [ true ], "type": "boolean" }, { "type": "null" } ], "description": "Only return events whose `requires_action` flag matches.", "examples": [ true ], "title": "Requires Action" } }, { "description": "Only return events created at or after this time (RFC 3339).", "examples": { "example": { "summary": "Start of a time window (RFC 3339)", "value": "2026-01-01T00:00:00Z" } }, "in": "query", "name": "from", "required": false, "schema": { "anyOf": [ { "examples": [ "2026-01-01T00:00:00Z" ], "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "Only return events created at or after this time (RFC 3339).", "examples": [ "2026-01-01T00:00:00Z" ], "title": "From" } }, { "description": "Only return events created before this time (RFC 3339).", "examples": { "example": { "summary": "End of a time window (RFC 3339)", "value": "2026-01-31T23:59:59Z" } }, "in": "query", "name": "to", "required": false, "schema": { "anyOf": [ { "examples": [ "2026-01-31T23:59:59Z" ], "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "Only return events created before this time (RFC 3339).", "examples": [ "2026-01-31T23:59:59Z" ], "title": "To" } }, { "description": "Only return events with this trace ID.", "examples": { "example": { "summary": "W3C trace ID", "value": "4bf92f3577b34da6a3ce929d0e0e4736" } }, "in": "query", "name": "trace_id", "required": false, "schema": { "anyOf": [ { "examples": [ "4bf92f3577b34da6a3ce929d0e0e4736" ], "type": "string" }, { "type": "null" } ], "description": "Only return events with this trace ID.", "examples": [ "4bf92f3577b34da6a3ce929d0e0e4736" ], "title": "Trace Id" } }, { "description": "Only return events caused by this actor.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "query", "name": "actor_id", "required": false, "schema": { "anyOf": [ { "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "type": "string" }, { "type": "null" } ], "description": "Only return events caused by this actor.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Actor Id" } }, { "description": "Only return events caused by this kind of actor, e.g. `user` or `agent`.", "examples": { "example": { "summary": "Example query value for `actor_type`", "value": "agent" } }, "in": "query", "name": "actor_type", "required": false, "schema": { "anyOf": [ { "examples": [ "agent" ], "type": "string" }, { "type": "null" } ], "description": "Only return events caused by this kind of actor, e.g. `user` or `agent`.", "examples": [ "agent" ], "title": "Actor Type" } }, { "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": { "example": { "summary": "Opaque cursor from a previous page", "value": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } }, "in": "query", "name": "cursor", "required": false, "schema": { "anyOf": [ { "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "type": "string" }, { "type": "null" } ], "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Cursor" } }, { "description": "Maximum number of events to return (1-100, default 25).", "examples": { "example": { "summary": "Example query value for `limit`", "value": 25 } }, "in": "query", "name": "limit", "required": false, "schema": { "default": 25, "description": "Maximum number of events to return (1-100, default 25).", "examples": [ 25 ], "maximum": 100, "minimum": 1, "title": "Limit", "type": "integer" } } ], "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "_links": { "action": "https://jentic.example.com/events/evt_6968b398b04f002b6dbff4d1/action", "execution": "https://jentic.example.com/executions/exec_6968b3982706c619fe73f0cf", "job": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb", "self": "https://jentic.example.com/events/evt_6968b398b04f002b6dbff4d1" }, "actor_id": "usr_6968b3987ee4c3ec0b4ee3b9", "actor_type": "user", "created_at": "2026-01-15T09:30:00Z", "data": { "job_id": "job_6968b3985e8c9902207afaeb", "revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" }, "detail": "The import produced 1 revision with 142 operations.", "event_id": "evt_6968b398b04f002b6dbff4d1", "requires_action": false, "severity": "info", "summary": "Imported stripe.com/stripe 2024-04-10", "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736", "type": "import.completed" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" }, "schema": { "$ref": "#/components/schemas/EventListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List Events", "tags": [ "Events" ] }, "summary": "List Events" }, "/events/stream": { "description": "`GET`: Stream Events.", "get": { "description": "Stream events as Server-Sent Events.", "operationId": "streamEvents", "parameters": [ { "description": "Stream events created after this time (RFC 3339); defaults to now, and a future time is treated as now.", "examples": { "example": { "summary": "Start of a time window (RFC 3339)", "value": "2026-01-01T00:00:00Z" } }, "in": "query", "name": "since", "required": false, "schema": { "anyOf": [ { "examples": [ "2026-01-01T00:00:00Z" ], "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "Stream events created after this time (RFC 3339); defaults to now, and a future time is treated as now.", "examples": [ "2026-01-01T00:00:00Z" ], "title": "Since" } }, { "description": "Only return events of one of these types; repeat the parameter for several.", "examples": { "example": { "summary": "Example query value for `event_type`", "value": [ "import.completed" ] } }, "in": "query", "name": "event_type", "required": false, "schema": { "anyOf": [ { "examples": [ [ "import.completed" ] ], "items": { "examples": [ "import.completed" ], "type": "string" }, "type": "array" }, { "type": "null" } ], "description": "Only return events of one of these types; repeat the parameter for several.", "examples": [ [ "import.completed" ] ], "title": "Event Type" } }, { "description": "Only return events with one of these severities; repeat the parameter for several.", "examples": { "example": { "summary": "Example query value for `severity`", "value": [ "warning", "error" ] } }, "in": "query", "name": "severity", "required": false, "schema": { "anyOf": [ { "examples": [ [ "warning", "error" ] ], "items": { "$ref": "#/components/schemas/EventSeverity", "examples": [ "warning" ] }, "type": "array" }, { "type": "null" } ], "description": "Only return events with one of these severities; repeat the parameter for several.", "examples": [ [ "warning", "error" ] ], "title": "Severity" } }, { "description": "Only return events whose `requires_action` flag matches.", "examples": { "example": { "summary": "Example query value for `requires_action`", "value": true } }, "in": "query", "name": "requires_action", "required": false, "schema": { "anyOf": [ { "examples": [ true ], "type": "boolean" }, { "type": "null" } ], "description": "Only return events whose `requires_action` flag matches.", "examples": [ true ], "title": "Requires Action" } }, { "description": "Only return events with this trace ID.", "examples": { "example": { "summary": "W3C trace ID", "value": "4bf92f3577b34da6a3ce929d0e0e4736" } }, "in": "query", "name": "trace_id", "required": false, "schema": { "anyOf": [ { "examples": [ "4bf92f3577b34da6a3ce929d0e0e4736" ], "type": "string" }, { "type": "null" } ], "description": "Only return events with this trace ID.", "examples": [ "4bf92f3577b34da6a3ce929d0e0e4736" ], "title": "Trace Id" } }, { "description": "Only return events caused by this actor.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "query", "name": "actor_id", "required": false, "schema": { "anyOf": [ { "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "type": "string" }, { "type": "null" } ], "description": "Only return events caused by this actor.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Actor Id" } }, { "description": "Only return events caused by this kind of actor, e.g. `user` or `agent`.", "examples": { "example": { "summary": "Example query value for `actor_type`", "value": "agent" } }, "in": "query", "name": "actor_type", "required": false, "schema": { "anyOf": [ { "examples": [ "agent" ], "type": "string" }, { "type": "null" } ], "description": "Only return events caused by this kind of actor, e.g. `user` or `agent`.", "examples": [ "agent" ], "title": "Actor Type" } }, { "description": "ID of the last event received (`evt_` plus 24 hex characters), to resume a stream after it; ignored if the event is not visible to the caller.", "examples": { "example": { "summary": "Event ID", "value": "evt_6968b398b04f002b6dbff4d1" } }, "in": "header", "name": "Last-Event-ID", "required": false, "schema": { "anyOf": [ { "examples": [ "evt_6968b398b04f002b6dbff4d1" ], "type": "string" }, { "type": "null" } ], "description": "ID of the last event received (`evt_` plus 24 hex characters), to resume a stream after it; ignored if the event is not visible to the caller.", "examples": [ "evt_6968b398b04f002b6dbff4d1" ], "title": "Last-Event-Id" } } ], "responses": { "200": { "content": { "application/json": { "schema": {} } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Stream Events", "tags": [ "Events" ] }, "summary": "Stream Events" }, "/events/{event_id}": { "description": "`GET`: Get Event.", "get": { "description": "Get an event by ID.", "operationId": "getEvent", "parameters": [ { "description": "ID of the event.", "examples": { "example": { "summary": "Event ID", "value": "evt_6968b398b04f002b6dbff4d1" } }, "in": "path", "name": "event_id", "required": true, "schema": { "description": "ID of the event.", "examples": [ "evt_6968b398b04f002b6dbff4d1" ], "title": "Event Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "_links": { "action": "https://jentic.example.com/events/evt_6968b398b04f002b6dbff4d1/action", "execution": "https://jentic.example.com/executions/exec_6968b3982706c619fe73f0cf", "job": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb", "self": "https://jentic.example.com/events/evt_6968b398b04f002b6dbff4d1" }, "actor_id": "usr_6968b3987ee4c3ec0b4ee3b9", "actor_type": "user", "created_at": "2026-01-15T09:30:00Z", "data": { "job_id": "job_6968b3985e8c9902207afaeb", "revision_id": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" }, "detail": "The import produced 1 revision with 142 operations.", "event_id": "evt_6968b398b04f002b6dbff4d1", "requires_action": false, "severity": "info", "summary": "Imported stripe.com/stripe 2024-04-10", "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736", "type": "import.completed" }, "schema": { "$ref": "#/components/schemas/EventResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get Event", "tags": [ "Events" ] }, "summary": "Get Event" }, "/executions": { "description": "`GET`: List Executions.", "get": { "description": "List execution records with optional filters.", "operationId": "listExecutions", "parameters": [ { "description": "Legacy: only return executions mediated by this toolkit.", "examples": { "example": { "summary": "Toolkit ID", "value": "tk_6968b3981ec22d56dbbc91e8" } }, "in": "query", "name": "toolkit_id", "required": false, "schema": { "anyOf": [ { "examples": [ "tk_6968b3981ec22d56dbbc91e8" ], "type": "string" }, { "type": "null" } ], "description": "Legacy: only return executions mediated by this toolkit.", "examples": [ "tk_6968b3981ec22d56dbbc91e8" ], "title": "Toolkit Id" } }, { "description": "Only return executions with this trace ID.", "examples": { "example": { "summary": "W3C trace ID", "value": "4bf92f3577b34da6a3ce929d0e0e4736" } }, "in": "query", "name": "trace_id", "required": false, "schema": { "anyOf": [ { "examples": [ "4bf92f3577b34da6a3ce929d0e0e4736" ], "type": "string" }, { "type": "null" } ], "description": "Only return executions with this trace ID.", "examples": [ "4bf92f3577b34da6a3ce929d0e0e4736" ], "title": "Trace Id" } }, { "description": "Only return executions with one of these terminal statuses (`completed` or `failed`); repeat the parameter for several.", "examples": { "example": { "summary": "Example query value for `status`", "value": [ "completed", "failed" ] } }, "in": "query", "name": "status", "required": false, "schema": { "anyOf": [ { "examples": [ [ "completed", "failed" ] ], "items": { "examples": [ "completed" ], "type": "string" }, "type": "array" }, { "type": "null" } ], "description": "Only return executions with one of these terminal statuses (`completed` or `failed`); repeat the parameter for several.", "examples": [ [ "completed", "failed" ] ], "title": "Status" } }, { "description": "Only return executions started at or after this time (RFC 3339).", "examples": { "example": { "summary": "Start of a time window (RFC 3339)", "value": "2026-01-01T00:00:00Z" } }, "in": "query", "name": "from", "required": false, "schema": { "anyOf": [ { "examples": [ "2026-01-01T00:00:00Z" ], "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "Only return executions started at or after this time (RFC 3339).", "examples": [ "2026-01-01T00:00:00Z" ], "title": "From" } }, { "description": "Only return executions started before this time (RFC 3339).", "examples": { "example": { "summary": "End of a time window (RFC 3339)", "value": "2026-01-31T23:59:59Z" } }, "in": "query", "name": "to", "required": false, "schema": { "anyOf": [ { "examples": [ "2026-01-31T23:59:59Z" ], "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "Only return executions started before this time (RFC 3339).", "examples": [ "2026-01-31T23:59:59Z" ], "title": "To" } }, { "description": "Only return executions of this API, given as `vendor[:name[:version]]`.", "examples": { "example": { "summary": "API reference (vendor:name:version)", "value": "stripe.com:stripe:2024-04-10" } }, "in": "query", "name": "api", "required": false, "schema": { "anyOf": [ { "examples": [ "stripe.com:stripe:2024-04-10" ], "type": "string" }, { "type": "null" } ], "description": "Only return executions of this API, given as `vendor[:name[:version]]`.", "examples": [ "stripe.com:stripe:2024-04-10" ], "title": "Api" } }, { "description": "Only return executions run by this actor.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "query", "name": "actor_id", "required": false, "schema": { "anyOf": [ { "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "type": "string" }, { "type": "null" } ], "description": "Only return executions run by this actor.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Actor Id" } }, { "description": "Only return executions initiated from this surface, e.g. `api` or `mcp`.", "examples": { "example": { "summary": "Example query value for `origin`", "value": "dashboard" } }, "in": "query", "name": "origin", "required": false, "schema": { "anyOf": [ { "examples": [ "dashboard" ], "type": "string" }, { "type": "null" } ], "description": "Only return executions initiated from this surface, e.g. `api` or `mcp`.", "examples": [ "dashboard" ], "title": "Origin" } }, { "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": { "example": { "summary": "Opaque cursor from a previous page", "value": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } }, "in": "query", "name": "cursor", "required": false, "schema": { "anyOf": [ { "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "type": "string" }, { "type": "null" } ], "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Cursor" } }, { "description": "Maximum number of execution records to return (1-100, default 25).", "examples": { "example": { "summary": "Example query value for `limit`", "value": 25 } }, "in": "query", "name": "limit", "required": false, "schema": { "default": 25, "description": "Maximum number of execution records to return (1-100, default 25).", "examples": [ 25 ], "maximum": 100, "minimum": 1, "title": "Limit", "type": "integer" } } ], "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "_links": { "self": "https://jentic.example.com/executions/exec_6968b3982706c619fe73f0cf" }, "actor_id": "agnt_6968b3984d1c238dbe7e2e29", "actor_type": "agent", "api": { "host": "api.stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "created_at": "2026-01-15T09:30:00Z", "credential_id": "cred_6968b39855d91a3561684b32", "credential_name": "Stripe production key", "duration_ms": 342, "error": "Upstream returned HTTP 502 Bad Gateway", "execution_id": "exec_6968b3982706c619fe73f0cf", "http_status": 200, "operation_id": "listCharges", "operation_method": "GET", "operation_path": "/v1/charges", "origin": "agent", "pinned_revisions": { "stripe.com:stripe:2024-04-10": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" }, "started_at": "2026-01-15T09:30:00Z", "status": "completed", "toolkit_id": "tk_6968b3981ec22d56dbbc91e8", "toolkit_name": "billing-toolkit", "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" }, "schema": { "$ref": "#/components/schemas/ExecutionListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List Executions", "tags": [ "Executions" ] }, "summary": "List Executions" }, "/executions/{execution_id}": { "description": "`GET`: Get Execution.", "get": { "description": "Get an execution record by ID.", "operationId": "getExecution", "parameters": [ { "description": "ID of the execution record.", "examples": { "example": { "summary": "Execution ID", "value": "exec_6968b3982706c619fe73f0cf" } }, "in": "path", "name": "execution_id", "required": true, "schema": { "description": "ID of the execution record.", "examples": [ "exec_6968b3982706c619fe73f0cf" ], "title": "Execution Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "_links": { "self": "https://jentic.example.com/executions/exec_6968b3982706c619fe73f0cf" }, "actor_id": "agnt_6968b3984d1c238dbe7e2e29", "actor_type": "agent", "api": { "host": "api.stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "created_at": "2026-01-15T09:30:00Z", "credential_id": "cred_6968b39855d91a3561684b32", "credential_name": "Stripe production key", "duration_ms": 342, "error": "Upstream returned HTTP 502 Bad Gateway", "execution_id": "exec_6968b3982706c619fe73f0cf", "http_status": 200, "operation_id": "listCharges", "operation_method": "GET", "operation_path": "/v1/charges", "origin": "agent", "pinned_revisions": { "stripe.com:stripe:2024-04-10": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" }, "started_at": "2026-01-15T09:30:00Z", "status": "completed", "toolkit_id": "tk_6968b3981ec22d56dbbc91e8", "toolkit_name": "billing-toolkit", "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736" }, "schema": { "$ref": "#/components/schemas/ExecutionResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get Execution", "tags": [ "Executions" ] }, "summary": "Get Execution" }, "/governed-hosts": { "description": "`GET`: Get Governed Hosts.", "get": { "description": "The caller's governed host set (credential-bound hosts) with an ETag digest.\n\n**Always self-scoped** — derived from the authenticated identity's own\ncredential bindings; there is no cross-actor or admin variant. Credentials\nbind to agents, so agent-scoped tokens (the OAuth agent-consent flow's\noutput) and agent API keys are the callers this endpoint serves — a plain\nuser token yields an empty set. Suspended bindings and inactive\ncredentials still contribute their hosts: keep diverting that\ntraffic, so the broker can refuse it — dropping it from the list would\nsend it direct to the upstream, unbrokered. The ``digest`` covers exactly\nthe ``data`` list and is also emitted as a strong ``ETag``, so integrators\npoll with ``If-None-Match: \"\"`` and get an empty ``304`` until\ntheir host set actually changes (the change-poll seam that replaces\n``GET /apis`` enumeration for interception scoping). Poll at most once per\nminute; on any ``5xx`` retain the last known set — never fall back to an\nempty (intercept-nothing) list.\n\nResponses are identity-scoped and marked ``Cache-Control: private,\nno-store`` — a shared cache must never serve one actor's host set to\nanother.", "operationId": "getGovernedHosts", "parameters": [ { "description": "Change-poll precondition: the `ETag` from a previous response (quoted, `\"\"`; the bare digest is accepted as a compatibility form). When it still matches, the response is an empty `304`.", "examples": { "example": { "summary": "Governed-hosts ETag", "value": "\"9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08\"" } }, "in": "header", "name": "if-none-match", "required": false, "schema": { "anyOf": [ { "examples": [ "\"9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08\"" ], "type": "string" }, { "type": "null" } ], "description": "Change-poll precondition: the `ETag` from a previous response (quoted, `\"\"`; the bare digest is accepted as a compatibility form). When it still matches, the response is an empty `304`.", "examples": [ "\"9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08\"" ], "title": "If-None-Match" } } ], "responses": { "200": { "content": { "application/json": { "example": { "data": [ "api.github.com", "api.stripe.com", "files.stripe.com:8443" ], "digest": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08" }, "schema": { "$ref": "#/components/schemas/GovernedHostsResponse" } } }, "description": "Successful Response", "headers": { "ETag": { "description": "Strong entity tag: the quoted `digest` (`\"\"`). Echo it in `If-None-Match` to change-poll.", "schema": { "type": "string" } } } }, "304": { "description": "The host set still matches the presented `If-None-Match` — empty body, `ETag` echoed.", "headers": { "ETag": { "description": "Strong entity tag: the quoted `digest` (`\"\"`). Echo it in `If-None-Match` to change-poll.", "schema": { "type": "string" } } } }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get Governed Hosts", "tags": [ "Governed Hosts" ] }, "summary": "Get Governed Hosts" }, "/health": { "description": "`GET`: Health.", "get": { "description": "Liveness probe for the combined control-plane app.\n\nUnauthenticated and dependency-free so orchestrators and load balancers\nhave a stable target. Returns ``{\"status\": \"ok\"}`` when the process is up.", "operationId": "getHealth", "responses": { "200": { "content": { "application/json": { "example": { "status": "ok", "version": "1.0.0" }, "schema": { "$ref": "#/components/schemas/RootHealthResponse" } } }, "description": "Successful Response" } }, "security": [], "summary": "Health", "tags": [ "System" ] }, "summary": "Health" }, "/inspect": { "description": "`GET`: Inspect operation.", "get": { "description": "Inspect an operation — resolve to full structural detail.\n\n`api.vendor`/`api.name`/`api.version` in the result is the canonical API\nreference: the identity to use in credential scopes, revision pins and\nother API references. `api.display_name` (optional) is a human-readable\nlabel only.", "operationId": "inspectOperation", "parameters": [ { "description": "METHOD URL identifier", "examples": { "example": { "summary": "Upstream operation (method and URL)", "value": "GET https://api.stripe.com/v1/charges" } }, "in": "query", "name": "id", "required": false, "schema": { "anyOf": [ { "examples": [ "GET https://api.stripe.com/v1/charges" ], "type": "string" }, { "type": "null" } ], "description": "METHOD URL identifier", "examples": [ "GET https://api.stripe.com/v1/charges" ], "title": "Id" } }, { "description": "Operation ID", "examples": { "example": { "summary": "Upstream operationId", "value": "listCharges" } }, "in": "query", "name": "operation_id", "required": false, "schema": { "anyOf": [ { "examples": [ "listCharges" ], "type": "string" }, { "type": "null" } ], "description": "Operation ID", "examples": [ "listCharges" ], "title": "Operation Id" } }, { "description": "Pin to specific revision", "examples": { "example": { "summary": "Revision ID (UUID)", "value": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" } }, "in": "query", "name": "revision_id", "required": false, "schema": { "anyOf": [ { "examples": [ "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" ], "type": "string" }, { "type": "null" } ], "description": "Pin to specific revision", "examples": [ "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" ], "title": "Revision Id" } }, { "description": "Level of detail to return; only `summary` is currently supported.", "examples": { "example": { "summary": "Example query value for `detail`", "value": "summary" } }, "in": "query", "name": "detail", "required": false, "schema": { "default": "summary", "description": "Level of detail to return; only `summary` is currently supported.", "enum": [ "summary", "full" ], "examples": [ "summary" ], "title": "Detail", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "schema": {} } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Inspect operation", "tags": [ "Inspect" ] }, "summary": "Inspect operation" }, "/instance": { "description": "`GET`: Backend identity.", "get": { "description": "Return this backend's self-describing identity.\n\nUnauthenticated and dependency-free so any client (an MCP server, the\nCLI, an agent) can read which backend it is bound to — local vs. a\nremote install — and label its responses accordingly.", "operationId": "getInstance", "responses": { "200": { "content": { "application/json": { "example": { "backend": "remote", "broker_url": "https://broker.jentic.example.com", "canonical_base_url": "https://jentic.example.com", "host": "jentic.example.com", "instance_id": "5f2c9e0b7a41d8c3", "mcp_enabled": true }, "schema": { "$ref": "#/components/schemas/InstanceIdentityResponse" } } }, "description": "Successful Response" } }, "security": [], "summary": "Backend identity", "tags": [ "System" ] }, "summary": "Backend identity" }, "/integrations:connect": { "description": "`POST`: Start an integration connect session.", "post": { "description": "Both entrypoints (agent + UI) use this endpoint.\n\nAgent callers: `agent_id` in the payload is refused (the caller *is*\nthe agent — spoofing another agent's id is a permission-boundary\nviolation). The caller's own identity is injected instead. UI / user\ncallers: `agent_id` is optional — when named, confirm creates the\ndirect agent-credential binding + permission rules; when omitted, the\ncredential connects unbound and an agent can be bound later through\nthe credentials API.", "operationId": "integrationsConnect", "requestBody": { "content": { "application/json": { "example": { "agent_id": "agnt_6968b3984d1c238dbe7e2e29", "api": { "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "auth_type": "oauth2", "name": "GitHub (work)", "oauth_app_registration_id": "oar_6968b39821e5f89a6975f501", "preferred_flow": "authorization_code", "reason": "Needs read access to triage issues in the platform repo.", "requested_permission_rules": [ { "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ], "requested_scopes": [ "repo", "read:user" ], "vendor": "github" }, "schema": { "$ref": "#/components/schemas/IntegrationsConnectRequest" } } }, "description": "Start connecting a credential for a vendor or a registry API.", "required": true }, "responses": { "201": { "content": { "application/json": { "schema": {} } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unknown vendor or API, or API targets are not enabled" }, "409": { "content": { "application/problem+json": { "example": { "detail": "The request conflicts with the current state of the resource.", "instance": "/example/path", "status": 409, "title": "Conflict", "type": "conflict" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "The API declares no supported scheme, or its hosts cannot be pinned" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "429": { "content": { "application/problem+json": { "example": { "detail": "Too many requests; retry after the indicated delay.", "instance": "/example/path", "status": 429, "title": "Too Many Requests", "type": "rate_limit_exceeded" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Rate limit, open-session cap, or a recent rejection" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Start an integration connect session", "tags": [ "Integrations" ] }, "summary": "Start an integration connect session" }, "/jobs": { "description": "`GET`: List Jobs.", "get": { "description": "List jobs with optional filters.", "operationId": "listJobs", "parameters": [ { "description": "Only return jobs of this kind, e.g. `import` or `execution`.", "examples": { "example": { "summary": "Example query value for `kind`", "value": "import" } }, "in": "query", "name": "kind", "required": false, "schema": { "anyOf": [ { "examples": [ "import" ], "type": "string" }, { "type": "null" } ], "description": "Only return jobs of this kind, e.g. `import` or `execution`.", "examples": [ "import" ], "title": "Kind" } }, { "description": "Only return jobs in one of these states; repeat the parameter for several.", "examples": { "example": { "summary": "Example query value for `status`", "value": [ "running" ] } }, "in": "query", "name": "status", "required": false, "schema": { "anyOf": [ { "examples": [ [ "running" ] ], "items": { "examples": [ "running" ], "type": "string" }, "type": "array" }, { "type": "null" } ], "description": "Only return jobs in one of these states; repeat the parameter for several.", "examples": [ [ "running" ] ], "title": "Status" } }, { "description": "Only return jobs created at or after this time (RFC 3339).", "examples": { "example": { "summary": "Start of a time window (RFC 3339)", "value": "2026-01-01T00:00:00Z" } }, "in": "query", "name": "from", "required": false, "schema": { "anyOf": [ { "examples": [ "2026-01-01T00:00:00Z" ], "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "Only return jobs created at or after this time (RFC 3339).", "examples": [ "2026-01-01T00:00:00Z" ], "title": "From" } }, { "description": "Only return jobs created before this time (RFC 3339).", "examples": { "example": { "summary": "End of a time window (RFC 3339)", "value": "2026-01-31T23:59:59Z" } }, "in": "query", "name": "to", "required": false, "schema": { "anyOf": [ { "examples": [ "2026-01-31T23:59:59Z" ], "format": "date-time", "type": "string" }, { "type": "null" } ], "description": "Only return jobs created before this time (RFC 3339).", "examples": [ "2026-01-31T23:59:59Z" ], "title": "To" } }, { "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": { "example": { "summary": "Opaque cursor from a previous page", "value": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } }, "in": "query", "name": "cursor", "required": false, "schema": { "anyOf": [ { "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "type": "string" }, { "type": "null" } ], "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Cursor" } }, { "description": "Maximum number of jobs to return (1-100, default 25).", "examples": { "example": { "summary": "Example query value for `limit`", "value": 25 } }, "in": "query", "name": "limit", "required": false, "schema": { "default": 25, "description": "Maximum number of jobs to return (1-100, default 25).", "examples": [ 25 ], "maximum": 100, "minimum": 1, "title": "Limit", "type": "integer" } } ], "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "_links": { "execution": "https://jentic.example.com/executions/exec_6968b3982706c619fe73f0cf", "result": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb/result", "self": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb" }, "actor_id": "agnt_6968b3984d1c238dbe7e2e29", "actor_type": "agent", "created_at": "2026-01-15T09:30:00Z", "error": "Upstream returned HTTP 502 Bad Gateway", "execution_id": "exec_6968b3982706c619fe73f0cf", "job_id": "job_6968b3985e8c9902207afaeb", "kind": "execution", "status": "completed", "updated_at": "2026-01-15T09:30:05Z" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" }, "schema": { "$ref": "#/components/schemas/JobListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List Jobs", "tags": [ "Jobs" ] }, "summary": "List Jobs" }, "/jobs/{job_id}": { "description": "`GET`: Get Job.", "get": { "description": "Get a job by ID.", "operationId": "getJob", "parameters": [ { "description": "ID of the job.", "examples": { "example": { "summary": "Job ID", "value": "job_6968b3985e8c9902207afaeb" } }, "in": "path", "name": "job_id", "required": true, "schema": { "description": "ID of the job.", "examples": [ "job_6968b3985e8c9902207afaeb" ], "title": "Job Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "_links": { "execution": "https://jentic.example.com/executions/exec_6968b3982706c619fe73f0cf", "result": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb/result", "self": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb" }, "actor_id": "agnt_6968b3984d1c238dbe7e2e29", "actor_type": "agent", "created_at": "2026-01-15T09:30:00Z", "error": "Upstream returned HTTP 502 Bad Gateway", "execution_id": "exec_6968b3982706c619fe73f0cf", "job_id": "job_6968b3985e8c9902207afaeb", "kind": "execution", "status": "completed", "updated_at": "2026-01-15T09:30:05Z" }, "schema": { "$ref": "#/components/schemas/JobResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get Job", "tags": [ "Jobs" ] }, "summary": "Get Job" }, "/jobs/{job_id}/result": { "description": "`GET`: Get Job Result.", "get": { "description": "Get the result of a completed job — polymorphic by kind.", "operationId": "getJobResult", "parameters": [ { "description": "ID of the job.", "examples": { "example": { "summary": "Job ID", "value": "job_6968b3985e8c9902207afaeb" } }, "in": "path", "name": "job_id", "required": true, "schema": { "description": "ID of the job.", "examples": [ "job_6968b3985e8c9902207afaeb" ], "title": "Job Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "schema": {} } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get Job Result", "tags": [ "Jobs" ] }, "summary": "Get Job Result" }, "/jobs/{job_id}:cancel": { "description": "`POST`: Cancel Job.", "post": { "description": "Cancel an active job.", "operationId": "cancelJob", "parameters": [ { "description": "ID of the job.", "examples": { "example": { "summary": "Job ID", "value": "job_6968b3985e8c9902207afaeb" } }, "in": "path", "name": "job_id", "required": true, "schema": { "description": "ID of the job.", "examples": [ "job_6968b3985e8c9902207afaeb" ], "title": "Job Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "_links": { "execution": "https://jentic.example.com/executions/exec_6968b3982706c619fe73f0cf", "result": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb/result", "self": "https://jentic.example.com/jobs/job_6968b3985e8c9902207afaeb" }, "actor_id": "agnt_6968b3984d1c238dbe7e2e29", "actor_type": "agent", "created_at": "2026-01-15T09:30:00Z", "error": "Upstream returned HTTP 502 Bad Gateway", "execution_id": "exec_6968b3982706c619fe73f0cf", "job_id": "job_6968b3985e8c9902207afaeb", "kind": "execution", "status": "completed", "updated_at": "2026-01-15T09:30:05Z" }, "schema": { "$ref": "#/components/schemas/JobResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Cancel Job", "tags": [ "Jobs" ] }, "summary": "Cancel Job" }, "/mcp/config-registrations": { "description": "`POST`: Report MCP config registration.", "post": { "description": "Record that an MCP server entry was written for an agent runtime.\n\nCalled by `jentic setup` / `jentic skill init` once per runtime whose MCP\nconfig entry it wrote (best-effort on the CLI side — a failed report never\nblocks setup). Emits the `mcp.config_registered` internal event; when the\noperator opted into telemetry, the event is forwarded carrying at most the\nclosed runtime tag. Reports are throttled per (actor, runtime) within a\n24h in-process window — a throttled repeat is still a 202 with\n`recorded: false`, since the CLI treats the report as fire-and-forget.\nAny authenticated actor may report.", "operationId": "reportMcpConfigRegistration", "requestBody": { "content": { "application/json": { "example": { "runtime": "cursor" }, "schema": { "$ref": "#/components/schemas/McpConfigRegistrationRequest" } } }, "description": "Report that an MCP config entry was written for one agent runtime.", "required": true }, "responses": { "202": { "content": { "application/json": { "example": { "recorded": true, "runtime": "cursor" }, "schema": { "$ref": "#/components/schemas/McpConfigRegistrationResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Report MCP config registration", "tags": [ "MCP" ] }, "summary": "Report MCP config registration" }, "/me": { "description": "`GET`: Get Me.", "get": { "description": "Return the caller's identity and context, discriminated by actor type.", "operationId": "getMe", "responses": { "200": { "content": { "application/json": { "schema": { "discriminator": { "mapping": { "agent": "#/components/schemas/MeAgent", "user": "#/components/schemas/MeUser" }, "propertyName": "type" }, "oneOf": [ { "$ref": "#/components/schemas/MeUser" }, { "$ref": "#/components/schemas/MeAgent" } ], "title": "Response Getme" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get Me", "tags": [ "Identity" ] }, "summary": "Get Me" }, "/monitoring/executions": { "description": "`GET`: Get Execution Stats.", "get": { "description": "Return aggregated execution statistics for the dashboard.", "operationId": "getExecutionStats", "parameters": [ { "description": "Number of days back from now to aggregate over (1-30, default 7).", "examples": { "example": { "summary": "Example query value for `days`", "value": 7 } }, "in": "query", "name": "days", "required": false, "schema": { "default": 7, "description": "Number of days back from now to aggregate over (1-30, default 7).", "examples": [ 7 ], "maximum": 30, "minimum": 1, "title": "Days", "type": "integer" } } ], "responses": { "200": { "content": { "application/json": { "example": { "daily_buckets": [ { "date": "2026-01-15", "failed": 8, "success": 120, "total": 128 } ], "success_rate_percent": 93.75, "top_operations": [ { "api_name": "stripe", "api_vendor": "stripe.com", "failed": 12, "operation_id": "listCharges", "total": 342 } ], "total_executions": 1280 }, "schema": { "$ref": "#/components/schemas/ExecutionStatsResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get Execution Stats", "tags": [ "Monitoring" ] }, "summary": "Get Execution Stats" }, "/monitoring/usage": { "description": "`GET`: Get Usage Stats.", "get": { "description": "Return detailed usage statistics for the monitoring overview.", "operationId": "getUsageStats", "parameters": [ { "description": "Start of the window in Unix epoch seconds (inclusive); defaults to 24 hours before `until`.", "examples": { "example": { "summary": "Example query value for `since`", "value": 1767225600 } }, "in": "query", "name": "since", "required": false, "schema": { "anyOf": [ { "examples": [ 1767225600 ], "type": "integer" }, { "type": "null" } ], "description": "Start of the window in Unix epoch seconds (inclusive); defaults to 24 hours before `until`.", "examples": [ 1767225600 ], "title": "Since" } }, { "description": "End of the window in Unix epoch seconds (exclusive); defaults to the next minute boundary after now.", "examples": { "example": { "summary": "Example query value for `until`", "value": 1769903999 } }, "in": "query", "name": "until", "required": false, "schema": { "anyOf": [ { "examples": [ 1769903999 ], "type": "integer" }, { "type": "null" } ], "description": "End of the window in Unix epoch seconds (exclusive); defaults to the next minute boundary after now.", "examples": [ 1769903999 ], "title": "Until" } }, { "description": "Dimension to group the `top` rows by; defaults to `api`.", "examples": { "example": { "summary": "Example query value for `group_by`", "value": "api" } }, "in": "query", "name": "group_by", "required": false, "schema": { "anyOf": [ { "$ref": "#/components/schemas/GroupBy" }, { "type": "null" } ], "description": "Dimension to group the `top` rows by; defaults to `api`.", "examples": [ "api" ], "title": "Group By" } }, { "description": "Maximum number of `top` rows to return (1-50, default 10).", "examples": { "example": { "summary": "Example query value for `top_limit`", "value": 10 } }, "in": "query", "name": "top_limit", "required": false, "schema": { "default": 10, "description": "Maximum number of `top` rows to return (1-50, default 10).", "examples": [ 10 ], "maximum": 50, "minimum": 1, "title": "Top Limit", "type": "integer" } }, { "description": "Legacy: only count executions mediated by this toolkit.", "examples": { "example": { "summary": "Toolkit ID", "value": "tk_6968b3981ec22d56dbbc91e8" } }, "in": "query", "name": "toolkit_id", "required": false, "schema": { "anyOf": [ { "examples": [ "tk_6968b3981ec22d56dbbc91e8" ], "type": "string" }, { "type": "null" } ], "description": "Legacy: only count executions mediated by this toolkit.", "examples": [ "tk_6968b3981ec22d56dbbc91e8" ], "title": "Toolkit Id" } }, { "description": "Only count executions of this API, given as `vendor/name`.", "examples": { "example": { "summary": "API vendor and name (vendor/name)", "value": "stripe.com/stripe" } }, "in": "query", "name": "api_id", "required": false, "schema": { "anyOf": [ { "examples": [ "stripe.com/stripe" ], "type": "string" }, { "type": "null" } ], "description": "Only count executions of this API, given as `vendor/name`.", "examples": [ "stripe.com/stripe" ], "title": "Api Id" } }, { "description": "Only count executions run by this actor ID.", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "query", "name": "agent_id", "required": false, "schema": { "anyOf": [ { "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "type": "string" }, { "type": "null" } ], "description": "Only count executions run by this actor ID.", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id" } }, { "description": "Only count executions with this status, e.g. `completed` or `failed`.", "examples": { "example": { "summary": "Example query value for `status`", "value": "completed" } }, "in": "query", "name": "status", "required": false, "schema": { "anyOf": [ { "examples": [ "completed" ], "type": "string" }, { "type": "null" } ], "description": "Only count executions with this status, e.g. `completed` or `failed`.", "examples": [ "completed" ], "title": "Status" } } ], "responses": { "200": { "content": { "application/json": { "example": { "bucket_seconds": 86400, "buckets": [ { "avg_ms": 231.4, "failed": 2, "success": 40, "total": 42, "ts": 1767225600 } ], "group_by": "api", "since": 1767225600, "stats": { "active_now": 0, "avg_ms": 245.6, "failed": 80, "p50_ms": 180.0, "p95_ms": 720.0, "pending": 0, "success": 1200, "total": 1280 }, "top": [ { "avg_ms": 212.8, "failed": 12, "key": "stripe.com/stripe", "label": "Stripe", "success": 330, "total": 342, "trend": [ 40, 52, 47, 61, 58, 84 ] } ], "until": 1769903999 }, "schema": { "$ref": "#/components/schemas/UsageResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get Usage Stats", "tags": [ "Monitoring" ] }, "summary": "Get Usage Stats" }, "/notes": { "description": "`POST`: Create Note. `GET`: List Notes.", "get": { "description": "List notes with optional filters and cursor pagination.", "operationId": "listNotes", "parameters": [ { "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": { "example": { "summary": "Opaque cursor from a previous page", "value": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } }, "in": "query", "name": "cursor", "required": false, "schema": { "anyOf": [ { "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "type": "string" }, { "type": "null" } ], "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Cursor" } }, { "description": "Maximum number of notes to return (1-200).", "examples": { "example": { "summary": "Example query value for `limit`", "value": 25 } }, "in": "query", "name": "limit", "required": false, "schema": { "default": 50, "description": "Maximum number of notes to return (1-200).", "examples": [ 25 ], "maximum": 200, "minimum": 1, "title": "Limit", "type": "integer" } }, { "description": "Only return notes attached to APIs matching `vendor[:name[:version]]`.", "examples": { "example": { "summary": "API reference (vendor:name:version)", "value": "stripe.com:stripe:2024-04-10" } }, "in": "query", "name": "api", "required": false, "schema": { "anyOf": [ { "examples": [ "stripe.com:stripe:2024-04-10" ], "type": "string" }, { "type": "null" } ], "description": "Only return notes attached to APIs matching `vendor[:name[:version]]`.", "examples": [ "stripe.com:stripe:2024-04-10" ], "title": "Api" } }, { "description": "Only return notes attached to this operation.", "examples": { "example": { "summary": "Upstream operationId", "value": "listCharges" } }, "in": "query", "name": "operation_id", "required": false, "schema": { "anyOf": [ { "examples": [ "listCharges" ], "type": "string" }, { "type": "null" } ], "description": "Only return notes attached to this operation.", "examples": [ "listCharges" ], "title": "Operation Id" } }, { "description": "Only return notes attached to this execution.", "examples": { "example": { "summary": "Execution ID", "value": "exec_6968b3982706c619fe73f0cf" } }, "in": "query", "name": "execution_id", "required": false, "schema": { "anyOf": [ { "examples": [ "exec_6968b3982706c619fe73f0cf" ], "type": "string" }, { "type": "null" } ], "description": "Only return notes attached to this execution.", "examples": [ "exec_6968b3982706c619fe73f0cf" ], "title": "Execution Id" } }, { "description": "Only return notes attached to this credential.", "examples": { "example": { "summary": "Credential ID", "value": "cred_6968b39855d91a3561684b32" } }, "in": "query", "name": "credential_id", "required": false, "schema": { "anyOf": [ { "examples": [ "cred_6968b39855d91a3561684b32" ], "type": "string" }, { "type": "null" } ], "description": "Only return notes attached to this credential.", "examples": [ "cred_6968b39855d91a3561684b32" ], "title": "Credential Id" } }, { "description": "Only return notes of this type.", "examples": { "example": { "summary": "Example query value for `type`", "value": "usage_hint" } }, "in": "query", "name": "type", "required": false, "schema": { "anyOf": [ { "examples": [ "usage_hint" ], "type": "string" }, { "type": "null" } ], "description": "Only return notes of this type.", "examples": [ "usage_hint" ], "title": "Type" } }, { "description": "Only return notes created by this actor ID.", "examples": { "example": { "summary": "User ID", "value": "usr_6968b3987ee4c3ec0b4ee3b9" } }, "in": "query", "name": "created_by", "required": false, "schema": { "anyOf": [ { "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "type": "string" }, { "type": "null" } ], "description": "Only return notes created by this actor ID.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "Created By" } } ], "responses": { "200": { "content": { "application/json": { "schema": {} } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List Notes", "tags": [ "Notes" ] }, "post": { "description": "Create a new note attached to a registry resource.", "operationId": "createNote", "requestBody": { "content": { "application/json": { "example": { "body": "Stripe returns 401 unless the secret key is sent as a Bearer token; Basic auth with an empty password also works.", "confidence": "observed", "related_execution_id": "exec_6968b3982706c619fe73f0cf", "resource": { "api": { "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "credential_id": "cred_6968b39855d91a3561684b32", "execution_id": "exec_6968b3982706c619fe73f0cf", "operation_id": "op_f92d69f1621f381bce8aaff47053c61b069ffe34" }, "source": "agent", "type": "auth_quirk" }, "schema": { "$ref": "#/components/schemas/NoteCreateRequest" } } }, "description": "Payload for creating a new note.", "required": true }, "responses": { "201": { "content": { "application/json": { "schema": {} } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Create Note", "tags": [ "Notes" ] }, "summary": "Create Note; List Notes" }, "/notes/{note_id}": { "delete": { "description": "Delete a note. Supports optimistic concurrency via If-Match.", "operationId": "deleteNote", "parameters": [ { "description": "ID of the note.", "examples": { "example": { "summary": "Note ID", "value": "note_6968b398edb465624291e405" } }, "in": "path", "name": "note_id", "required": true, "schema": { "description": "ID of the note.", "examples": [ "note_6968b398edb465624291e405" ], "title": "Note Id", "type": "string" } }, { "description": "Expected note revision (the `ETag` value); the request fails with 412 if the note has changed.", "examples": { "example": { "summary": "Note ETag (quoted revision)", "value": "\"3\"" } }, "in": "header", "name": "if-match", "required": false, "schema": { "anyOf": [ { "examples": [ "\"3\"" ], "type": "string" }, { "type": "null" } ], "description": "Expected note revision (the `ETag` value); the request fails with 412 if the note has changed.", "examples": [ "\"3\"" ], "title": "If-Match" } } ], "responses": { "204": { "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Delete Note", "tags": [ "Notes" ] }, "description": "`GET`: Get Note. `PATCH`: Update Note. `DELETE`: Delete Note.", "get": { "description": "Retrieve a single note by ID.", "operationId": "getNote", "parameters": [ { "description": "ID of the note.", "examples": { "example": { "summary": "Note ID", "value": "note_6968b398edb465624291e405" } }, "in": "path", "name": "note_id", "required": true, "schema": { "description": "ID of the note.", "examples": [ "note_6968b398edb465624291e405" ], "title": "Note Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "schema": {} } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get Note", "tags": [ "Notes" ] }, "patch": { "description": "Update a note (partial). Supports optimistic concurrency via If-Match.", "operationId": "updateNote", "parameters": [ { "description": "ID of the note.", "examples": { "example": { "summary": "Note ID", "value": "note_6968b398edb465624291e405" } }, "in": "path", "name": "note_id", "required": true, "schema": { "description": "ID of the note.", "examples": [ "note_6968b398edb465624291e405" ], "title": "Note Id", "type": "string" } }, { "description": "Expected note revision (the `ETag` value); the request fails with 412 if the note has changed.", "examples": { "example": { "summary": "Note ETag (quoted revision)", "value": "\"3\"" } }, "in": "header", "name": "if-match", "required": false, "schema": { "anyOf": [ { "examples": [ "\"3\"" ], "type": "string" }, { "type": "null" } ], "description": "Expected note revision (the `ETag` value); the request fails with 412 if the note has changed.", "examples": [ "\"3\"" ], "title": "If-Match" } } ], "requestBody": { "content": { "application/json": { "example": { "body": "Stripe returns 401 unless the secret key is sent as a Bearer token; Basic auth with an empty password also works.", "confidence": "verified", "related_execution_id": "exec_6968b3982706c619fe73f0cf", "source": "agent", "type": "auth_quirk" }, "schema": { "$ref": "#/components/schemas/NoteUpdateRequest" } } }, "description": "Payload for updating an existing note (partial).", "required": true }, "responses": { "200": { "content": { "application/json": { "schema": {} } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Update Note", "tags": [ "Notes" ] }, "summary": "Get Note; Update Note; Delete Note" }, "/oauth-app-registrations": { "description": "`POST`: Register a shared OAuth application. `GET`: List OAuth app registrations.", "get": { "description": "List OAuth application registrations with cursor-based pagination.\n\nAdmin-only: the full view carries endpoints, ``created_by``, inactive\nrows and org-wide dependent-credential counts. Non-admins discover the\nshared apps they can connect through via ``GET /vendors``.", "operationId": "listOauthAppRegistrations", "parameters": [ { "description": "Filter by vendor slug.", "examples": { "example": { "summary": "Vendor registry key", "value": "github" } }, "in": "query", "name": "api_vendor", "required": false, "schema": { "anyOf": [ { "examples": [ "github" ], "type": "string" }, { "type": "null" } ], "description": "Filter by vendor slug.", "examples": [ "github" ], "title": "Api Vendor" } }, { "description": "Include registrations with is_active=false in the response.", "examples": { "example": { "summary": "Example query value for `include_inactive`", "value": true } }, "in": "query", "name": "include_inactive", "required": false, "schema": { "default": false, "description": "Include registrations with is_active=false in the response.", "examples": [ true ], "title": "Include Inactive", "type": "boolean" } }, { "description": "Filter by OAuth flow kind.", "examples": { "example": { "summary": "Example query value for `flow_kind`", "value": "authorization_code" } }, "in": "query", "name": "flow_kind", "required": false, "schema": { "anyOf": [ { "$ref": "#/components/schemas/OAuthAppRegistrationFlowKind" }, { "type": "null" } ], "description": "Filter by OAuth flow kind.", "examples": [ "authorization_code" ], "title": "Flow Kind" } }, { "description": "Opaque cursor from a previous page's next_cursor; omit for the first page.", "examples": { "example": { "summary": "Opaque cursor from a previous page", "value": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } }, "in": "query", "name": "cursor", "required": false, "schema": { "anyOf": [ { "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "type": "string" }, { "type": "null" } ], "description": "Opaque cursor from a previous page's next_cursor; omit for the first page.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Cursor" } }, { "description": "Maximum number of registrations to return (1-200, default 50).", "examples": { "example": { "summary": "Example query value for `limit`", "value": 25 } }, "in": "query", "name": "limit", "required": false, "schema": { "default": 50, "description": "Maximum number of registrations to return (1-200, default 50).", "examples": [ 25 ], "maximum": 200, "minimum": 1, "title": "Limit", "type": "integer" } } ], "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "api_vendor": "github", "authorization_endpoint": "https://github.com/login/device/code", "authorize_url": "https://github.com/login/oauth/authorize", "catalog_api_id": "github.com/api.github.com", "client_id": "Iv1.a1b2c3d4", "created_at": "2026-01-15T09:30:00Z", "created_by": "usr_6968b3987ee4c3ec0b4ee3b9", "default_scopes": [ "repo", "read:user" ], "dependent_credential_count": 4, "display_name": "GitHub", "flow_kind": "authorization_code", "has_client_secret": true, "id": "oar_6968b39821e5f89a6975f501", "is_active": true, "name": "MyOrg GitHub", "secret_last_rotated_at": "2026-01-20T14:05:00Z", "token_endpoint": "https://github.com/login/oauth/access_token", "token_url": "https://github.com/login/oauth/access_token", "updated_at": "2026-01-20T14:05:00Z" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" }, "schema": { "$ref": "#/components/schemas/OAuthAppRegistrationListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List OAuth app registrations", "tags": [ "OAuth App Registrations" ] }, "post": { "description": "Register a shared OAuth application that users on this instance can SSO through.\n\nThe client secret is stored encrypted and never returned by any read\nendpoint — reads only expose ``has_client_secret`` + ``secret_last_rotated_at``.\nConnect sessions waiting for an OAuth app for the registration's API\nmove on to it right away.", "operationId": "createOauthAppRegistration", "requestBody": { "content": { "application/json": { "schema": { "discriminator": { "mapping": { "authorization_code": "#/components/schemas/AuthorizationCodeRegistrationCreateRequest", "device_authorization": "#/components/schemas/DeviceAuthorizationRegistrationCreateRequest" }, "propertyName": "flow_kind" }, "oneOf": [ { "$ref": "#/components/schemas/AuthorizationCodeRegistrationCreateRequest" }, { "$ref": "#/components/schemas/DeviceAuthorizationRegistrationCreateRequest" } ], "title": "Body" } } }, "description": "Request payload for the `createOauthAppRegistration` operation.", "required": true }, "responses": { "201": { "content": { "application/json": { "example": { "api_vendor": "github", "authorization_endpoint": "https://github.com/login/device/code", "authorize_url": "https://github.com/login/oauth/authorize", "catalog_api_id": "github.com/api.github.com", "client_id": "Iv1.a1b2c3d4", "created_at": "2026-01-15T09:30:00Z", "created_by": "usr_6968b3987ee4c3ec0b4ee3b9", "default_scopes": [ "repo", "read:user" ], "dependent_credential_count": 4, "display_name": "GitHub", "flow_kind": "authorization_code", "has_client_secret": true, "id": "oar_6968b39821e5f89a6975f501", "is_active": true, "name": "MyOrg GitHub", "secret_last_rotated_at": "2026-01-20T14:05:00Z", "token_endpoint": "https://github.com/login/oauth/access_token", "token_url": "https://github.com/login/oauth/access_token", "updated_at": "2026-01-20T14:05:00Z" }, "schema": { "$ref": "#/components/schemas/OAuthAppRegistrationResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Register a shared OAuth application", "tags": [ "OAuth App Registrations" ] }, "summary": "Register a shared OAuth application; List OAuth app registrations" }, "/oauth-app-registrations/{id}": { "delete": { "description": "Delete a registration.\n\nRefused if any credentials still reference it — revoke those first, or\ndeactivate the registration with a PATCH ``is_active=false`` instead.", "operationId": "deleteOauthAppRegistration", "parameters": [ { "description": "ID of the OAuth app registration.", "examples": { "example": { "summary": "OAuth app registration ID", "value": "oar_6968b39821e5f89a6975f501" } }, "in": "path", "name": "id", "required": true, "schema": { "description": "ID of the OAuth app registration.", "examples": [ "oar_6968b39821e5f89a6975f501" ], "title": "Id", "type": "string" } } ], "responses": { "204": { "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "409": { "content": { "application/problem+json": { "example": { "detail": "The request conflicts with the current state of the resource.", "instance": "/example/path", "status": 409, "title": "Conflict", "type": "conflict" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Conflict" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Delete an OAuth app registration", "tags": [ "OAuth App Registrations" ] }, "description": "`GET`: Get an OAuth app registration. `PATCH`: Update an OAuth app registration. `DELETE`: Delete an OAuth app registration.", "get": { "description": "Get an OAuth app registration by id (admin-only, see the list endpoint).", "operationId": "getOauthAppRegistration", "parameters": [ { "description": "ID of the OAuth app registration.", "examples": { "example": { "summary": "OAuth app registration ID", "value": "oar_6968b39821e5f89a6975f501" } }, "in": "path", "name": "id", "required": true, "schema": { "description": "ID of the OAuth app registration.", "examples": [ "oar_6968b39821e5f89a6975f501" ], "title": "Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "api_vendor": "github", "authorization_endpoint": "https://github.com/login/device/code", "authorize_url": "https://github.com/login/oauth/authorize", "catalog_api_id": "github.com/api.github.com", "client_id": "Iv1.a1b2c3d4", "created_at": "2026-01-15T09:30:00Z", "created_by": "usr_6968b3987ee4c3ec0b4ee3b9", "default_scopes": [ "repo", "read:user" ], "dependent_credential_count": 4, "display_name": "GitHub", "flow_kind": "authorization_code", "has_client_secret": true, "id": "oar_6968b39821e5f89a6975f501", "is_active": true, "name": "MyOrg GitHub", "secret_last_rotated_at": "2026-01-20T14:05:00Z", "token_endpoint": "https://github.com/login/oauth/access_token", "token_url": "https://github.com/login/oauth/access_token", "updated_at": "2026-01-20T14:05:00Z" }, "schema": { "$ref": "#/components/schemas/OAuthAppRegistrationResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get an OAuth app registration", "tags": [ "OAuth App Registrations" ] }, "patch": { "description": "Update mutable fields on a registration.\n\n``client_id`` is immutable (would orphan every dependent credential) —\nuse ``:rotate-secret`` for the client secret.", "operationId": "updateOauthAppRegistration", "parameters": [ { "description": "ID of the OAuth app registration.", "examples": { "example": { "summary": "OAuth app registration ID", "value": "oar_6968b39821e5f89a6975f501" } }, "in": "path", "name": "id", "required": true, "schema": { "description": "ID of the OAuth app registration.", "examples": [ "oar_6968b39821e5f89a6975f501" ], "title": "Id", "type": "string" } } ], "requestBody": { "content": { "application/json": { "example": { "authorization_endpoint": "https://github.com/login/device/code", "authorize_url": "https://github.com/login/oauth/authorize", "default_scopes": [ "repo", "read:user" ], "display_name": "GitHub", "is_active": true, "name": "MyOrg GitHub", "token_endpoint": "https://github.com/login/oauth/access_token", "token_url": "https://github.com/login/oauth/access_token" }, "schema": { "$ref": "#/components/schemas/OAuthAppRegistrationUpdateRequest" } } }, "description": "Partial update — fields not present are left untouched.", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "api_vendor": "github", "authorization_endpoint": "https://github.com/login/device/code", "authorize_url": "https://github.com/login/oauth/authorize", "catalog_api_id": "github.com/api.github.com", "client_id": "Iv1.a1b2c3d4", "created_at": "2026-01-15T09:30:00Z", "created_by": "usr_6968b3987ee4c3ec0b4ee3b9", "default_scopes": [ "repo", "read:user" ], "dependent_credential_count": 4, "display_name": "GitHub", "flow_kind": "authorization_code", "has_client_secret": true, "id": "oar_6968b39821e5f89a6975f501", "is_active": true, "name": "MyOrg GitHub", "secret_last_rotated_at": "2026-01-20T14:05:00Z", "token_endpoint": "https://github.com/login/oauth/access_token", "token_url": "https://github.com/login/oauth/access_token", "updated_at": "2026-01-20T14:05:00Z" }, "schema": { "$ref": "#/components/schemas/OAuthAppRegistrationResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Update an OAuth app registration", "tags": [ "OAuth App Registrations" ] }, "summary": "Get an OAuth app registration; Update an OAuth app registration; Delete an OAuth app registration" }, "/oauth-app-registrations/{id}:rotate-secret": { "description": "`POST`: Rotate the client secret.", "post": { "description": "Replace the encrypted client secret. Existing tokens are unaffected;\nsubsequent refreshes present the new secret.", "operationId": "rotateOauthAppRegistrationSecret", "parameters": [ { "description": "ID of the OAuth app registration.", "examples": { "example": { "summary": "OAuth app registration ID", "value": "oar_6968b39821e5f89a6975f501" } }, "in": "path", "name": "id", "required": true, "schema": { "description": "ID of the OAuth app registration.", "examples": [ "oar_6968b39821e5f89a6975f501" ], "title": "Id", "type": "string" } } ], "requestBody": { "content": { "application/json": { "example": { "client_secret": "example-secret" }, "schema": { "$ref": "#/components/schemas/OAuthAppRegistrationRotateSecretRequest" } } }, "description": "Rotate the client secret on an auth-code registration.", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "api_vendor": "github", "authorization_endpoint": "https://github.com/login/device/code", "authorize_url": "https://github.com/login/oauth/authorize", "catalog_api_id": "github.com/api.github.com", "client_id": "Iv1.a1b2c3d4", "created_at": "2026-01-15T09:30:00Z", "created_by": "usr_6968b3987ee4c3ec0b4ee3b9", "default_scopes": [ "repo", "read:user" ], "dependent_credential_count": 4, "display_name": "GitHub", "flow_kind": "authorization_code", "has_client_secret": true, "id": "oar_6968b39821e5f89a6975f501", "is_active": true, "name": "MyOrg GitHub", "secret_last_rotated_at": "2026-01-20T14:05:00Z", "token_endpoint": "https://github.com/login/oauth/access_token", "token_url": "https://github.com/login/oauth/access_token", "updated_at": "2026-01-20T14:05:00Z" }, "schema": { "$ref": "#/components/schemas/OAuthAppRegistrationResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "409": { "content": { "application/problem+json": { "example": { "detail": "The request conflicts with the current state of the resource.", "instance": "/example/path", "status": 409, "title": "Conflict", "type": "conflict" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Conflict" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Rotate the client secret", "tags": [ "OAuth App Registrations" ] }, "summary": "Rotate the client secret" }, "/oauth-clients": { "description": "`POST`: Register OAuth client (anonymous DCR).", "post": { "description": "Register a public OAuth client anonymously (RFC 7591 subset).\n\nReturns 201 with the new ``client_id``, or 200 with the **existing** row's\n``client_id`` on an exact dedupe match (D8, extended per G13/#1251):\n(``software_id`` + redirect-URI set), falling back to (``client_name`` +\nredirect-URI set) for registrations without a ``software_id`` — so a\npending client's awaiting-approval retry loop re-attaches instead of\nminting duplicate rows. Re-registering a client an administrator has\ndeactivated re-enters the approval queue: the registration re-attaches\n(200) and the client awaits a fresh admin decision (#1312). No\nclient_secret is ever issued here and no registration_access_token\nis returned (D12). New rows await admin approval unless the deployment\nauto-approves registrations (D9). The ``server.mcp.oauth.enabled`` gate\nlives on the route class — a disabled door 404s before this handler,\nits body validation, or the rate limiter ever run.", "operationId": "registerOauthClientEndpoint", "requestBody": { "content": { "application/json": { "example": { "application_type": "native", "client_name": "Cursor", "grant_types": [ "authorization_code", "refresh_token" ], "redirect_uris": [ "https://client.example.com/oauth/callback" ], "response_types": [ "code" ], "scope": "apis:read capabilities:execute", "software_id": "com.example.mcp-client", "software_version": "1.4.2", "token_endpoint_auth_method": "none" }, "schema": { "$ref": "#/components/schemas/OAuthClientRegistrationRequest" } } }, "description": "POST /oauth-clients request body (RFC 7591 client metadata subset).", "required": true }, "responses": { "201": { "content": { "application/json": { "example": { "application_type": "native", "client_id": "oc_Xk3vQ9mT2pLw8RzN5bYc1HdF7gJs4AeU", "client_id_issued_at": 1767225600, "client_name": "Cursor", "grant_types": [ "authorization_code", "refresh_token" ], "redirect_uris": [ "https://client.example.com/oauth/callback" ], "response_types": [ "code" ], "scope": "apis:read capabilities:execute", "software_id": "com.example.mcp-client", "software_version": "1.4.2", "token_endpoint_auth_method": "none" }, "schema": { "$ref": "#/components/schemas/OAuthClientRegistrationResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/json": { "example": { "error": "invalid_client_metadata", "error_description": "redirect_uris: at least one redirect URI is required" }, "schema": { "$ref": "#/components/schemas/OAuthErrorResponse" } } }, "description": "Invalid client metadata (RFC 7591 §3.2.2): `{\"error\": \"invalid_client_metadata\", \"error_description\": \"...\"}`." }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [], "summary": "Register OAuth client (anonymous DCR)", "tags": [ "OAuth Clients" ] }, "summary": "Register OAuth client (anonymous DCR)" }, "/oauth-grants/{grant_id}:revoke": { "description": "`POST`: Revoke OAuth grant.", "post": { "description": "Revoke a consent→agent grant — one of the three revocation kill radii.\n\nAllowed for the grant's owner (the consenting user) or an admin. Marks\nthe grant ``revoked`` and revokes every outstanding access/refresh token\nminted under it in the same transaction; the live resolvers also re-check\ngrant status on every verdict (belt + braces). The client's next token\nuse or refresh fails closed. Idempotent on an already-revoked grant.", "operationId": "revokeOauthGrant", "parameters": [ { "description": "ID of the OAuth grant.", "examples": { "example": { "summary": "OAuth consent grant ID", "value": "ocg_6968b3985e21c5fdf643025d" } }, "in": "path", "name": "grant_id", "required": true, "schema": { "description": "ID of the OAuth grant.", "examples": [ "ocg_6968b3985e21c5fdf643025d" ], "title": "Grant Id", "type": "string" } } ], "responses": { "204": { "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Revoke OAuth grant", "tags": [ "OAuth" ] }, "summary": "Revoke OAuth grant" }, "/oauth/approval/decision": { "description": "`POST`: Approve or deny a pending client inline (approval-pending page).", "post": { "description": "Thin wrapper over the admin approval path for the approval-pending page.\n\nAuthorization is byte-identical to ``POST /admin/oauth-clients/{id}:approve``\n/ ``:deny`` (``oauth-clients:write``, org:admin implies it) and the\ndecision itself is the SAME ``OAuthClientService.approve``/``deny`` calls —\nsame audit records, same D7 active/approval_status coupling; this endpoint\nonly translates the signed state blob into the client row. CSRF posture\nmatches the consent POST: no ambient credential is honored — the browser\nmust explicitly present the SPA bearer token, which a cross-site form\ncannot do.", "operationId": "approvalDecisionEndpoint", "requestBody": { "content": { "application/json": { "example": { "action": "approve", "state": "eyJfcHVycG9zZSI6ICJleGFtcGxlIn0=.5d41402abc4b2a76b9719d911017c592" }, "schema": { "$ref": "#/components/schemas/OAuthApprovalDecisionRequest" } } }, "description": "Inline admin approve/deny posted from the approval-pending page.\n\n``state`` is the signed approval-state blob minted by ``/authorize`` for\nthis exact authorize request — the decision endpoint never accepts a bare\n``client_id``.\n\n``state`` is deliberately NOT marked x-sensitive: the CLI's GEN-21\nredaction backstop unions every sensitive field's BARE name globally, and\n\"state\" is generic enough to redact unrelated CLI output (e.g. the MCP\nsession-diagnosis ``state`` field). The blob is not a lasting bearer\ncredential — it is HMAC-signed, purpose-discriminated, TTL'd (600 s), and\nthe decision endpoint additionally requires an authenticated admin with\n``oauth-clients:write`` — so global redaction buys nothing worth that\ncollision.", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "status": "approved" }, "schema": { "$ref": "#/components/schemas/OAuthApprovalStatusResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Malformed, tampered, or expired approval-state blob." }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Approve or deny a pending client inline (approval-pending page)", "tags": [ "OAuth" ] }, "summary": "Approve or deny a pending client inline (approval-pending page)" }, "/oauth/approval/status": { "description": "`GET`: Poll client approval status (approval-pending page).", "get": { "description": "Minimal tri-state poll for the approval-pending page.\n\nAnonymous but keyed by the signed approval-state blob — never a bare\nclient_id, so the endpoint cannot be used to enumerate registrations. Any\nverification failure (bad signature, wrong purpose, expired ``iat``,\nmalformed blob) is a 400 ``invalid_grant``; the page reacts to a 400 by\nre-running /authorize, which mints a fresh blob. The response carries ONLY\nthe tri-state — no names, redirect URIs, or metadata.", "operationId": "approvalStatusEndpoint", "parameters": [ { "description": "Signed approval-state blob minted by /authorize", "examples": { "example": { "summary": "Signed flow state blob", "value": "eyJfcHVycG9zZSI6ICJleGFtcGxlIn0=.5d41402abc4b2a76b9719d911017c592" } }, "in": "query", "name": "st", "required": true, "schema": { "description": "Signed approval-state blob minted by /authorize", "examples": [ "eyJfcHVycG9zZSI6ICJleGFtcGxlIn0=.5d41402abc4b2a76b9719d911017c592" ], "title": "St", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "status": "approved" }, "schema": { "$ref": "#/components/schemas/OAuthApprovalStatusResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Malformed, tampered, or expired approval-state blob." }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [], "summary": "Poll client approval status (approval-pending page)", "tags": [ "OAuth" ] }, "summary": "Poll client approval status (approval-pending page)" }, "/oauth/consent/agent": { "description": "`POST`: Create the consenting user's first agent inline (consent page).", "post": { "description": "Create the consenting user's first agent from the zero-agents consent page (P4).\n\nThe form is rendered only when the consenting user owns zero agents in\nany status (the G12(b) first-run dead-end). This submit verifies the signed\nsingle-use ``agent-create`` blob (bound to the consent handle AND the\nauthenticated subject — no ambient credential is honored, so a cross-site\nform cannot drive it: it would need both the unguessable handle and a\nblob minted for that very handle), re-validates the handle and the D7\nclient gate, provisions the user row if deferred provisioning left none\n(an affirmative user action, unlike rendering), re-checks the zero-agents\npredicate (an agent appearing in between skips creation — idempotent),\ncreates the agent through the same ``AgentService.create`` path as the\nSPA (owner = the consenting user, default agent scopes, same audit +\nevent), and 303-redirects back into ``GET /oauth/consent`` where the new\nagent renders pre-selected.\n\nFailure arms: expired/tampered/replayed blob and expired handle → the\nconsent flow's standard ``invalid_consent`` error redirect; a gated\nclient → ``access_denied``; an invalid agent name → the form re-rendered\nwith the error inline and a fresh blob.\n\nCreation posture (security review — the hybrid): the arm is decided\nserver-side AFTER the subject is resolved/provisioned, against the same\neffective-permission math as POST /agents' ``agents:write`` gate. A\npermissioned user gets the original behaviour (ACTIVE + 303 re-entry); an\nunpermissioned one gets a PENDING agent (the POST /register posture) and\nthe awaiting-approval page. A per-subject ``set_if_absent`` slot claim\nmakes N parallel submits (N distinct blobs from N renders) create exactly\none agent — losers re-enter consent, which renders the picker or the\nawaiting page as appropriate.", "operationId": "consentAgentCreate", "requestBody": { "content": { "application/x-www-form-urlencoded": { "schema": { "$ref": "#/components/schemas/Body_consentAgentCreate" } } }, "description": "Request payload for the `consentAgentCreate` operation.", "required": true }, "responses": { "200": { "content": { "application/json": { "schema": {} } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [], "summary": "Create the consenting user's first agent inline (consent page)", "tags": [ "OAuth" ] }, "summary": "Create the consenting user's first agent inline (consent page)" }, "/oauth/consent/agent/status": { "description": "`GET`: Poll pending-agent approval status (consent awaiting page).", "get": { "description": "Minimal tri-state poll for the pending-agent awaiting page (P4 hybrid).\n\nAnonymous but keyed by the signed ``agent-status`` blob — never a bare\nagent id, so the endpoint cannot be used to enumerate or probe agents:\nthe id it reports on is the one SIGNED into the blob, which only the\nconsent flow mints, and only for an agent it verified belongs to the\nhandle's subject. The response carries ONLY the tri-state — no name,\nowner, or scopes — and non-terminal lifecycle states (disabled, archived,\na vanished row) all read as ``pending``, so possession of a blob is not a\nlifecycle oracle either. Any verification failure (bad signature, wrong\npurpose, expired ``iat``, malformed blob) is a 400 ``invalid_grant``; the\npage treats a 400 as terminal (\"retry the connection\") because the blob\nshares the consent handle's lifetime — a retry re-enters the flow, which\nre-parks on a fresh awaiting page while the agent stays pending. Shares\nthe approval-status poll's own per-IP rate bucket (same cadence, same\ncaller shape).", "operationId": "consentAgentStatus", "parameters": [ { "description": "Signed agent-status blob minted by the consent flow's pending arm", "examples": { "example": { "summary": "Signed flow state blob", "value": "eyJfcHVycG9zZSI6ICJleGFtcGxlIn0=.5d41402abc4b2a76b9719d911017c592" } }, "in": "query", "name": "st", "required": true, "schema": { "description": "Signed agent-status blob minted by the consent flow's pending arm", "examples": [ "eyJfcHVycG9zZSI6ICJleGFtcGxlIn0=.5d41402abc4b2a76b9719d911017c592" ], "title": "St", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "status": "pending" }, "schema": { "$ref": "#/components/schemas/ConsentAgentStatusResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Malformed, tampered, or expired agent-status blob." }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [], "summary": "Poll pending-agent approval status (consent awaiting page)", "tags": [ "OAuth" ] }, "summary": "Poll pending-agent approval status (consent awaiting page)" }, "/oauth/introspect": { "description": "`POST`: Introspect Endpoint.", "post": { "description": "Introspect a token (RFC 7662).\n\nAccepts both ``application/x-www-form-urlencoded`` (the §2.1 request\nencoding) and JSON (the platform's own contract) bodies. Both arms\nrequire a platform bearer identity, and both answer an unknown, invalid,\nor expired *token value* with 200 ``{\"active\": false}`` (§2.2) — only a\nmalformed request body (missing ``token``) is a 400 ``invalid_request``:\nProblem Details on the JSON arm, the RFC 6749 §5.2 error dialect on the\nform arm.", "operationId": "introspectEndpoint", "requestBody": { "content": { "application/json": { "schema": { "description": "Introspection endpoint request (RFC 7662) — JSON or form-encoded.", "properties": { "token": { "title": "Token", "type": "string", "x-sensitive": true }, "token_type_hint": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Token Type Hint" } }, "required": [ "token" ], "title": "IntrospectRequest", "type": "object" } }, "application/x-www-form-urlencoded": { "schema": { "description": "Introspection endpoint request (RFC 7662) — JSON or form-encoded.", "properties": { "token": { "title": "Token", "type": "string", "x-sensitive": true }, "token_type_hint": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Token Type Hint" } }, "required": [ "token" ], "title": "IntrospectRequest", "type": "object" } } }, "description": "Introspection endpoint request (RFC 7662) — JSON or form-encoded.", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "active": true, "exp": 1769903999, "scope": "apis:read capabilities:execute", "sub": "agnt_6968b3984d1c238dbe7e2e29", "token_type": "access_token" }, "schema": { "$ref": "#/components/schemas/IntrospectResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Malformed request body (missing `token`). JSON requests get platform Problem Details (`type: invalid_request`); form-encoded (RFC 7662 §2.1) requests get the RFC 6749 §5.2 dialect: `{\"error\": \"invalid_request\", \"error_description\": \"...\"}`. An unknown, invalid, or expired token value is never an error — it is 200 `{\"active\": false}` (RFC 7662 §2.2)." }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Introspect Endpoint", "tags": [ "OAuth" ] }, "summary": "Introspect Endpoint" }, "/oauth/revoke": { "description": "`POST`: Revoke Endpoint.", "post": { "description": "Revoke a token (RFC 7009). Always returns 200 for valid requests.\n\nTwo client-authentication arms, negotiated on the request content type by\n``_RevocationRoute`` (this function body IS the JSON arm — form-encoded\nrequests never reach it):\n\n- **Form-encoded** (`application/x-www-form-urlencoded`, RFC 7009 §2.1 —\n the shape MCP OAuth clients send, G11): `token` + optional\n `token_type_hint` + `client_id`. Public (secret-less) clients\n authenticate by client_id **lineage binding** — the call revokes\n anything only when the token exists and was issued to that `client_id`;\n everything else is a 200 no-op (no token-validity oracle). Revoking an\n access token kills that token only; revoking a **refresh token is a full\n disconnect** — every token of the consent grant AND the grant row itself\n die, so reconnecting requires fresh consent (deliberately beyond the\n RFC 7009 §2.1 SHOULD; one revocation semantics platform-wide). This arm\n is gated by `server.mcp.oauth.enabled` (plain 404 when off), capped at\n 64 KiB declared body length, and per-IP rate limited; its errors speak\n the RFC 6749 §5.2 dialect (RFC 7009 §2.2.1), not Problem Details.\n- **JSON** (any other content type — the pre-G11 contract, byte-identical\n including 422 shapes): requires a platform bearer identity; revokes the\n caller's own token (access → that token, refresh → its family). Used by\n `jentic logout`.\n\nRevocation residual: a revoked **access** token dies on the control-plane\nresolver immediately, but the broker's `CachedTokenValidator` (30 s TTL)\nmay honour an already-cached verdict for up to 30 s — the same residual as\nthe UI `:revoke` kill switch and the G10 transfer sweep.", "operationId": "revokeEndpoint", "requestBody": { "content": { "application/json": { "example": { "client_id": "oc_Xk3vQ9mT2pLw8RzN5bYc1HdF7gJs4AeU", "token": "rt_example-refresh-token", "token_type_hint": "refresh_token" }, "schema": { "$ref": "#/components/schemas/RevokeRequest" } }, "application/x-www-form-urlencoded": { "schema": { "$ref": "#/components/schemas/RevokeRequest" } } }, "description": "Revocation endpoint request (RFC 7009) — JSON or form-encoded.\n\n``token`` is required either way. ``token_type_hint``\n(``access_token``/``refresh_token``) is a lookup-order optimization only —\nthe server falls through both types regardless (RFC 7009 §2.1).\n``client_id`` belongs to the form-encoded public-client arm (G11): the\nsecret-less client's lineage binding; ignored on the bearer-authenticated\nJSON arm, where the platform identity scopes the revocation instead.", "required": true }, "responses": { "200": { "content": { "application/json": { "schema": {} } }, "description": "Successful Response" }, "400": { "content": { "application/json": { "example": { "error": "invalid_request", "error_description": "missing required parameter" }, "schema": { "$ref": "#/components/schemas/OAuthErrorResponse" } } }, "description": "Form-encoded (RFC 7009) requests only: missing `token` (RFC 6749 §5.2 dialect per RFC 7009 §2.2.1): `{\"error\": \"invalid_request\", \"error_description\": \"...\"}`." }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "404": { "content": { "application/json": { "example": { "detail": "Not Found" }, "schema": { "$ref": "#/components/schemas/RouteNotFoundResponse" } } }, "description": "Form-encoded (RFC 7009) requests only: interactive OAuth for MCP is disabled (`server.mcp.oauth.enabled=false`), so the RFC 7009 arm answers the framework's plain route-not-found 404 (gate state unobservable — same posture as the anonymous DCR door). The bearer-authenticated JSON arm is not gated." }, "413": { "content": { "application/json": { "example": { "error": "invalid_request", "error_description": "request body too large" }, "schema": { "$ref": "#/components/schemas/OAuthErrorResponse" } } }, "description": "Form-encoded (RFC 7009) requests only: declared Content-Length exceeds the 64 KiB raw-body cap (RFC 6749 §5.2 dialect)." }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "429": { "content": { "application/json": { "example": { "error": "slow_down", "error_description": "rate limit exceeded, retry later" }, "schema": { "$ref": "#/components/schemas/OAuthErrorResponse" } } }, "description": "Form-encoded (RFC 7009) requests only: per-IP rate limit exceeded (`Retry-After` header set; RFC 6749 §5.2 dialect body, `error=slow_down` per RFC 8628 §3.5)." }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [], "summary": "Revoke Endpoint", "tags": [ "OAuth" ] }, "summary": "Revoke Endpoint" }, "/oauth/token": { "description": "`POST`: Token Endpoint.", "post": { "description": "Exchange a refresh token, JWT assertion, or authorization code for tokens.\n\nError responses speak the RFC 6749 §5.2 dialect (top-level ``error`` +\n``error_description``), NOT platform Problem Details — reshaped by\n``_TokenRoute``. Malformed/missing parameters answer ``invalid_request``;\nfailed client authentication answers ``invalid_client`` (status 401 with a\n``WWW-Authenticate: Basic`` challenge when the client attempted HTTP Basic,\n400 otherwise). On the refresh arm, a revoked consent grant answers\n``invalid_grant`` with ``error_description: \"consent grant has been\nrevoked\"`` — terminal; restart the authorization flow.", "operationId": "tokenEndpoint", "requestBody": { "content": { "application/json": { "schema": { "description": "Token endpoint request — accepts both JSON and form-encoded (RFC 6749).", "properties": { "assertion": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Assertion", "x-sensitive": true }, "client_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Client Id" }, "client_secret": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Client Secret", "x-sensitive": true }, "code": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Code" }, "code_verifier": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Code Verifier" }, "grant_type": { "title": "Grant Type", "type": "string" }, "redirect_uri": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Redirect Uri" }, "refresh_token": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Refresh Token", "x-sensitive": true } }, "required": [ "grant_type" ], "title": "TokenRequest", "type": "object" } }, "application/x-www-form-urlencoded": { "schema": { "description": "Token endpoint request — accepts both JSON and form-encoded (RFC 6749).", "properties": { "assertion": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Assertion", "x-sensitive": true }, "client_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Client Id" }, "client_secret": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Client Secret", "x-sensitive": true }, "code": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Code" }, "code_verifier": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Code Verifier" }, "grant_type": { "title": "Grant Type", "type": "string" }, "redirect_uri": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Redirect Uri" }, "refresh_token": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Refresh Token", "x-sensitive": true } }, "required": [ "grant_type" ], "title": "TokenRequest", "type": "object" } } }, "description": "Token endpoint request — accepts both JSON and form-encoded (RFC 6749).", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "access_token": "at_example-access-token", "expires_in": 3600, "id_token": "example-id-token", "refresh_token": "rt_example-refresh-token", "scope": "apis:read capabilities:execute", "token_type": "bearer" }, "schema": { "$ref": "#/components/schemas/TokenResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/json": { "example": { "error": "invalid_request", "error_description": "missing required parameter" }, "schema": { "$ref": "#/components/schemas/OAuthErrorResponse" } } }, "description": "RFC 6749 §5.2 error dialect (NOT platform Problem Details — this is a spec-facing endpoint real OAuth/MCP clients parse): `{\"error\": \"invalid_request\" | \"invalid_grant\" | \"invalid_client\" | \"unsupported_grant_type\", \"error_description\": \"...\"}`. `invalid_request` covers malformed/missing parameters; a revoked consent grant surfaces on the refresh arm as `invalid_grant` with `error_description: \"consent grant has been revoked\"` — clients should treat it as terminal and restart the authorization flow. A client whose authentication fails after attempting HTTP Basic (`Authorization` header, RFC 6749 §2.3.1) gets the same `invalid_client` dialect body with status 401 and a `WWW-Authenticate: Basic` challenge, per §5.2." }, "429": { "content": { "application/json": { "example": { "error": "slow_down", "error_description": "rate limit exceeded, retry later" }, "schema": { "$ref": "#/components/schemas/OAuthErrorResponse" } } }, "description": "Per-client+IP rate limit exceeded (`Retry-After` header set; RFC 6749 §5.2 dialect body, `error=slow_down` per RFC 8628 §3.5)." }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [], "summary": "Token Endpoint", "tags": [ "OAuth" ] }, "summary": "Token Endpoint" }, "/permission-rule-sets": { "description": "`GET`: List permission rule sets. `POST`: Create permission rule set.", "get": { "description": "List shared rule sets with per-set rule counts (cursor-paginated).", "operationId": "listPermissionRuleSets", "parameters": [ { "description": "Opaque cursor from a previous page's next_cursor; omit for the first page.", "examples": { "example": { "summary": "Opaque cursor from a previous page", "value": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } }, "in": "query", "name": "cursor", "required": false, "schema": { "anyOf": [ { "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "type": "string" }, { "type": "null" } ], "description": "Opaque cursor from a previous page's next_cursor; omit for the first page.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Cursor" } }, { "description": "Maximum number of rule sets to return (1-200, default 50).", "examples": { "example": { "summary": "Example query value for `limit`", "value": 25 } }, "in": "query", "name": "limit", "required": false, "schema": { "default": 50, "description": "Maximum number of rule sets to return (1-200, default 50).", "examples": [ 25 ], "maximum": 200, "minimum": 1, "title": "Limit", "type": "integer" } } ], "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "created_at": "2026-01-15T09:30:00Z", "created_by": "usr_6968b3987ee4c3ec0b4ee3b9", "curated": true, "description": "Allows GET requests to the Stripe API; denies everything else.", "name": "Stripe read-only", "rule_count": 2, "rule_set_id": "prs_6968b3987c22b63e87e79f05" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" }, "schema": { "$ref": "#/components/schemas/RuleSetListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List permission rule sets", "tags": [ "Permission Rule Sets" ] }, "post": { "description": "Create a named, reusable list of permission rules.\n\nAttach the set to any number of agent-credential bindings\n(`PUT /credentials/{credential_id}/agents/{agent_id}/rule-set`); editing\nits rules later updates every attached binding at once, so a policy\nchange such as \"block this operation everywhere\" is a single edit.\nSupply a unique `name`, an optional `description`, and optional initial\nordered `rules`. A set created by an `org:admin` is *curated*: any\n`credentials:write` holder may attach it, but only an `org:admin` may\nedit it. Returns the set with its rules; 409 (`rule_set_name_conflict`)\nif the name is taken.", "operationId": "createPermissionRuleSet", "requestBody": { "content": { "application/json": { "example": { "description": "Allows GET requests to the Stripe API; denies everything else.", "name": "Stripe read-only", "rules": [ { "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] }, "schema": { "$ref": "#/components/schemas/RuleSetCreateRequest" } } }, "description": "Create a shared permission rule set (theme 5 phase 1, Q-04).", "required": true }, "responses": { "201": { "content": { "application/json": { "example": { "binding_count": 3, "created_at": "2026-01-15T09:30:00Z", "created_by": "usr_6968b3987ee4c3ec0b4ee3b9", "curated": true, "description": "Allows GET requests to the Stripe API; denies everything else.", "name": "Stripe read-only", "rule_set_id": "prs_6968b3987c22b63e87e79f05", "rules": [ { "_comment": "Read-only access to charges.", "_system": false, "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] }, "schema": { "$ref": "#/components/schemas/RuleSetResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "409": { "content": { "application/problem+json": { "example": { "detail": "The request conflicts with the current state of the resource.", "instance": "/example/path", "status": 409, "title": "Conflict", "type": "conflict" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Conflict" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Create permission rule set", "tags": [ "Permission Rule Sets" ] }, "summary": "List permission rule sets; Create permission rule set" }, "/permission-rule-sets/{rule_set_id}": { "delete": { "description": "Permanently delete a rule set that no binding uses.\n\nDetach the set from every binding first: while any binding still\nreferences it the delete fails with 409 (`rule_set_in_use`) and nothing\nchanges. Same edit permission as updating the set (403\n`rule_set_access_denied`). Returns 204.", "operationId": "deletePermissionRuleSet", "parameters": [ { "description": "ID of the permission rule set.", "examples": { "example": { "summary": "Permission rule set ID", "value": "prs_6968b3987c22b63e87e79f05" } }, "in": "path", "name": "rule_set_id", "required": true, "schema": { "description": "ID of the permission rule set.", "examples": [ "prs_6968b3987c22b63e87e79f05" ], "title": "Rule Set Id", "type": "string" } } ], "responses": { "204": { "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "409": { "content": { "application/problem+json": { "example": { "detail": "The request conflicts with the current state of the resource.", "instance": "/example/path", "status": 409, "title": "Conflict", "type": "conflict" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Conflict" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Delete permission rule set", "tags": [ "Permission Rule Sets" ] }, "description": "`GET`: Get permission rule set. `PATCH`: Rename or re-describe a permission rule set. `DELETE`: Delete permission rule set.", "get": { "description": "Get a rule set with its ordered rules and referencing-binding count.", "operationId": "getPermissionRuleSet", "parameters": [ { "description": "ID of the permission rule set.", "examples": { "example": { "summary": "Permission rule set ID", "value": "prs_6968b3987c22b63e87e79f05" } }, "in": "path", "name": "rule_set_id", "required": true, "schema": { "description": "ID of the permission rule set.", "examples": [ "prs_6968b3987c22b63e87e79f05" ], "title": "Rule Set Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "binding_count": 3, "created_at": "2026-01-15T09:30:00Z", "created_by": "usr_6968b3987ee4c3ec0b4ee3b9", "curated": true, "description": "Allows GET requests to the Stripe API; denies everything else.", "name": "Stripe read-only", "rule_set_id": "prs_6968b3987c22b63e87e79f05", "rules": [ { "_comment": "Read-only access to charges.", "_system": false, "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] }, "schema": { "$ref": "#/components/schemas/RuleSetResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get permission rule set", "tags": [ "Permission Rule Sets" ] }, "patch": { "description": "Change a rule set's `name` and/or `description`.\n\nThe rules themselves are replaced separately, with\n`PUT /permission-rule-sets/{rule_set_id}/rules`. A curated set is editable\nonly by an `org:admin`; any other set by its creator or an `org:admin`\n(403 `rule_set_access_denied` otherwise). Returns the updated set with\nits rules and the number of bindings referencing it; 409\n(`rule_set_name_conflict`) if the new name is taken.", "operationId": "updatePermissionRuleSet", "parameters": [ { "description": "ID of the permission rule set.", "examples": { "example": { "summary": "Permission rule set ID", "value": "prs_6968b3987c22b63e87e79f05" } }, "in": "path", "name": "rule_set_id", "required": true, "schema": { "description": "ID of the permission rule set.", "examples": [ "prs_6968b3987c22b63e87e79f05" ], "title": "Rule Set Id", "type": "string" } } ], "requestBody": { "content": { "application/json": { "example": { "description": "Allows GET requests to the Stripe API; denies everything else.", "name": "Stripe read-only" }, "schema": { "$ref": "#/components/schemas/RuleSetUpdateRequest" } } }, "description": "Rename or re-describe a rule set.", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "binding_count": 3, "created_at": "2026-01-15T09:30:00Z", "created_by": "usr_6968b3987ee4c3ec0b4ee3b9", "curated": true, "description": "Allows GET requests to the Stripe API; denies everything else.", "name": "Stripe read-only", "rule_set_id": "prs_6968b3987c22b63e87e79f05", "rules": [ { "_comment": "Read-only access to charges.", "_system": false, "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] }, "schema": { "$ref": "#/components/schemas/RuleSetResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Rename or re-describe a permission rule set", "tags": [ "Permission Rule Sets" ] }, "summary": "Get permission rule set; Rename or re-describe a permission rule set; Delete permission rule set" }, "/permission-rule-sets/{rule_set_id}/rules": { "description": "`PUT`: Replace all rules in a permission rule set.", "put": { "description": "Replace a rule set's entire ordered rule list with the body.\n\nThis is a full replacement, not a merge: user rules missing from the body\nare removed, and an empty list clears them. Platform-managed system rules\n(`_system: true`) are kept. The request is idempotent.\nEvery binding attached to the set enforces the new rules immediately.\nSame edit permission as updating the set (403 `rule_set_access_denied`).\nReturns the stored rules in order.", "operationId": "replacePermissionRuleSetRules", "parameters": [ { "description": "ID of the permission rule set.", "examples": { "example": { "summary": "Permission rule set ID", "value": "prs_6968b3987c22b63e87e79f05" } }, "in": "path", "name": "rule_set_id", "required": true, "schema": { "description": "ID of the permission rule set.", "examples": [ "prs_6968b3987c22b63e87e79f05" ], "title": "Rule Set Id", "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "items": { "$ref": "#/components/schemas/PermissionRuleSchema" }, "maxItems": 100, "title": "Body", "type": "array" } } }, "description": "Request payload for the `replacePermissionRuleSetRules` operation.", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "_comment": "Read-only access to charges.", "_system": false, "effect": "allow", "match_mode": "prefix", "methods": [ "GET" ], "operations": [ "listCharges" ], "path": "/v1/charges" } ] }, "schema": { "$ref": "#/components/schemas/PermissionRuleListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Replace all rules in a permission rule set", "tags": [ "Permission Rule Sets" ] }, "summary": "Replace all rules in a permission rule set" }, "/permissions": { "description": "`GET`: List the permission catalogue.", "get": { "description": "List every permission, flagged with whether the caller may grant it to an agent.\n\nEach entry gives the permission `name`, a `description`, the permissions\nit `implies`, and `grantable_by_caller` — whether `POST /agents` and\n`PUT /agents/{agent_id}/permissions` would accept it from this caller.\n`org:admin` is listed only to callers who hold it. Use it to build an\nagent permission picker. Any signed-in caller may call it.", "operationId": "listPermissions", "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "description": "Create, update, and disable users", "grantable_by_caller": true, "implies": [ "users:read" ], "name": "users:write" } ] }, "schema": { "$ref": "#/components/schemas/PermissionListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List the permission catalogue", "tags": [ "Permissions" ] }, "summary": "List the permission catalogue" }, "/register": { "description": "`POST`: Register Endpoint.", "post": { "description": "Register a new agent client (RFC 7591).", "operationId": "registerEndpoint", "requestBody": { "content": { "application/json": { "example": { "client_name": "invoice-reconciler", "grant_types": [ "urn:ietf:params:oauth:grant-type:jwt-bearer" ], "jwks": { "keys": [ { "crv": "Ed25519", "kid": "agent-key-1", "kty": "OKP", "x": "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo" } ] }, "scope": "apis:read capabilities:execute", "token_endpoint_auth_method": "private_key_jwt" }, "schema": { "$ref": "#/components/schemas/RegisterRequest" } } }, "description": "POST /register request body.", "required": true }, "responses": { "201": { "content": { "application/json": { "example": { "claim_token": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk", "client_id": "agnt_6968b3984d1c238dbe7e2e29", "grant_types": [ "urn:ietf:params:oauth:grant-type:jwt-bearer" ], "registration_access_token": "rat_example-secret", "registration_client_uri": "https://jentic.example.com/register/agnt_6968b3984d1c238dbe7e2e29", "status": "pending", "token_endpoint_auth_method": "private_key_jwt" }, "schema": { "$ref": "#/components/schemas/RegisterResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [], "summary": "Register Endpoint", "tags": [ "Agent Registration" ] }, "summary": "Register Endpoint" }, "/register/{agent_id}": { "delete": { "description": "Client deletion not supported — returns 403.", "operationId": "deleteRegistrationEndpoint", "parameters": [ { "description": "ID of the registered agent (its client_id).", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the registered agent (its client_id).", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "schema": {} } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Delete Registration Endpoint", "tags": [ "Agent Registration" ] }, "description": "`GET`: Poll Status Endpoint. `PUT`: Update Registration Endpoint. `DELETE`: Delete Registration Endpoint.", "get": { "description": "Poll registration status (RFC 7592).", "operationId": "pollStatusEndpoint", "parameters": [ { "description": "ID of the registered agent (its client_id).", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the registered agent (its client_id).", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "client_id": "agnt_6968b3984d1c238dbe7e2e29", "grant_types": [ "urn:ietf:params:oauth:grant-type:jwt-bearer" ], "status": "active", "token_endpoint_auth_method": "private_key_jwt" }, "schema": { "$ref": "#/components/schemas/RegistrationStatusResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [], "summary": "Poll Status Endpoint", "tags": [ "Agent Registration" ] }, "put": { "description": "Client update not supported — returns 403.", "operationId": "updateRegistrationEndpoint", "parameters": [ { "description": "ID of the registered agent (its client_id).", "examples": { "example": { "summary": "Agent ID", "value": "agnt_6968b3984d1c238dbe7e2e29" } }, "in": "path", "name": "agent_id", "required": true, "schema": { "description": "ID of the registered agent (its client_id).", "examples": [ "agnt_6968b3984d1c238dbe7e2e29" ], "title": "Agent Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "schema": {} } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Update Registration Endpoint", "tags": [ "Agent Registration" ] }, "summary": "Poll Status Endpoint; Update Registration Endpoint; Delete Registration Endpoint" }, "/search": { "description": "`POST`: Search operations.", "post": { "description": "Lexical (full-text) search over registered API operations.", "operationId": "searchOperations", "requestBody": { "content": { "application/json": { "example": { "apis": [ "stripe.com/stripe" ], "cursor": "eyJkIjogMC4yODE2LCAiaWQiOiAib3BfZjkyZDY5ZjE2MjFmMzgxYmNlOGFhZmY0NzA1M2M2MWIwNjlmZmUzNCJ9", "limit": 10, "query": "list recent charges", "revision_pins": { "stripe.com/stripe/2024-04-10": "3f2b8c1e-7d4a-4e9b-a6c5-1d2e3f4a5b6c" } }, "schema": { "$ref": "#/components/schemas/SearchRequest" } } }, "description": "POST /search request body.", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "_links": { "inspect": "https://jentic.example.com/inspect?id=GET%20https%3A%2F%2Fapi.stripe.com%2Fv1%2Fcharges" }, "api": { "host": "api.stripe.com", "name": "stripe", "vendor": "stripe.com", "version": "2024-04-10" }, "description": "Returns a list of charges you've previously created, newest first.", "method": "GET", "name": "List all charges", "operation_id": "op_f92d69f1621f381bce8aaff47053c61b069ffe34", "relevance_score": 0.87, "target": "GET:https://api.stripe.com/v1/charges", "type": "operation", "url": "https://api.stripe.com/v1/charges" } ], "has_more": true, "next_cursor": "eyJkIjogMC4yODE2LCAiaWQiOiAib3BfZjkyZDY5ZjE2MjFmMzgxYmNlOGFhZmY0NzA1M2M2MWIwNjlmZmUzNCJ9" }, "schema": { "$ref": "#/components/schemas/SearchResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Search operations", "tags": [ "Search" ] }, "summary": "Search operations" }, "/system/version": { "description": "`GET`: Running and latest-available app version.", "get": { "description": "Return the running version and the latest available release.\n\nRequires an authenticated session (any valid caller; no special\npermission). The SPA reads it from inside the signed-in shell to show the\ncurrent version and, when a newer release is available, an update banner.\nThe latest release is resolved best-effort (cached); on any failure it is\n``null`` and no banner shows.", "operationId": "getVersion", "responses": { "200": { "content": { "application/json": { "example": { "current": "0.42.2", "latest": "0.43.0", "update_available": true }, "schema": { "$ref": "#/components/schemas/VersionResponse" } } }, "description": "Successful Response" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Running and latest-available app version", "tags": [ "System" ] }, "summary": "Running and latest-available app version" }, "/users": { "description": "`GET`: List Users. `POST`: Create User.", "get": { "description": "List users with cursor-based pagination.\n\nScoped to the caller: org admins see every user; anyone else sees only themselves.", "operationId": "listUsers", "parameters": [ { "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": { "example": { "summary": "Opaque cursor from a previous page", "value": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" } }, "in": "query", "name": "cursor", "required": false, "schema": { "anyOf": [ { "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "type": "string" }, { "type": "null" } ], "description": "Opaque cursor from a previous page's `next_cursor`; omit for the first page.", "examples": [ "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" ], "title": "Cursor" } }, { "description": "Maximum number of users to return (1-200, default 50).", "examples": { "example": { "summary": "Example query value for `limit`", "value": 25 } }, "in": "query", "name": "limit", "required": false, "schema": { "default": 50, "description": "Maximum number of users to return (1-200, default 50).", "examples": [ 25 ], "maximum": 200, "minimum": 1, "title": "Limit", "type": "integer" } }, { "description": "Only return users with this stored invite state; lapsed invites are stored as `pending`, so `expired` matches no users.", "examples": { "example": { "summary": "Example query value for `invite_state`", "value": "pending" } }, "in": "query", "name": "invite_state", "required": false, "schema": { "anyOf": [ { "$ref": "#/components/schemas/InviteState" }, { "type": "null" } ], "description": "Only return users with this stored invite state; lapsed invites are stored as `pending`, so `expired` matches no users.", "examples": [ "pending" ], "title": "Invite State" } } ], "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "active": true, "auth_provider": "external", "created_at": "2026-01-15T09:30:00Z", "email": "ada@example.com", "external_subject_id": "auth0|6568b3984d1c238dbe7e2e29", "first_name": "Ada", "id": "usr_6968b3987ee4c3ec0b4ee3b9", "invite_state": "accepted", "last_name": "Lovelace", "must_change_password": false, "name": "Ada Lovelace", "permissions": { "assigned": [ "users:write", "agents:read" ], "effective": [ { "implied_by": "users:write", "name": "users:read" } ] }, "updated_at": "2026-01-20T14:05:00Z" } ], "has_more": true, "next_cursor": "eyJ0IjogIjIwMjYtMDEtMTVUMDk6MzA6MDArMDA6MDAiLCAiaWQiOiAiM2YyYjhjMWUtN2Q0YS00ZTliLWE2YzUtMWQyZTNmNGE1YjZjIn0=" }, "schema": { "$ref": "#/components/schemas/UserListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List Users", "tags": [ "Users" ] }, "post": { "description": "Create a new user and issue an invite token.", "operationId": "createUser", "requestBody": { "content": { "application/json": { "example": { "email": "ada@example.com", "first_name": "Ada", "last_name": "Lovelace", "permissions": [ "users:read", "agents:read" ] }, "schema": { "$ref": "#/components/schemas/UserCreateRequest" } } }, "description": "Request body for creating a new user.", "required": true }, "responses": { "201": { "content": { "application/json": { "example": { "invite_expires_at": "2026-01-22T09:30:00Z", "invite_token": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk", "user": { "active": true, "auth_provider": "external", "created_at": "2026-01-15T09:30:00Z", "email": "ada@example.com", "external_subject_id": "auth0|6568b3984d1c238dbe7e2e29", "first_name": "Ada", "id": "usr_6968b3987ee4c3ec0b4ee3b9", "invite_state": "accepted", "last_name": "Lovelace", "must_change_password": false, "name": "Ada Lovelace", "permissions": { "assigned": [ "users:write", "agents:read" ], "effective": [ { "implied_by": "users:write", "name": "users:read" } ] }, "updated_at": "2026-01-20T14:05:00Z" } }, "schema": { "$ref": "#/components/schemas/UserCreatedResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Create User", "tags": [ "Users" ] }, "summary": "List Users; Create User" }, "/users/me": { "description": "`GET`: Get current user.", "get": { "description": "Return the authenticated user's profile.", "operationId": "getCurrentUser", "responses": { "200": { "content": { "application/json": { "example": { "active": true, "created_at": "2026-01-15T09:30:00Z", "email": "ada@example.com", "first_name": "Ada", "id": "usr_6968b3987ee4c3ec0b4ee3b9", "last_name": "Lovelace", "must_change_password": false, "permissions": [ "users:write", "users:read", "agents:read" ], "updated_at": "2026-01-20T14:05:00Z" }, "schema": { "$ref": "#/components/schemas/CurrentUserResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get current user", "tags": [ "Users" ] }, "summary": "Get current user" }, "/users/me:change-password": { "description": "`POST`: Change own password.", "post": { "description": "Change the authenticated user's password and return a fresh token.\n\nA new token is required because the caller's current token still carries the\nstale ``must_change_password`` claim; returning a re-minted token is what\nactually clears the rotation gate client-side.", "operationId": "changePassword", "requestBody": { "content": { "application/json": { "example": { "current_password": "example-password", "new_password": "example-new-password" }, "schema": { "$ref": "#/components/schemas/ChangePasswordRequest" } } }, "description": "Payload for changing own password.", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "access_token": "example-access-token", "expires_in": 3600, "must_change_password": false, "token_type": "bearer" }, "schema": { "$ref": "#/components/schemas/LoginResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Change own password", "tags": [ "Users" ] }, "summary": "Change own password" }, "/users/{user_id}": { "delete": { "description": "Delete a user account (terminal-but-kept).\n\nThe row is retained — the account is anonymized (tombstone email) and\ndeactivated so history and audit references stay resolvable — but the\naction is terminal: there is no re-enable arm. For the reversible kill\nswitch use ``:disable`` / ``:enable`` instead.", "operationId": "deleteUser", "parameters": [ { "description": "ID of the user.", "examples": { "example": { "summary": "User ID", "value": "usr_6968b3987ee4c3ec0b4ee3b9" } }, "in": "path", "name": "user_id", "required": true, "schema": { "description": "ID of the user.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "User Id", "type": "string" } } ], "responses": { "204": { "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "409": { "content": { "application/problem+json": { "example": { "detail": "The request conflicts with the current state of the resource.", "instance": "/example/path", "status": 409, "title": "Conflict", "type": "conflict" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "The user is the last active org:admin" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Delete User", "tags": [ "Users" ] }, "description": "`GET`: Get User. `PATCH`: Update User. `DELETE`: Delete User.", "get": { "description": "Get a user by ID.\n\nScoped to the caller: org admins can read any user; anyone else only themselves.\nAny other user answers 404.", "operationId": "getUser", "parameters": [ { "description": "ID of the user.", "examples": { "example": { "summary": "User ID", "value": "usr_6968b3987ee4c3ec0b4ee3b9" } }, "in": "path", "name": "user_id", "required": true, "schema": { "description": "ID of the user.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "User Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "active": true, "auth_provider": "external", "created_at": "2026-01-15T09:30:00Z", "email": "ada@example.com", "external_subject_id": "auth0|6568b3984d1c238dbe7e2e29", "first_name": "Ada", "id": "usr_6968b3987ee4c3ec0b4ee3b9", "invite_state": "accepted", "last_name": "Lovelace", "must_change_password": false, "name": "Ada Lovelace", "permissions": { "assigned": [ "users:write", "agents:read" ], "effective": [ { "implied_by": "users:write", "name": "users:read" } ] }, "updated_at": "2026-01-20T14:05:00Z" }, "schema": { "$ref": "#/components/schemas/UserResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get User", "tags": [ "Users" ] }, "patch": { "description": "Update a user's profile fields.", "operationId": "updateUser", "parameters": [ { "description": "ID of the user.", "examples": { "example": { "summary": "User ID", "value": "usr_6968b3987ee4c3ec0b4ee3b9" } }, "in": "path", "name": "user_id", "required": true, "schema": { "description": "ID of the user.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "User Id", "type": "string" } } ], "requestBody": { "content": { "application/json": { "example": { "email": "ada.lovelace@example.com", "first_name": "Ada", "last_name": "Lovelace" }, "schema": { "$ref": "#/components/schemas/UserUpdateRequest" } } }, "description": "Request body for updating a user.", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "active": true, "auth_provider": "external", "created_at": "2026-01-15T09:30:00Z", "email": "ada@example.com", "external_subject_id": "auth0|6568b3984d1c238dbe7e2e29", "first_name": "Ada", "id": "usr_6968b3987ee4c3ec0b4ee3b9", "invite_state": "accepted", "last_name": "Lovelace", "must_change_password": false, "name": "Ada Lovelace", "permissions": { "assigned": [ "users:write", "agents:read" ], "effective": [ { "implied_by": "users:write", "name": "users:read" } ] }, "updated_at": "2026-01-20T14:05:00Z" }, "schema": { "$ref": "#/components/schemas/UserResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Update User", "tags": [ "Users" ] }, "summary": "Get User; Update User; Delete User" }, "/users/{user_id}/permissions": { "description": "`PUT`: Set User Permissions.", "put": { "description": "Set the assigned permissions for a user.", "operationId": "setUserPermissions", "parameters": [ { "description": "ID of the user.", "examples": { "example": { "summary": "User ID", "value": "usr_6968b3987ee4c3ec0b4ee3b9" } }, "in": "path", "name": "user_id", "required": true, "schema": { "description": "ID of the user.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "User Id", "type": "string" } } ], "requestBody": { "content": { "application/json": { "example": { "permissions": [ "users:write", "agents:read" ] }, "schema": { "$ref": "#/components/schemas/SetPermissionsRequest" } } }, "description": "Request body for setting user permissions.", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "active": true, "auth_provider": "external", "created_at": "2026-01-15T09:30:00Z", "email": "ada@example.com", "external_subject_id": "auth0|6568b3984d1c238dbe7e2e29", "first_name": "Ada", "id": "usr_6968b3987ee4c3ec0b4ee3b9", "invite_state": "accepted", "last_name": "Lovelace", "must_change_password": false, "name": "Ada Lovelace", "permissions": { "assigned": [ "users:write", "agents:read" ], "effective": [ { "implied_by": "users:write", "name": "users:read" } ] }, "updated_at": "2026-01-20T14:05:00Z" }, "schema": { "$ref": "#/components/schemas/UserResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "409": { "content": { "application/problem+json": { "example": { "detail": "The request conflicts with the current state of the resource.", "instance": "/example/path", "status": 409, "title": "Conflict", "type": "conflict" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Would remove org:admin from the last active org:admin" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Set User Permissions", "tags": [ "Users" ] }, "summary": "Set User Permissions" }, "/users/{user_id}:disable": { "description": "`POST`: Disable User.", "post": { "description": "Disable a user account.", "operationId": "disableUser", "parameters": [ { "description": "ID of the user.", "examples": { "example": { "summary": "User ID", "value": "usr_6968b3987ee4c3ec0b4ee3b9" } }, "in": "path", "name": "user_id", "required": true, "schema": { "description": "ID of the user.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "User Id", "type": "string" } } ], "responses": { "204": { "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "404": { "content": { "application/problem+json": { "example": { "detail": "The requested resource does not exist or is not visible to you.", "instance": "/example/path", "status": 404, "title": "Not Found", "type": "not_found" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Not Found" }, "409": { "content": { "application/problem+json": { "example": { "detail": "The request conflicts with the current state of the resource.", "instance": "/example/path", "status": 409, "title": "Conflict", "type": "conflict" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "The user is the last active org:admin" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Disable User", "tags": [ "Users" ] }, "summary": "Disable User" }, "/users/{user_id}:enable": { "description": "`POST`: Enable User.", "post": { "description": "Enable a user account.", "operationId": "enableUser", "parameters": [ { "description": "ID of the user.", "examples": { "example": { "summary": "User ID", "value": "usr_6968b3987ee4c3ec0b4ee3b9" } }, "in": "path", "name": "user_id", "required": true, "schema": { "description": "ID of the user.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "User Id", "type": "string" } } ], "responses": { "204": { "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Enable User", "tags": [ "Users" ] }, "summary": "Enable User" }, "/users/{user_id}:reissue-invite": { "description": "`POST`: Reissue Invite.", "post": { "description": "Reissue an invite token for a user.", "operationId": "reissueInvite", "parameters": [ { "description": "ID of the user.", "examples": { "example": { "summary": "User ID", "value": "usr_6968b3987ee4c3ec0b4ee3b9" } }, "in": "path", "name": "user_id", "required": true, "schema": { "description": "ID of the user.", "examples": [ "usr_6968b3987ee4c3ec0b4ee3b9" ], "title": "User Id", "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "example": { "expires_at": "2026-01-22T09:30:00Z", "token": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" }, "schema": { "$ref": "#/components/schemas/InviteIssuedResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Reissue Invite", "tags": [ "Users" ] }, "summary": "Reissue Invite" }, "/users:create-admin": { "description": "`POST`: Create first admin (one-time setup).", "post": { "description": "First-run setup: create the first admin user and auto-login.\n\nUnauthenticated by design — there is no admin to authenticate as yet. The\noperation self-closes once any user exists (returns 410 ``setup_already_complete``\nthereafter), so it is safe to expose only during first boot.", "operationId": "createAdmin", "requestBody": { "content": { "application/json": { "example": { "email": "admin@example.com", "first_name": "Ada", "last_name": "Lovelace", "password": "example-password" }, "schema": { "$ref": "#/components/schemas/CreateAdminRequest" } } }, "description": "Payload for first-run admin creation (one-time setup).", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "access_token": "example-access-token", "expires_in": 3600, "must_change_password": false, "token_type": "bearer" }, "schema": { "$ref": "#/components/schemas/LoginResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "410": { "content": { "application/problem+json": { "example": { "detail": "The resource is no longer available and the operation has self-closed.", "instance": "/example/path", "status": 410, "title": "Gone", "type": "gone" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Setup already complete — the first admin exists and this endpoint is closed." }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [], "summary": "Create first admin (one-time setup)", "tags": [ "Users" ] }, "summary": "Create first admin (one-time setup)" }, "/users:redeem-invite": { "description": "`POST`: Redeem invite.", "post": { "description": "Redeem an invite token, set password, and return a JWT.", "operationId": "redeemInvite", "requestBody": { "content": { "application/json": { "example": { "invite_token": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk", "password": "example-password" }, "schema": { "$ref": "#/components/schemas/RedeemInviteRequest" } } }, "description": "Payload for redeeming an invite token.", "required": true }, "responses": { "200": { "content": { "application/json": { "example": { "access_token": "example-access-token", "expires_in": 3600, "must_change_password": false, "token_type": "bearer" }, "schema": { "$ref": "#/components/schemas/LoginResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [], "summary": "Redeem invite", "tags": [ "Users" ] }, "summary": "Redeem invite" }, "/vendors": { "description": "`GET`: List verified vendors.", "get": { "description": "Public metadata for every vendor known to the platform.\n\nUnioned across two sources: admin-registered ``oauth_app_registrations``\nrows and the platform-shipped ``vendors`` config. The two never dedupe —\neach active registration and each config entry is its own picker card,\nand ``flow_kinds`` lists every flow that card can run. Never returns\nsecrets.", "operationId": "listVendors", "responses": { "200": { "content": { "application/json": { "example": { "data": [ { "catalog_api_id": "github.com/api.github.com", "display_name": "GitHub", "entry_id": "oar_6968b39821e5f89a6975f501", "flow_kinds": [ "authorization_code" ], "key": "github", "name": "MyOrg GitHub", "registration_id": "oar_6968b39821e5f89a6975f501", "source": "db", "vendor": "github.com/api.github.com" } ] }, "schema": { "$ref": "#/components/schemas/VendorListResponse" } } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "List verified vendors", "tags": [ "Vendors" ] }, "summary": "List verified vendors" }, "/vendors/{vendor_key}/auth-capabilities": { "description": "`GET`: Get a vendor's OAuth flows and scopes.", "get": { "description": "Describe how to connect a vendor: its OAuth flows and scope catalogue.\n\n`vendor_key` is a key from `GET /vendors`. Returns the vendor's display\nname, the OAuth `flows` it supports (`authorization_code` and/or\n`device_authorization`), and every scope with its `classification`\n(`read`, `write` or `admin`), whether it is requested by default, and a\ndescription. Use it to build a connect screen before starting a connect\nsession. When the vendor has several admin-registered OAuth apps, pass\n`oauth_app_registration_id` to pick one; without it the request fails\nwith 400 (`ambiguous_vendor`). The OAuth client secret is never returned.\nAn unknown vendor returns 404 (`unknown_vendor`).", "operationId": "getAuthCapabilities", "parameters": [ { "description": "Vendor registry key.", "examples": { "example": { "summary": "Vendor registry key", "value": "github" } }, "in": "path", "name": "vendor_key", "required": true, "schema": { "description": "Vendor registry key.", "examples": [ "github" ], "title": "Vendor Key", "type": "string" } }, { "description": "Pin to a specific admin-registered OAuth app when the vendor has more than one. Returns that registration's scopes + client_id, so the picker's tile and the connect payload stay aligned.", "examples": { "example": { "summary": "OAuth app registration ID", "value": "oar_6968b39821e5f89a6975f501" } }, "in": "query", "name": "oauth_app_registration_id", "required": false, "schema": { "anyOf": [ { "examples": [ "oar_6968b39821e5f89a6975f501" ], "maxLength": 30, "type": "string" }, { "type": "null" } ], "description": "Pin to a specific admin-registered OAuth app when the vendor has more than one. Returns that registration's scopes + client_id, so the picker's tile and the connect payload stay aligned.", "examples": [ "oar_6968b39821e5f89a6975f501" ], "title": "Oauth App Registration Id" } } ], "responses": { "200": { "content": { "application/json": { "schema": {} } }, "description": "Successful Response" }, "400": { "content": { "application/problem+json": { "example": { "detail": "The request was malformed or failed a precondition.", "instance": "/example/path", "status": 400, "title": "Bad Request", "type": "bad_request" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Bad Request" }, "401": { "content": { "application/problem+json": { "example": { "detail": "Authentication is required or the bearer token is invalid.", "instance": "/example/path", "status": 401, "title": "Unauthorized", "type": "unauthorized" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unauthorized" }, "403": { "content": { "application/problem+json": { "example": { "detail": "The authenticated principal lacks the required permission.", "instance": "/example/path", "status": 403, "title": "Forbidden", "type": "forbidden" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Forbidden" }, "422": { "content": { "application/problem+json": { "example": { "detail": "Request validation failed; see errors[] for details.", "errors": [ { "detail": "Field 'name' must not be blank.", "pointer": "#/name" } ], "instance": "/example/path", "status": 422, "title": "Unprocessable Entity", "type": "validation_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Unprocessable Entity" }, "500": { "content": { "application/problem+json": { "example": { "detail": "An unexpected error occurred.", "instance": "/example/path", "status": 500, "title": "Internal Server Error", "type": "server_error" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Internal Server Error" }, "503": { "content": { "application/problem+json": { "example": { "detail": "The database is temporarily unavailable; please retry.", "instance": "/example/path", "status": 503, "title": "Service Unavailable", "type": "database_unavailable" }, "schema": { "$ref": "#/components/schemas/ProblemDetail" } } }, "description": "Service Unavailable" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "summary": "Get a vendor's OAuth flows and scopes", "tags": [ "Vendors" ] }, "summary": "Get a vendor's OAuth flows and scopes" } }, "security": [ { "BearerAuth": [] }, { "OAuth2": [] } ], "servers": [ { "description": "Same-origin (relative)", "url": "/" } ], "tags": [ { "description": "Part of the **Core / Access** bounded context — the authoritative record of \"who can call what, with which secret\". A `Credential` is the auth secret + header configuration the Broker injects on the way out to an upstream API. Credentials reference registry content via the loose `(vendor, name, version)` identity tuple (see `APIReference`) — there is no foreign key between Core and Registry, by design. Cleartext secret material is returned **exactly once** at creation (and on rotation via `PATCH`). Read paths return a redacted projection — last-N characters, hints, never the secret itself.", "name": "Credentials" }, { "description": "Part of the **Core / Access** bounded context — a `PermissionRuleSet` is a named, shareable ordered rule list (first-match-wins, default-deny) that many direct agent↔credential bindings can point at via their `rule_set_id`, so a policy edit or `permissions:test` stays a single-place operation. A binding with no `rule_set_id` uses its own inline rules instead. Rule sets carry policy, not secrets; deleting one that bindings still reference is refused (409 `rule_set_in_use`).", "name": "Permission Rule Sets" }, { "description": "Part of the **Core / Access** bounded context — the platform-curated catalog of verified vendors that support agent-initiated OAuth connect flows. Each entry describes the OAuth flows available (device_authorization, authorization_code) and the scope catalog with read/write classification. Vendor entries are seeded from operator config, not user-managed — the API surfaces them read-only so the SPA and agents can discover which vendors are available and pick a flow at ``:connect`` time.", "name": "Vendors" }, { "description": "Part of the **Core / Access** bounded context — agent-initiated OAuth connect sessions. A caller (agent or UI) begins a session via ``POST /integrations:connect``, choosing a vendor and requested scope set; the platform provisions a pending credential, initiates the vendor's OAuth flow (device_authorization or authorization_code depending on the vendor), and returns a session id + human-facing challenge (device user_code / authorize_url).\n\nThe initiator polls ``GET /connect-sessions/{id}/status`` until the session reaches ``connected`` (tokens vaulted) or a terminal failure. Sessions are capped by a TTL; unfinished sessions can be cancelled via ``POST /connect-sessions/{id}:cancel``. The ``:confirm`` step is a UI-only hand-off that binds any pre-declared permission rules to the resulting credential.", "name": "Integrations" }, { "description": "The `Api` aggregate root — what APIs are registered for this deployment, addressable by the loose `(vendor, name, version)` tuple. Every successful import lands a new immutable `ApiRevision`; the `Api` carries the live `current_revision_id` plus presentation metadata (`display_name`, `description`, `icon_url`).\n\nMutation surfaces:\n\n- `POST /apis` — async import (url / inline). Returns 202 + `Job (kind=import)`.\n- `PATCH /apis/{vendor}/{name}/{version}` — metadata-only updates (display name, description, icon). Cannot mutate revisions or spec content.\n- `POST /apis/{vendor}/{name}/{version}/revisions/{revision_id}:promote` — make a draft revision live.\n- `POST /apis/{vendor}/{name}/{version}/revisions/{revision_id}:archive` — retire a draft revision.\n- `DELETE /apis/{vendor}/{name}/{version}` — deregister the API and all its revisions.\n\nNewly imported revisions are **never auto-promoted** — callers must explicitly `:promote` to flip the live pointer. Hot-path Broker calls can pin to a specific revision via the `Jentic-Revision` request header for testing without flipping the pointer.\n\nSub-resources of an `Api` live under sibling tags: `API Operations` enumerates the operations exposed by a registered revision; `API Spec` returns the underlying OpenAPI document for tooling.", "name": "APIs" }, { "description": "The caller's own governed host set — the upstream hosts reachable through its credential bindings (admin bindings → credential scopes, suspended or inactive included → registered APIs), deduplicated and sorted. **Always self-scoped**: the set is derived for the authenticated identity; there is no cross-actor or admin variant.\n\nThe response carries a content-derived SHA-256 `digest` (also emitted as a strong `ETag`), so integrators — e.g. a native gate scoping traffic interception per agent — poll with `If-None-Match: \"\"` and receive an empty `304` until the host set actually changes. Deliberately unpaginated: the set is bounded by the caller's own bindings and the digest covers it atomically.", "name": "Governed Hosts" }, { "description": "Sub-resource of **APIs** (Registry bounded context). Enumerate the operations exposed by a registered API — either the live (`current_revision_id`) view or a specific revision. Complements `Search` (ranked discovery) and `Inspect` (single-operation detail) by giving callers the deterministic list of every registered operation under one API without ranking, paging through `Search`, or parsing the spec.\n\nEach row is slim — the structural detail (parameters, response schema, security scheme) lives behind `_links.inspect` for callers that need it.", "name": "API Operations" }, { "description": "Sub-resource of **APIs** (Registry bounded context). Download the underlying OpenAPI document for a registered API — either the live (`current_revision_id`) view or a specific revision. Supports `application/json`, `application/openapi+yaml`, and `application/yaml` via `Accept`-header content negotiation, with `Content-Disposition: attachment; filename=\"...\"` so browser downloads work cleanly.\n\nBy default the response includes any deployment-local overlays merged on top of the imported base. Pass `?overlays=false` to download the raw imported spec instead.", "name": "API Spec" }, { "description": "The public API **catalog** — a registry-side browse/preview/import surface over the Jentic public-APIs GitHub manifest. Powers the Discover experience: list importable APIs (`GET /catalog`, keyset cursor-paginated), preview an entry's operations (`GET /catalog/{api_id}/operations`), refresh the cached manifest (`POST /catalog:refresh`, `org:admin`), and import an entry into the local registry (`POST /catalog/{api_id}:import`).\n\nThe catalog is a cache of an upstream document, distinct from the local registry (`GET /apis`): `/apis` is what this deployment has imported, `/catalog` is what it *could* import. Each entry's `registered` flag reflects whether its `spec_url` already backs a local API revision. Import resolves to a plain fetchable spec URL and reuses the standard async import job — no catalog identity ever crosses into the importer.", "name": "Catalog" }, { "description": "Lexical (full-text) search across registered operations, ranked by relevance. Returns a slim row per operation; each row carries `_links.inspect` pointing into the `Inspect` tag for full structural detail.", "name": "Search" }, { "description": "Resolve a single registered operation to its full structural detail — parameters, response schema, security scheme, server URL. Heavier than `Lookup` (which is the Broker hot path) and separate from `Search` (which only returns ranked summaries). Supports JSON, Markdown, and OpenAPI YAML response formats via `Accept`-header content negotiation.", "name": "Inspect" }, { "description": "The Broker's read interface into Registry — fast, narrow lookup from a real-world URL to a Jentic `operation_id`. Hot path; not for human use. The capability map names this as the Execution → Registry read interface.", "name": "Lookup" }, { "description": "Free-form annotations attached to registry resources — an `Api`, an `ApiRevision`, a registered `operation_id`, an `ExecutionRecord`, or a `Credential`. Used to capture human or agent observations about quirks: *\"this endpoint silently truncates email addresses to 64 chars\"*, *\"this credential rejects calls outside US business hours\"*, *\"this operation needs `Accept: application/json` even though the spec doesn't say so\"*.\n\nNotes are an information surface for agents — they accumulate over time as the platform learns from real executions and surface back through `_links.notes` on the resources they annotate (woven in by individual surfaces as they need it).\n\n**Edit model.** Notes are editable via `PATCH`; each successful edit bumps a monotonic `revision` counter on the `Note`. Use the `If-Match` header on `PATCH` and `DELETE` to guard against concurrent modification.\n\n**Confidence promotion.** Notes carry both a `confidence` value (`observed | suspected | verified`) and a `confidence_source` (`client | platform_promoted`). Today only `client` is written by callers; the `platform_promoted` value is reserved for a future surface that auto-promotes `observed` notes to `verified` once enough matching `execution_feedback` accumulates.\n\n**Authentication.** Any authenticated principal (agent or human) can post any note type. Per-type policy (e.g. only humans may file `correction`) is enforced platform-side and not modelled in the spec.", "name": "Notes" }, { "description": "OpenAPI Overlay 1.0 (`https://spec.openapis.org/overlay/v1.0.0`) documents that correct an imported spec without rewriting it. Overlays capture wrong required fields, missing security schemes, undocumented headers, silent payload truncation, and other places where the upstream spec disagrees with the upstream API's actual behaviour — without forking the spec or waiting for an upstream fix.\n\nOverlays attach to the `Api` aggregate (not to a specific `ApiRevision`) and continue to apply across revision bumps until materially superseded. The optional `target_revision_id` records the revision the overlay was authored against, for auditing.\n\n**Lifecycle.** New overlays start in `pending`. The Broker calls `POST /apis/{vendor}/{name}/{version}/overlays/{overlay_id}:confirm` after the first successful upstream execution that exercised an overlay-patched operation, transitioning the overlay to `confirmed`. This is the platform's only documented data-plane → control-plane writeback. Once `confirmed`, an overlay stays `confirmed` — repeated `:confirm` calls return `200` with the existing record unchanged.\n\n**Edit model.** Overlay documents are editable via `PATCH` only while `pending`. Once `confirmed` (or `deprecated`), the document is immutable — to change a confirmed overlay, submit a new one and let the old one age out via `DELETE` (which soft-deprecates).\n\n**Deletion.** `DELETE` is a **soft-deprecation** — the row is preserved with `status: deprecated` for audit. Deprecated overlays no longer apply to spec-download merges (`?overlays=false` becomes the default for that overlay) but stay queryable via `GET`. There is no hard-delete in this surface.\n\n**Authentication.** Any authenticated principal (agent or human) can submit, edit, confirm, or deprecate overlays. Platform-side rate limits gate abuse.", "name": "Overlays" }, { "description": "Append-only audit log of every Broker call (sync or async) — timing, status, trace IDs, and the upstream API reference (`vendor:name:version`). Bodies are not stored. Records are written by the Broker; this surface is read-only. To walk the history of a single logical request that fanned out into multiple upstream calls, list with `?trace_id={trace_id}`. An execution is visible only to the actor that ran it, the owner of the agent that ran it, and `org:admin`; to any other caller it is indistinguishable from a missing execution (`404`).", "name": "Executions" }, { "description": "In-flight async-job tracker for both Registry import jobs and Broker async-execution jobs — one uniform `Job` shape keyed by `kind`. Lifecycle only — type-specific result payloads (the imported revisions for `import`, upstream response body for `execution`) live under `/jobs/{job_id}/result`. Result availability follows the organisation-level retention policy (one-shot or TTL); once that expires, both `/jobs/{job_id}` and `/jobs/{job_id}/result` `404`. A job is visible only to the actor that created it, the owner of the agent that created it, and `org:admin`; to any other caller it is indistinguishable from a missing job (`404`), including on `:cancel`.", "name": "Jobs" }, { "description": "Curated, severity-tagged event stream surfaced to dashboards and operators. Each event is either **informational** (no action required, e.g. `import.completed`) or **actionable** (requires operator follow-up, e.g. `credential.expiring_soon`, `execution.repeated_failure`). Events reference the underlying `ExecutionRecord` or `Job` via `_links` and share `trace_id` for correlation. Subscribe live via `GET /events/stream` (Server-Sent Events) or poll `GET /events` with a `since=` filter. An event is visible only to the actor it names (`actor_id`), to the subject it is about (for example the owner of the credential or the agent concerned), to the human owner of either when that is an agent, and to `org:admin`; system events with no subject are visible only to `org:admin`. To any other caller an event is indistinguishable from a missing one (`404`).", "name": "Events" }, { "description": "Part of the **Admin / Audit** bounded context — the human roster of the organisation. One organisation, many users; admin surfaces here cover create / list / read / update / delete plus the AIP-style action verbs (`:disable`, `:enable`, `:reissue-invite`). Self-service is intentionally minimal: `GET /users/me` to introspect, `POST /users/me:change-password` to rotate (which re-mints and returns a fresh token, clearing any `must_change_password` gate so the caller need not re-login).\n\n**First-run setup (no default credentials).** The platform ships with an empty users table — there is no seeded `admin@local` account. On a fresh install `GET /health` reports `setup_required: true` (with `next_step: create_admin`). The operator creates the first administrator via `POST /users:create-admin {email, password}`: a one-time, unauthenticated endpoint that succeeds only while no user exists, grants `org:admin`, and returns an auto-login `LoginResponse` with `must_change_password: false` (the operator chose the password, so there is no forced rotation). It **self-closes** — once any user exists it returns `410 setup_already_complete`, so it is safe to leave exposed during first boot; a single-row setup sentinel is the concurrency backstop against racing callers (even ones using different emails). After the first user exists, `setup_required` flips to `false`.\n\n**Onboarding flow.** Admins create new users via `POST /users` (no password supplied). The response carries a one-time `inv_…` invite token shown **once**; the admin hands it off out-of-band (Slack, 1Password, email — there is no platform-side email infrastructure in this revision). The new user redeems via `POST /users:redeem-invite {invite_token, password}` and is auto-logged-in via the returned `LoginResponse`. Tokens default to a 7-day TTL and are single-use; `:reissue-invite` issues a fresh one if the original is lost or expired.\n\n**Authentication.** Today only local (username + password) identity ships. The `User` schema carries `auth_provider: local | external` and an `external_subject_id` field reserved for future SSO integrations (Okta, Cognito, Azure AD); when SSO arrives, those users will be created via a separate provider-specific router. The on-the-wire token contract — `Authorization: Bearer ` — is unchanged either way.\n\n**Disabling and revocation.** `:disable` flips `active=false` and rejects subsequent `POST /auth/login` **and** `POST /auth/refresh`. **Existing JWTs keep working until they expire** (≤ 1 hour with the platform's default TTL). This is a deliberate trade-off; sub-minute revocation would require a server-side session table.\n\n**Session lifetime.** Login JWTs carry a 1-hour TTL. The UI keeps an active session alive by calling `POST /auth/refresh` before expiry (sliding session); refresh re-reads permissions and the `must_change_password` gate from the database and is refused with 401 `session_expired` once the original authentication is older than the absolute window (`admin.auth.session_ttl_seconds`, 12 hours by default), forcing a fresh login.", "name": "Users" }, { "description": "Part of the **Admin / Audit** bounded context — the catalogue of grantable permission strings. Permissions are namespaced `resource:action` strings (`users:write`, `capabilities:execute`, `credentials:read`, …) gating every other surface in the API. The set is platform-defined and small; `GET /permissions` returns it in full, with each entry describing what it does, what it implies (the static implication map; e.g. `capabilities:execute` implies `apis:read` and `executions:read`), and whether the calling user is authorised to grant it.\n\nOne reserved superpower short-circuits individual checks in code: `org:admin` (full deployment-wide access, granted via direct DB action). It is not enumerated to non-holders by `GET /permissions`, and is rejected by `PUT /users/{user_id}/permissions` from any caller who doesn't already hold it.\n\nThe same vocabulary is used for `User.permissions` — the coarse set embedded in the JWT — so the catalogue below covers user assignment. The per-binding fine-grained `PermissionRule[]` (the inner PBAC tier) lives separately on the direct agent↔credential bindings under the `Credentials` tag.", "name": "Permissions" }, { "description": "Operational endpoints for service health and platform tooling. Not part of any bounded context — surfaced here so orchestrators and load balancers have a stable probe target.", "name": "System" }, { "description": "Identity introspection for the calling principal (human or agent) — `GET /me` returns the resolved subject and its permissions behind the presented token.", "name": "Identity" }, { "description": "Agent actors — autonomous principals that call the Broker. Covers the agent lifecycle (list, read, approve / deny, enable / disable, archive) and the credentials directly bound to each agent.", "name": "Agents" }, { "description": "OAuth 2.0 / OIDC endpoints exposed by the platform authorization server — the authorize, token, introspection, and revocation endpoints plus the redirect callback.", "name": "OAuth" }, { "description": "Dynamic agent registration (RFC 7591-style) — register a new agent client, poll registration status, update, or delete a registration.", "name": "Agent Registration" }, { "description": "Unauthenticated metadata discovery — the JWKS document and OAuth authorization server metadata under `/.well-known/*`.", "name": "Discovery" }, { "description": "Unified actor directory — a lightweight read-only view across all actor types (users and agents). Returns ID-to-name mappings for UI cache hydration so dashboards can display friendly names wherever an `actor_id` appears.", "name": "Actors" }, { "description": "Append-only administrative audit trail — who did what, when. Distinct from `Executions` (brokered upstream calls); this records control-plane mutations.", "name": "Audit" }, { "description": "Dashboard-oriented aggregation endpoints — execution volume, success/failure ratios, and top operations over a bounded time window. Results are cached in-process (TTL ~120 s) so concurrent dashboard viewers never stampede the database.", "name": "Monitoring" }, { "description": "Runtime, DB-backed platform configuration. Lets an operator set, read, and list configuration that previously required hand-editing backend YAML and restarting the server — starting with credential provider configs (e.g. Pipedream). A successful write rebuilds the in-process provider registry so the change takes effect without a restart. Secret fields (e.g. `client_secret`) are encrypted at rest and redacted on read. **Topology note:** in the combined (single-process) deployment a write takes effect immediately for all surfaces. In a multi-process deployment the control/broker processes pick up the new config at their next boot, not the instant the admin write lands; cross-process propagation is a tracked follow-up.", "name": "Configuration" }, { "description": "Admin-managed registry of third-party OAuth clients (confidential, secret-bearing). Registered clients integrate with Jentic One via the standard Authorization Code + PKCE flow. Admins can create, list, update, rotate secrets, and disable clients. Disabling a client immediately invalidates all tokens issued through it.", "name": "OAuth Clients" }, { "description": "Admin-managed OAuth application registrations that end users on the instance can SSO through. Each row holds a client_id, endpoints, and (for authorization-code flows) an encrypted client secret. Registrations are per-vendor and per-flow-kind; users then start a connect session against a registration to mint their own tokens.", "name": "OAuth App Registrations" }, { "description": "MCP (Model Context Protocol) transport reporting. The `jentic mcp` stdio server terminates all MCP protocol traffic locally; the control plane only sees plain HTTP. This tag covers the small reporting surface behind it — today, the config-registration report `jentic setup`/`jentic skill init` send after writing an MCP server entry for a detected agent runtime, which feeds the config-written → first-session → first-execute adoption funnel.", "name": "MCP" } ], "x-tagGroups": [ { "name": "Core / Access", "tags": [ "Credentials", "Permission Rule Sets", "Vendors", "Integrations" ] }, { "name": "Registry", "tags": [ "APIs", "API Operations", "API Spec", "Catalog", "Search", "Inspect", "Lookup", "Notes", "Overlays" ] }, { "name": "Admin / Audit", "tags": [ "Users", "Actors", "Permissions", "Executions", "Jobs", "Events", "Audit", "Monitoring", "Configuration", "OAuth Clients", "OAuth App Registrations" ] }, { "name": "Platform Actors", "tags": [ "Identity", "Agents", "OAuth", "Agent Registration", "Discovery" ] }, { "name": "Operations", "tags": [ "System", "MCP" ] } ] }