A valid request URL is required to generate request examples{
"receipts": [
{
"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>"
}
],
"nextBefore": "2023-11-07T05:31:56Z",
"nextBeforeKey": "<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": "rate_limited",
"message": "<string>"
}
}{
"error": {
"code": "backend_resolution_failed",
"message": "<string>",
"retryable": true
}
}List your org's receipts
Every action your org has taken, newest first. This is the enumeration counterpart to the get_receipt tool: use that one to recover a lost response, and this one to answer what has happened.
TWO DIFFERENCES FROM get_receipt, both worth knowing before you reach for it. It answers about ONE key rather than a page, and it requires the deviceId as well as the key. This route and GET /v1/receipts/{idempotencyKey} do not: an idempotency key is unique PER DEVICE, so one organisation can legitimately hold the same key on two devices, and these two resolve that by answering 400 and naming deviceId only when it actually happens. So a recovery path that does not know which device it sent to has to come here, not to the tool. Narrowing the tool to match is filed as D170 and is not in this release.
Paging is keyset based, not offset based, so rows cannot be skipped or repeated while new receipts arrive. When a page is not the last, the response carries nextBefore and nextBeforeKey; send them back as before and beforeKey for the next page, and stop when they are absent. Send BOTH, and send them unchanged: the ordering is by timestamp and key together, and receipts written concurrently routinely share a timestamp.
A key narrowed to a subset of devices sees only that subset. Asking about a device outside it returns an empty page rather than a refusal, which is the same shape a narrowed key already sees in device listings: out of subset reads as nothing here, never as exists but denied.
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{
"receipts": [
{
"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>"
}
],
"nextBefore": "2023-11-07T05:31:56Z",
"nextBeforeKey": "<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": "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.
Query Parameters
Only receipts for this device. Omit for every device the credential can see.
Only receipts produced by this agent run, which is how you rebuild one run's action sequence without pulling every receipt for the device and filtering client side. Matching is on the run's own receipts, not on a name prefix, so a run id that begins with another run's id does not collect its receipts. An empty value is refused rather than answered with everything.
1Only receipts in this state. failed is the usual one: it is how you list what went wrong without reading everything that went right.
A receipt state.
pending, committed, failed Only actions taken by this person, by the subject id you read off actor.userId. Mutually exclusive with actorApiKeyId: an actor is a person or a key and never both, so asking for both is refused rather than answered with an empty page. An empty value is refused too.
1Only actions taken by this key, by the id you read off actor.apiKeyId or from GET /v1/api-keys. This is the answer to "a key was public for eleven hours, what did it do". Mutually exclusive with actorUserId.
1How many receipts to return. Defaults to 50; larger values are clamped to 200 rather than refused.
x >= 1Keyset cursor, first half: the nextBefore of the previous page, passed back unchanged. On its own it also works as a plain time bound, returning receipts recorded strictly before this timestamp.
Keyset cursor, second half: the nextBeforeKey of the previous page. Send it whenever you send before from a previous page. Paging with before alone cannot separate receipts that share a timestamp, and under concurrent dispatch many do.
Response
A page of receipts.
A page of receipts, newest first.
Show child attributes
Show child attributes
Send back as before for the next page, TOGETHER with nextBeforeKey. ABSENT on the last page, which is how paging ends. It carries microsecond precision; pass it back unchanged rather than reformatting it, because a value rounded to milliseconds skips rows.
The other half of the cursor. Send back as beforeKey. Receipts are ordered by timestamp AND key, so a cursor without this half cannot resume correctly when several receipts share a timestamp, which is the normal case under concurrent dispatch.