This guide adds a tamper-evident receipt to an AI agent’s important decisions, in any Python stack — LangChain, LlamaIndex, a raw OpenAI loop, or your own framework. The receipt is signed, hash-chained, and verifiable by anyone with no Marturia account. Budget about fifteen minutes.

If you only want the verify side (you’ve been handed a receipt to check), skip to Verify a receipt.

1. Get a project and an API key

In the dashboard at marturia.dev/app:

  1. Create a project (Projects → + New project). The slug shows up in the public verifier URL.
  2. Mint an API key (open the project → API KeysMint key). You’ll see the key once — it starts with mtu_live_. Copy it; only its hash is stored.

Keep the key in your environment, not in code:

export MARTURIA_API_KEY=mtu_live_xxxxxxxxxxxx

2. Install

The SDK and the offline verifier ship in one package:

pip install marturia-verify

That gives you marturia_sdk (to record receipts) and the marturia-verify CLI (to check them).

3. Record a receipt at a decision point

Pick the moments that would matter in a dispute — money moving, an approval, an irreversible action — not every token. At that point, call record_receipt with a short agent_name and a JSON-serializable payload:

import os
from marturia_sdk import SyncClient

client = SyncClient(api_key=os.environ["MARTURIA_API_KEY"])

# ... your agent decides something consequential ...
receipt = client.record_receipt(
    agent_name="refund_approver",
    payload={
        "decision": "approve_refund",
        "order_id": "A-10293",
        "amount_usd": 1200,
        "model": "your-model-id",
        "reason": "within policy window",
    },
)

# Store the receipt reference next to your normal logs.
log.info("marturia receipt recorded", verify_url=receipt.verify_url)

A few rules that keep receipts honest:

try:
    receipt = client.record_receipt(agent_name="refund_approver", payload=payload)
except Exception:
    log.warning("marturia receipt failed; continuing")  # never block the agent

Optionally pass agent_run_id="..." to group every receipt from one agent run.

4. Store the reference

You don’t need to store the whole receipt — just enough to find it later. Keep the verify URL (or the tenant id + sequence it encodes) in your existing logs or database, alongside the decision it covers. The receipt chain itself lives in Marturia; the verifier pulls what it needs.

Verify a receipt

Anyone — an auditor, a customer, opposing counsel — can verify without an account. Download the receipt JSON from its public verify URL, then check it against your tenant’s public key (available in the project’s settings):

curl -s https://marturia.dev/v1/verify/<tenant>/<seq> > receipt.json

pip install marturia-verify
marturia-verify --receipt receipt.json --pubkey-hex <tenant-public-key>

A clean receipt reports VALID (signature good, hash chain intact, sequence confirmed). If anyone altered the payload or signature, it reports INVALID and which check failed. To verify a whole run at once, use --chain receipts.jsonl instead of --receipt.

That’s the entire loop: one record_receipt call at the decisions that matter, and a one-line verify that needs nothing but the public key.

What this is (and isn’t)

It’s an integrity layer, not a tracing tool. Keep your observability stack for debugging; add a receipt only where you’d need to prove to someone else that a decision happened and hasn’t changed. Most of your agent’s activity will never touch it.

Closed beta is open:

Related Marturia resources - /guides/integrating-marturia-with-langchain.html - /guides/bulk-receipt-verification.html - /blog/logs-arent-evidence.html