Developer API · sign your own LLM

Prove your AI said exactly that.

Send any AI output to Attevia and get back a tamper-proof receipt. If anyone changes even one character later, the receipt stops matching — and anyone can check it, with no account and no call to us. One request in, one receipt out.

What it is

A one-call HTTPS endpoint that turns any JSON into a tamper-evident, publicly verifiable receipt.

You POST a document (any JSON: an AI output, a model decision, a transcript). We canonicalise it, SHA-256 it, sign the hash with the server's ed25519 private key, store the receipt in Vercel Blob, and return the receipt to you. Anyone — your compliance officer, your auditor, a regulator — can later re-hash the same document and check it against the receipt using our public key. They never need to call Attevia at all.

ed25519 provenance

Every document gets a 64-byte signature over a canonical SHA-256 hash. Forgery-resistant under any compute budget.

Independent review

Optional review: true runs a second model before sign. The verdict lives under document.attevia.independentReview — inside the hash.

Immutable archive

Receipts mirror to Vercel Blob with a SHA-256-derived path. Write-once, region-isolated, audit-readable.

Who uses it

Wherever an LLM's output has consequences.

Wealth & broking
Sign every model-driven output

Problem. Regulated firms need a reproducible trail for AI-generated research and decisions.

Solution. Wrap the LLM call in /v1/audit/sign and store the receiptId next to the output in your CRM.

LLM-as-a-service
Prove your model said what your customer thinks it said

Problem. A customer disputes a chatbot's reply weeks later. Without a signed log it's their word against yours.

Solution. Sign every completion. Hand them the receipt. Verification is public — even your lawyer can re-run it.

Healthcare AI
HIPAA / EU AI Act 'high-risk system' logs

Problem. High-risk AI systems must keep an immutable log of inputs, model version, and output for years.

Solution. Sign the input + output JSON. The receipt + Blob URL are the log. Verification is offline.

Internal compliance
Prevent prompt-injection denial later

Problem. Inputs and outputs drift; without proof, 'the model never said that' becomes plausible.

Solution. Sign at the boundary. Tampered documents fail verification with a hash-mismatch reason.

Try it now

Sign a real document, then break it on purpose.

One click signs the sample below and shows you a real receipt — the same one your code would get in production. Then hit Tamper to change one character and watch verification fail in red. That contrast is the whole idea.

Live audit playground
This really runs against /api/v1/audit/sign. No signup, no card.

We'll sign the sample document below and show you a real, verifiable receipt.

Your receipt will appear here
Press the button above. You'll get a tamper-evident receipt you can verify forever — then break it on purpose to see verification fail.
What just happened?
1
You sent some JSON

Any AI output, decision, or transcript — whatever you want to be able to prove later.

2
We hashed & signed it

We turned it into a unique fingerprint and signed that fingerprint with our private key. The result is the receipt.

3
Anyone can verify it

With the public key, anyone can re-check the document against the receipt. No account, no call to Attevia. Change one byte and it fails.

How it works

Four steps, zero magic.

  1. 1
    Canonicalise the document

    JSON keys are sorted lexically so {a:1,b:2} and {b:2,a:1} produce the same canonical bytes. No surprises across language runtimes.

  2. 2
    SHA-256 the canonical bytes

    A 32-byte hash that uniquely identifies the document and its position in the message stream. Recomputed on verification.

  3. 3
    ed25519-sign the hash

    64-byte detached signature using the server's private key (held in ATTEVIA_SIGNING_SEED, never logged). Public key at /api/pubkey.

  4. 4
    Store + return the receipt

    Receipt persisted to Vercel Blob at audit/receipts/<id>.json, indexed for tenant streams, returned to caller, also mirrored to your console at /app/receipts.

The contract

POST. Get receipt. Verify forever.

One endpoint to sign, one endpoint to verify. The verify endpoint requires no API key — your customers, auditors, and regulators can verify without an account.

POST /api/v1/audit/sign (Bearer auth)
curl -X POST $ATTEVIA_URL/api/v1/audit/sign \
  -H "Authorization: Bearer $ATTEVIA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "document": {
      "model": "claude-opus-4-8",
      "output": "Thesis stance: supported for NIFTYBEES over 12m based on backtest alpha +0.8%.",
      "inputs": { "thesis": "rural wages + monsoon" }
    },
    "actor": "claude-opus-4-8@anthropic",
    "externalId": "memo_2026_04_20_NFTY50_001",
    "review": true
  }'
Response
{
  "ok": true,
  "receipt": {
    "receiptId": "r8fzaQp2",
    "documentSha256": "a42f…",
    "signature": {
      "algo": "ed25519",
      "fingerprint": "bks8zvfobs-nOEJo",
      "signature": "cR9f…",
      "signedAt": 1745089234012
    },
    "publicKeyFingerprint": "bks8zvfobs-nOEJo"
  },
  "verifyUrl": "/api/v1/audit/verify/r8fzaQp2",
  "publicKeyUrl": "/api/pubkey"
}
GET /api/v1/audit/export (Bearer auth)
curl "$ATTEVIA_URL/api/v1/audit/export?format=jsonl&limit=500" \
  -H "Authorization: Bearer $ATTEVIA_KEY" \
  -o audit-export.jsonl

// One JSON object per line — receipt envelope + tenant metadata for GRC tooling
POST /api/v1/audit/verify/:id (NO auth required)
curl -X POST $ATTEVIA_URL/api/v1/audit/verify/r8fzaQp2 \
  -H "Content-Type: application/json" \
  -d '{ "document": { /* exact JSON you signed */ } }'

// => { "valid": true, "publicKeyFingerprint": "bks8zvfobs-nOEJo" }
// (or { "valid": false, "reason": "document hash mismatch …" } if tampered)
GET /api/pubkey (NO auth)
{
  "algo": "ed25519",
  "fingerprint": "bks8zvfobs-nOEJo",
  "publicKeySpkiBase64Url": "MCowBQYDK2VwAyE…"
}
From your code

Three lines, idiomatic TypeScript.

lib/sign.ts
const res = await fetch(`${ATTEVIA_URL}/api/v1/audit/sign`, {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.ATTEVIA_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({ document: llmOutput, actor: `${model}@${provider}` }),
});
const { receipt, verifyUrl } = await res.json();
// store receipt.receiptId in your DB next to llmOutput
FAQ

The questions auditors actually ask.

What stops Attevia from re-signing a different document later?

The private key never leaves the server, and the audit-receipt Blob is write-once with a deterministic path derived from the receipt id. To rewrite history we'd have to break SHA-256 — which is the whole point of using it.

How do I verify a receipt without depending on Attevia being online?

Pull /api/pubkey once and pin the SPKI base64url string in your verifier. After that, verification is a local ed25519.verify(signature, sha256(canonical_json(doc)), pubkey). Code samples in /docs.

What's the latency?

50–120 ms end-to-end on a warm Lambda. The sign call is one Blob write + one signature; verify is one Blob read + one hash check.

What does the free tier cover?

The shared demo key is rate-limited; a personal Free account gets 5 signed memos/month or unlimited Audit-API ops on Pro+ ($30/mo). Per-tenant signing keys are available on the Fund tier — see /pricing.

Can I rotate the signing key?

Yes — rotate ATTEVIA_SIGNING_SEED in your deployment env. The current public key is always at /api/pubkey. Historical fingerprint archive is on the Enterprise roadmap.

Does Audit include a second-model review?

Yes — pass review: true on POST /api/v1/audit/sign. An independent model reads your document, embeds its verdict under document.attevia.independentReview, and signs the combined payload. Counts as 2 signed ops. Prime and Desk pipelines include finance-specific multi-model consensus automatically.

Is this the same as the OpenTimestamps / Bitcoin-anchor approach?

Different threat model. We give you fast, free, cryptographic provenance now. Bitcoin-anchor adds a public consensus layer at a per-receipt cost. We can layer both — talk to us on enterprise.

Ready to ship
Sign your first document in 60 seconds.