Skip to main content
A receipt is the gateway’s signed record of one request. It is an ordered event log that captures what the gateway received, which upstream it selected and verified, what it forwarded, and what it returned, with a hash at each step. The gateway signs the receipt with a key published in its attestation report, so a verified receipt proves the response came from the attested workload and was not altered. Every inference response includes the receipt id in the x-receipt-id header. Fetch the receipt:
{id} accepts the receipt id (rcpt-…) or the response id (chat id). See GET /v1/aci/receipts/{id} for the response shape.

What a receipt commits to

GET /v1/aci/receipts/{id} returns the receipt directly, signed by a key from the attested keyset: The event_log carries the two hashes that matter most: request.received.body_hash (the request the gateway observed) and response.returned.body_hash (the response it returned). Comparing these to the bytes you sent and received proves the receipt covers your exact exchange.
The legacy alias GET /v1/signature/{id} returns the same receipt wrapped in a compatibility envelope that adds a text field ("<request body hash>:<response hash>"), a top-level signature, and signing_address, for earlier API clients. New integrations should use the canonical /v1/aci/receipts/{id} response above.

The transparency event log

The event_log records the request’s path through the gateway. Each event carries a hash or a fact, never your prompt text. The signed receipt includes request.received.body_hash and response.returned.body_hash, which lets a verifier bind the receipt to the exact bytes you sent and received.

The upstream.verified event

This event tells you whether the model that ran your prompt was itself attested:
The session id is a snapshot from the public sessions list; use the id in your own receipt.
  • For a confidential model, result is verified, required is true, and session_id references the attested session the channel was bound to.
  • For a routed model, result is failed, required is false, and there is no session_id. The gateway still served the request, but the upstream provider was not attested.
Signed refusal receipts for 412 session_not_accepted and 503 upstream_verification_failed also arrive via x-receipt-id: they record result: "failed", required: true, a reason, and no session_id or request.forwarded event; response.returned hashes the error body.

Why hashes, not bodies

The gateway does not store your request or response. Receipts hold hashes, so they prove integrity without warehousing your data. A request rewrite appears as a difference between request.received.body_hash and request.forwarded.body_hash; a response rewrite appears as a difference between response.received.body_hash and response.returned.body_hash.

Streaming

For streaming responses the gateway can return x-receipt-id early, but the signed receipt is complete only after the stream finishes, because response.returned.body_hash covers the full streamed body. Fetch the receipt after the stream ends. Hash the raw SSE bytes, including every data: line and blank line, rather than the reassembled text.

Attested sessions

Follow session_id to the verified security context behind a confidential response.

Verify a response

Check a receipt signature and hashes yourself.