> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trynito.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Response Evidence

> Get original encrypted request and response bytes with signature evidence for verification in your client.

Encrypted Chat Completions can return the original request and response bytes alongside the backend's signature proof. Your client uses these bytes to verify the signed exchange against a signing identity established by fresh attestation.

## Request Evidence

On a backend that supports response evidence, add this header to your existing Encrypted request to `POST /v1/chat/completions`:

```http theme={"theme":{"light":"github-light","dark":"github-dark"}}
nito-encrypted-response-evidence: 1
```

Keep the other [Encrypted headers](/api/api-reference/chat-and-text/encrypted#headers) and set `stream` to `false` in the JSON body. The native `/api/v1/chat/completions` route accepts the same option. Evidence requests require Encrypted transport and nonstreaming Chat Completions. Sending another nonempty header value, or requesting evidence with `stream: true`, returns `400 invalid_request`.

Omitting the header keeps the existing completion response and skips signature lookup. In an encrypted tool loop, keep the option consistent across requests and verify each exchange separately.

## Response Fields

The normal completion adds a `response_evidence` object:

| Field | Meaning |
| :- | :- |
| `version` | Envelope version, currently `"1"`. |
| `provider` | Opaque backend identifier. This is an open string. |
| `model` | Model identifier in the original upstream request. It may differ from the public model ID. |
| `response_id` | Original completion body ID, separate from billing correlation IDs. |
| `body_status` | `available` or `too_large`. |
| `request_body_base64` | Exact upstream request body, including its original whitespace. Present when bodies are available. |
| `response_body_base64` | Exact uncompressed upstream response body before Nito normalizes its JSON. Present when bodies are available. |
| `proof_format` | Opaque, versioned proof-format identifier. This is an open string. |
| `proof_status` | `returned` or `unavailable`. |
| `proof_base64` | Original backend proof JSON bytes. Present when proof is returned. |
| `verified` | Always `false`. Verification runs in your client. |

`proof_status: returned` records that the backend supplied a proof envelope. Your client still checks its signature, hashes, signer, and attestation binding. Raw response bodies may contain additional backend fields; treat those fields as untrusted until checked.

## Verify the Exchange

1. **Verify fresh attestation before the completion.** Use your own challenge and retain the verified signing identity, algorithm, measurements, and model binding. Follow [Verify It Yourself](/privacy/tee-attestation/verify-yourself-recipe). Top-level key fields alone are insufficient to establish trust.
2. **Require available evidence.** Check `body_status: available` and `proof_status: returned`. Select a verifier that explicitly supports the returned `proof_format` and version. Reject unknown formats or unsupported algorithms when your policy requires verification.
3. **Decode the original bytes.** Base64-decode the body and proof fields. Keep the original body bytes intact for hashing; parsing and reserializing JSON can change signed bytes.
4. **Check your request.** Compare its ciphertext, model, and generation parameters with what you intended to send, accounting for Nito's request mapping. A signed exchange must also match your request.
5. **Verify hashes and signature.** Calculate SHA-256 hashes of the original body bytes. Follow the proof format's rules for the exact signed text, signer scope, model binding, and signature verification against your verified attestation. An upstream gateway signature alone does not establish that a model-serving enclave signed the response.
6. **Consume the verified reply.** Decrypt the ciphertext in the verified original response. When using normalized completion fields, first confirm they match the signed original fields you intend to use.

For example, these steps decode the evidence and calculate its body hashes:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import base64
import hashlib
import json

with open("completion.json", "rb") as file:
    evidence = json.load(file)["response_evidence"]

if evidence["body_status"] != "available" or evidence["proof_status"] != "returned":
    raise ValueError("Response evidence is unavailable")

request_bytes = base64.b64decode(evidence["request_body_base64"], validate=True)
response_bytes = base64.b64decode(evidence["response_body_base64"], validate=True)
proof_bytes = base64.b64decode(evidence["proof_base64"], validate=True)
request_hash = hashlib.sha256(request_bytes).hexdigest()
response_hash = hashlib.sha256(response_bytes).hexdigest()
proof = json.loads(proof_bytes)
```

This snippet prepares verification inputs. Complete the signature and attestation checks above before treating the response as verified. Hash the decoded original body rather than Nito's normalized Chat Completions response.

## Limits and Unavailable Evidence

Each original body has a 1 MiB evidence limit. If either exceeds it, `body_status` is `too_large` and both body fields are omitted. Evidence is never silently truncated.

Proof lookup makes at most three attempts within a three-second timeout and accepts up to 256 KiB of proof JSON. Pending, missing, malformed, oversized, or failed proof responses produce `proof_status: unavailable` and omit `proof_base64`.

An unavailable proof preserves the successful completion and normal usage accounting. Apply your verification policy before consuming it. Repeating inference makes a new billable request; it does not retry proof retrieval for the original response. A separate evidence-retrieval endpoint is not available.

## Handling Evidence

Evidence stays within the request and is returned with `Cache-Control: no-store`. Nito does not log or persist these bodies or proofs. Keep evidence out of later model prompts and public conversation shares. The Browser App does not automatically verify response signatures or save this API evidence in chat history.

## Related

* [Encrypted API requests](/api/api-reference/chat-and-text/encrypted)
* [Encrypted protocol](/privacy/encrypted/protocol)
* [Verify attestation yourself](/api/api-reference/attestation/verify-yourself)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.