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:
| Field | Meaning |
|---|---|
receipt_id, chat_id | The receipt id and the response/chat id. |
workload_id, workload_keyset_digest | Must match the attestation report you verified. |
endpoint, method, served_at | The route, HTTP method, and time served. |
event_log | The ordered transparency events below. |
signature | Signature over the receipt, by a receipt_signing_keys entry in the attested keyset. |
event_log carries the two hashes that matter most: request.received.body_hash (the request
the gateway observed) and response.returned.wire_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
Theevent_log records the request’s path through the gateway. Each event carries a hash or a fact,
never your prompt text.
| Event | Author | What it records |
|---|---|---|
request.received | Frontend | Hash of the request body the gateway observed. |
middleware.forwarded | Frontend | Effective body hash after any middleware rewrite. |
route.selected | Backend | The target route id the backend accepted. |
request.forwarded | Backend | Hash of the provider-facing request body. |
transparency.request_modified | Backend | Present when the forwarded body differs from the received body. |
upstream.verified | Backend | The upstream verification result and binding (see below). |
response.received | Backend | The provider response before any post-processing. |
transparency.response_modified | Backend | Present when the returned response differs from the received response. |
response.returned | Frontend | cleartext_hash and wire_hash of the final response. |
request.received.body_hash and response.returned.wire_hash are the two values combined into
the signed text. That is what lets you prove the signature covers 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:
- For a confidential model,
resultisverified,requiredistrue, andsession_idreferences the attested session the channel was bound to. - For a routed model,
resultisfailed,requiredisfalse, and there is nosession_id. The gateway still served the request, but the upstream provider was not attested.
Why hashes, not bodies
The gateway does not store your request or response. Receipts hold hashes, so they prove integrity without warehousing your data. If the response was modified in transit, atransparency.*_modified event records that the forwarded bytes differed,
again by hash.
Streaming
For streaming responses the gateway can returnx-receipt-id early, but the signed receipt is
complete only after the stream finishes, because response.returned.wire_hash covers the full
streamed body. Fetch the receipt after the stream ends.
Next
Attested sessions
Follow
session_id to the verified security context behind a confidential response.Verify a response
Check a receipt signature and hashes yourself.