API referenceidentity
Approve mcp grant request
POST
/v1/mcp/grant-requests/{requestId}:approveAccepts bearer
The signed-in human approves an MCP grant for themselves
HUMAN CONSOLE SESSION ONLY: an API key, a service token and an MCP grant-derived token are 403 PERMISSION_DENIED details.reason SESSION_REQUIRED, so an agent can never approve its own grant.Show more
HUMAN CONSOLE SESSION ONLY: an API key, a service token and an MCP grant-derived token are 403 PERMISSION_DENIED details.reason SESSION_REQUIRED, so an agent can never approve its own grant. The grant is bound to the approving human and to the session (refresh family) the approval came from: logout, logout-all, a password change or reset, user disable, tenant SUSPENDED or OFFBOARDED and session reuse detection all end it. The tenant must be ACTIVE (a SUSPENDED tenant is 403 TENANT_SUSPENDED), the tenant's console toolset switch ON (getMcpSettings; OFF is 403 PERMISSION_DENIED details.reason TOOLSET_DISABLED) and grants enabled on the rung (else 403 PERMISSION_DENIED details.reason GRANTS_DISABLED). A request that is no longer PENDING is 409 CONFLICT details.reason WRONG_STATE. For an authorization-code request the answer carries redirectTo, the client's redirect_uri with code, state and iss, and the browser goes exactly there; the code is single-use and lives 60 s. For a device flow the answer is {approved: true} and the agent's next poll receives the tokens. A grant never reaches a route outside its toolset's read operations, and never one the human cannot reach now. writeOperations, a subset of the request's offered writeOperations, gives write consent for those console commit-lite tools; it needs the step-up proof (stepUpCode or stepUpAssertion; absent 403 STEP_UP_REQUIRED, wrong STEP_UP_FAILED). A ticked write runs only while the tenant keeps it ON, the platform and plane write ceilings are on and the human holds its permission; money and decisions stay unreachable. Emits mcp.grant.approved and writes the audit row mcp.grant.approve (writeOperations, stepUp).Path parameters
- requestIdstringRequired
A pending MCP grant request id, from the consent redirect (?request=) or a user-code lookup.Show more
A pending MCP grant request id, from the consent redirect (?request=) or a user-code lookup. Opaque and unguessable: at least 128 bits from a cryptographic random source, never a sequential or monotonic id, because it is the only handle in the consent URL.
Request body
- toolsetstringRequiredMust equal the request's toolset; on a device flow the human selects it by hand
- console
- supplier
- operator
- operationsarray of stringOptional
- writeOperationsarray of stringOptional
Console only: the write tools ticked, a subset of the request's writeOperations (any other name is 400 VALIDATION details.reason OPERATION_NOT_ALLOWED, field writeOperations); absent or empty = no…Show more
Console only: the write tools ticked, a subset of the request's writeOperations (any other name is 400 VALIDATION details.reason OPERATION_NOT_ALLOWED, field writeOperations); absent or empty = no write consent. Non-empty needs the step-up proof - crossTenantReadsarray of stringOptionalOperator only: the cross-tenant reads ticked, a subset of the request's crossTenantReads; absent or empty = none (the default)
- confirmOwnDevicebooleanOptionalRequired true on a device flow ("I started this on my own device")
- stepUpCodestringOptionalThe approving human's current TOTP code. Send this or stepUpAssertion, not both
- stepUpAssertionobjectOptionalA WebAuthn step-up assertion. Send this or stepUpCode, not both
5 child attributes
- idstringRequiredThe credential id, base64url
- rawIdstringRequiredThe credential id, base64url
- typestringRequired
- public-key
- responseobjectRequired
4 child attributes
- clientDataJSONstringRequiredbase64url
- authenticatorDatastringRequiredbase64url
- signaturestringRequiredbase64url
- userHandlestringOptionalbase64url, or null when the authenticator returns none
- clientExtensionResultsobjectOptional
Responses
- 200ApprovedMcpGrantRequestDecision
- 400ApiErrorResponse
VALIDATION on approveMcpGrantRequest, supplierApproveMcpGrantRequest and opsApproveMcpGrantRequest: toolset missing or not the request's (details.reason TOOLSET_MISMATCH), an operation outside the…Show more
VALIDATION on approveMcpGrantRequest, supplierApproveMcpGrantRequest and opsApproveMcpGrantRequest: toolset missing or not the request's (details.reason TOOLSET_MISMATCH), an operation outside the request's list or an empty list (OPERATION_NOT_ALLOWED, details.field operations), a write tool or a cross-tenant read the request did not offer, or a device flow without confirmOwnDevice true (OWN_DEVICE_CONFIRMATION_REQUIRED). - 401ApiErrorResponse
UNAUTHENTICATED — missing or expired token.Show more
UNAUTHENTICATED — missing or expired token. Declared on every operation because `security` is declared globally at the document root: every route is authenticated, so every route can answer 401. - 403ApiErrorResponse
- 404NOT_FOUND — unknown or expired ref (unguessable refs, 15)ApiErrorResponse
- 405ApiErrorResponse
VALIDATION — the public edge serves GET, POST, PUT, PATCH and DELETE only; any other method is refused before the platform sees it (details.reason METHOD_NOT_ALLOWED, details.source edge).Show more
VALIDATION — the public edge serves GET, POST, PUT, PATCH and DELETE only; any other method is refused before the platform sees it (details.reason METHOD_NOT_ALLOWED, details.source edge). Not retryable as sent. - 409CONFLICT details.reason WRONG_STATE — the grant request is no longer PENDING (already approved or denied, expired, or, for an operator request, AWAITING_SECOND_APPROVAL); details.state says which.ApiErrorResponse
- 413ApiErrorResponse
VALIDATION — the request body is larger than the surface's limit.Show more
VALIDATION — the request body is larger than the surface's limit. Not retryable as sent: shrink the body. Declared on every operation that takes a request body. details carries exactly one key, maxBodyBytes (integer): the limit that applies to this surface, in bytes. - 414ApiErrorResponse
VALIDATION — the request URI (path and query string) is longer than 8 KiB; the public edge refuses it before the platform sees it (details.reason URI_TOO_LONG, details.source edge).Show more
VALIDATION — the request URI (path and query string) is longer than 8 KiB; the public edge refuses it before the platform sees it (details.reason URI_TOO_LONG, details.source edge). Not retryable as sent: send long input in the body of a POST. - 415ApiErrorResponse
VALIDATION — a request body that is not JSON (application/json or application/*+json; a form body only on the OAuth token routes).Show more
VALIDATION — a request body that is not JSON (application/json or application/*+json; a form body only on the OAuth token routes). The public edge refuses it before the platform sees it (details.reason UNSUPPORTED_MEDIA_TYPE, details.source edge). Not retryable as sent: send Content-Type application/json. Declared on every operation that takes a JSON request body. - 500INTERNAL — a bug, and traceId is the support handle.ApiErrorResponse
Errors you should handle
Branch on code and honour retryable — never on the HTTP status alone.
| 400 | VALIDATION Select the toolset this agent asked for before approving. | not retryable |
| 401 | UNAUTHENTICATED The bearer token is expired. Re-authenticate and retry. | not retryable |
| 403 | PERMISSION_DENIED Approving agent connections needs a signed-in person. An agent cannot read or approve its own connection. | not retryable |
| 403 | TENANT_SUSPENDED This organisation is suspended; new agent connections are refused. | not retryable |
| 404 | NOT_FOUND searchRef SR-F-7b31d0a9 is unknown or has expired; re-search | not retryable |
| 405 | VALIDATION This method is not served. | not retryable |
| 409 | CONFLICT This agent connection request has already been decided. | not retryable |
| 413 | VALIDATION The request body is larger than this API accepts (262144 bytes). | not retryable |
| 414 | VALIDATION The request URI is longer than 8 KiB. | not retryable |
| 415 | VALIDATION Send application/json. | not retryable |
| 500 | INTERNAL An unexpected error occurred. Quote the traceId to support. | retryable |