A valid request URL is required to generate request examples{
"orgId": "<string>",
"deviceId": "<string>",
"idempotencyKey": "<string>",
"backendKind": "<string>",
"action": "<string>",
"argsSummary": {},
"status": "pending",
"requestedAt": "2023-11-07T05:31:56Z",
"actor": {
"kind": "api_key",
"viaCopilot": true,
"userId": "<string>",
"apiKeyId": "<string>",
"onBehalfOf": {
"kind": "schedule",
"scheduleId": "<string>",
"userId": "<string>",
"apiKeyId": "<string>"
}
},
"principalKind": "api_key",
"committedAt": "2023-11-07T05:31:56Z",
"failedAt": "2023-11-07T05:31:56Z",
"observedFrame": "<string>",
"error": {},
"reason": "<string>",
"requiresManualReview": true,
"apiKeyId": "<string>",
"reviewedAt": "2023-11-07T05:31:56Z",
"reviewedBy": "<string>"
}{
"error": {
"code": "backend_resolution_failed",
"message": "<string>",
"retryable": true
}
}{
"error": {
"code": "unauthorized",
"reason": "missing_credentials",
"hint": "<string>"
}
}{
"error": {
"code": "backend_resolution_failed",
"message": "<string>",
"retryable": true
}
}{
"error": {
"code": "receipt_not_found",
"message": "<string>"
}
}{
"error": {
"code": "rate_limited",
"message": "<string>"
}
}{
"error": {
"code": "backend_resolution_failed",
"message": "<string>",
"retryable": true
}
}Read one receipt
One recorded action, addressed by the idempotencyKey you sent with it. This is the permanent URL for a receipt: the listing answers what has happened, and this answers what happened in one case, without paging to find it again.
THE KEY IS NOT UNIQUE ON ITS OWN. Idempotency is defined per device, so one organisation may hold the same key on two devices. When it does, this answers 400 and asks for deviceId rather than choosing a receipt for you: a page showing the wrong action with nothing to say so is worse than a refusal. Keys minted by agent runs carry a frame id and never collide, so this is a hand written key’s problem.
A key belonging to another organisation answers 404 exactly as one that was never used does, and a key narrowed to a subset of devices reads only within that subset.
Hosted deployments only. A local checkout does not mount this route, so calling it there is a 404.
A valid request URL is required to generate request examples{
"orgId": "<string>",
"deviceId": "<string>",
"idempotencyKey": "<string>",
"backendKind": "<string>",
"action": "<string>",
"argsSummary": {},
"status": "pending",
"requestedAt": "2023-11-07T05:31:56Z",
"actor": {
"kind": "api_key",
"viaCopilot": true,
"userId": "<string>",
"apiKeyId": "<string>",
"onBehalfOf": {
"kind": "schedule",
"scheduleId": "<string>",
"userId": "<string>",
"apiKeyId": "<string>"
}
},
"principalKind": "api_key",
"committedAt": "2023-11-07T05:31:56Z",
"failedAt": "2023-11-07T05:31:56Z",
"observedFrame": "<string>",
"error": {},
"reason": "<string>",
"requiresManualReview": true,
"apiKeyId": "<string>",
"reviewedAt": "2023-11-07T05:31:56Z",
"reviewedBy": "<string>"
}{
"error": {
"code": "backend_resolution_failed",
"message": "<string>",
"retryable": true
}
}{
"error": {
"code": "unauthorized",
"reason": "missing_credentials",
"hint": "<string>"
}
}{
"error": {
"code": "backend_resolution_failed",
"message": "<string>",
"retryable": true
}
}{
"error": {
"code": "receipt_not_found",
"message": "<string>"
}
}{
"error": {
"code": "rate_limited",
"message": "<string>"
}
}{
"error": {
"code": "backend_resolution_failed",
"message": "<string>",
"retryable": true
}
}Authorizations
The control surface credential. Send Authorization: Bearer <token>.
Two kinds of token are accepted and they are told apart by shape, not by a separate header. A token beginning pbk_ is an org scoped API key, whose public half and secret half are generated together and of which only a hash of the secret is ever stored; anything else is treated as an OAuth 2.1 access token and verified against the authorization server's keys.
Both resolve to the same context: an org, a principal and a set of scopes. Nothing downstream branches on which channel you used, with one deliberate exception, key management, which requires a signed-in person so that a key can never mint another key.
Scopes are enforced when MCP tools are REGISTERED rather than when they are called, so a tool your credential cannot use is absent from tools/list rather than refused mid gesture.
Path Parameters
The key you sent with the action, percent encoded. 1 to 128 printable ASCII characters.
Query Parameters
Which device's receipt, when the same key was used on more than one. Omit it unless the response asks for it.
Response
The receipt.
One recorded action, and who took it. actor names a person or a key by id, so a receipt can be attributed to the particular credential that made the call.
THE LEASE THE ACTION RAN UNDER IS NOT PART OF THIS SHAPE. A receipt used to carry leaseId and fencingToken, and both are gone as of 2026-09-12. They are credentials: a lease id is what releases a lease and a fencing token is what orders writes under it, which is why the get_receipt tool already withheld both and why GET /v1/leases names no lease id either. Reading receipts needs only devices:read, so publishing them here let a read-only credential lift a live lease off the newest receipt and hand it to one that can act. Nothing replaces them on this face.
principalKind and apiKeyId beside it say the same thing in a flatter shape. They are not new: this endpoint has returned them since attribution was added, without declaring them here, and declaring them is part of the same change that added actor. New code should read actor, which is the only one of the two that can name a person.
The key the caller supplied, which is what makes a retry a replay.
Which action was attempted.
A summary of the arguments, not the raw input. Text is bounded and never echoed wholesale.
Where this action ended up.
pending, committed, failed WHO. The same shape answers three questions: who took an action (Receipt.actor), who is holding a device (Lease.holder), and who started a run (RunView.initiator). One shape on purpose, so the three can never disagree about what a given credential is called.
Show child attributes
Show child attributes
SUPERSEDED by actor.kind, and identical to it. Read actor in new code; this stays because a consumer already reads it.
api_key, oauth, dev_token, system, unattributed The frame this action was bound to, when it was bound to one.
Present on a failed receipt.
Why a failure was recorded, where the failure had a classified cause.
The physical outcome is unknown (a crash or a lost transport) and needs reconciliation.
SUPERSEDED by actor.apiKeyId, and identical to it. Read actor in new code.
When a person opened this receipt. Absent until one does, and fixed once set: the first instant is the answer to how long it waited. It records that somebody LOOKED, and not that the action was correct or accepted.
Who looked. A subject id, never a name, and set together with reviewedAt or not at all.