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

# PrysmProof

> A tamper-evident SHA-256 receipt on every response — proving which model ran, in which mode, on which input and output.

Every PRYSM completion ships with a **PrysmProof**: a cryptographic receipt that records
exactly what happened — which model and provider ran, in which mode, over which input and
output — as a SHA-256 hash you can store and later verify.

When routing is automatic, "which model actually answered this?" stops being a matter of
trust. PrysmProof makes each decision **auditable**: an immutable record for compliance,
debugging, billing disputes, and reproducibility.

## What's in a proof

Each response's `prysm.proof` block looks like this:

```json theme={null}
{
  "request_id": "b1e7c0d2-3f4a-5b6c-7d8e-9f0a1b2c3d4e",
  "timestamp": "2026-06-02T18:24:01.123456+00:00",
  "proof_hash": "sha256:a1b2c3d4e5f6a7b8",
  "model": "DeepSeek V4 Flash",
  "provider": "deepseek",
  "mode": "balanced",
  "reason": "Code: 95% cheaper than GPT-5.2",
  "verifiable": true
}
```

| Field        | Description                                                               |
| ------------ | ------------------------------------------------------------------------- |
| `request_id` | Unique ID for the request — use it to [verify](#verifying-a-proof) later. |
| `timestamp`  | UTC ISO-8601 time the proof was generated.                                |
| `proof_hash` | The receipt: `sha256:` followed by the hash digest.                       |
| `model`      | Human-readable model that produced the response.                          |
| `provider`   | Upstream provider that served the call.                                   |
| `mode`       | Routing mode used (`quality`, `balanced`, `agility`, or `direct`).        |
| `reason`     | Why this model was chosen.                                                |
| `verifiable` | Whether the proof can be checked against PRYSM's records.                 |

## How the hash is computed

### Single-request proof (v1 — all non-agentic calls)

The `proof_hash` is a SHA-256 digest over a canonical, sorted JSON payload binding the
request together:

```text theme={null}
proof_hash = SHA-256(
  request_id +
  timestamp +
  model + provider + mode +
  SHA-256(messages)[:16] +      # prompt fingerprint
  SHA-256(response_text)[:16] + # response fingerprint
  input_tokens + output_tokens
)
```

Because the prompt and response are folded in as fingerprints, **any change** to the
input or output produces a different hash. The receipt is bound to the exact exchange,
not just to "a call happened."

<Note>
  The proof commits to *fingerprints* of your prompt and response, not the raw text — so
  the receipt is verifiable without PRYSM having to expose your content in the proof
  itself.
</Note>

### Trajectory proof (v2 — agentic multi-step runs)

For **agentic runs** (`POST /v1/agent/run`), PrysmProof v2 produces a Merkle-rooted
trajectory proof that binds every step of the run into a single, tamper-evident receipt.

Each **step proof** chains the previous step's hash to the current:

```text theme={null}
step_proof[i] = SHA-256(
  "prysm-agent-step-v2" \x00
  step_proof[i-1] \x00          # previous step (genesis = "")
  step_index \x00
  model_id \x00
  SHA-256(input)[:32] \x00      # input fingerprint
  SHA-256(output)[:32] \x00     # output fingerprint
  cost_usd \x00
  confidence \x00
  timestamp
)
```

The **trajectory root** binds all step proofs into a Bitcoin-style SHA-256 Merkle tree
(odd nodes are duplicated to make pairs), then folds in the run metadata:

```text theme={null}
merkle_root = MerkleRoot([step_proof[0], step_proof[1], ...])

trajectory_root = SHA-256(
  "prysm-agent-v2" \x00
  run_id \x00
  policy \x00
  strategy \x00
  merkle_root \x00
  SHA-256(final_output)[:32]
)
```

The `trajectory_root` field in the agent response is the canonical receipt for the entire
run. **Any step modification** (changed model, altered output, inserted step) produces a
different root — the tree makes tampering both detectable and localizable.

<Tip>
  Use `Agents.verify(trajectory)` in the Node or Python SDK to verify a trajectory proof
  locally, with no network round-trip. The SDK recomputes the full Merkle chain and
  compares the root.
</Tip>

```typescript Verify a trajectory locally (Node SDK) theme={null}
import { Agents } from "@prysmai/sdk";

const run = await client.agents.run({ goal: "...", max_cost_usd: 0.5 });

// Locally verify the chain — no network call, no trust required
const isValid = Agents.verify(run.trajectory);
console.log(isValid);  // true | false
```

```python Verify a trajectory locally (Python SDK) theme={null}
from prysm import Agents

run = client.agents.run(goal="...", max_cost_usd=0.5)
is_valid = Agents.verify(run.trajectory)
print(is_valid)  # True | False
```

## Verifying a proof

Look up any proof by its `request_id`. This endpoint is public (no auth) so a third
party — an auditor, a customer, a teammate — can independently confirm the record:

<CodeGroup>
  ```python Python theme={null}
  from prysm import Prysm

  client = Prysm()
  print(client.verify_proof("b1e7c0d2-3f4a-5b6c-7d8e-9f0a1b2c3d4e"))
  ```

  ```typescript Node theme={null}
  import { Prysm } from "@prysmai/sdk";

  const client = new Prysm();
  console.log(await client.verifyProof("b1e7c0d2-3f4a-5b6c-7d8e-9f0a1b2c3d4e"));
  ```

  ```bash cURL theme={null}
  curl https://api.prysm1.com/v1/proof/b1e7c0d2-3f4a-5b6c-7d8e-9f0a1b2c3d4e
  ```
</CodeGroup>

```json Response theme={null}
{
  "verified": true,
  "request_id": "b1e7c0d2-3f4a-5b6c-7d8e-9f0a1b2c3d4e",
  "entry": {
    "model": "deepseek-v4-flash",
    "provider": "deepseek",
    "mode": "balanced",
    "input_tokens": 18,
    "output_tokens": 240,
    "cost_usd": 0.000106,
    "timestamp": "2026-06-02T18:24:01.123456+00:00"
  }
}
```

If no record matches the ID, the endpoint returns `404 proof_not_found`.

## Reading the proof from an SDK

Use [`extension()`](/sdks/python#access-the-prysm-extensions) to pull the proof off a
response:

<CodeGroup>
  ```python Python theme={null}
  from prysm import extension

  ext = extension(resp)
  print(ext.proof.proof_hash)   # "sha256:a1b2c3d4e5f6a7b8"
  print(ext.proof.request_id)   # store this to verify later
  ```

  ```typescript Node theme={null}
  import { extension } from "@prysmai/sdk";

  const ext = extension(resp);
  console.log(ext?.proof?.proof_hash);  // "sha256:a1b2c3d4e5f6a7b8"
  console.log(ext?.proof?.request_id);  // store this to verify later
  ```
</CodeGroup>

## Use cases

<CardGroup cols={2}>
  <Card title="Compliance & audit" icon="scale-balanced">
    Keep an immutable record of which model handled regulated or sensitive work.
  </Card>

  <Card title="Billing disputes" icon="receipt">
    Reconcile usage and cost against verifiable per-request receipts.
  </Card>

  <Card title="Debugging" icon="bug">
    Reproduce a routing decision exactly — model, mode, and reason are all recorded.
  </Card>

  <Card title="Trust for agents" icon="robot">
    Prove to downstream consumers what an autonomous agent actually ran.
  </Card>
</CardGroup>

<Tip>
  Set `log_proofs: true` in your [BRAIN.md](/concepts/brain-md) to emit a PrysmProof for
  every request by default.
</Tip>
