AgentOath Registry
中文
EVIDENCE FOR AI AGENTS

Your logs are your word.
A receipt is evidence.

Your agents approve things, judge things, and act for your customers. When someone later disputes what happened, all you have is your own database — and there is no reason for them to believe it was not edited. AgentOath turns an action into a signed, timestamped record that anyone can check without trusting you, and without trusting us.

registry.checking...·GET /api/v1/health

What that looks like in practice

A real receipt, stamped on 2026-08-20. Every line below was checked against a source that has nothing to do with this project.

# the receipt is signed — change one byte and the signature fails
sha256(receipt) = b0a80f750c7021d8e107fa5c5227…

# three unrelated timestamp authorities signed that hash with their own clocks
2026-08-20T19:48:15Z  DigiCert SHA256 RSA4096 Timestamp Responder 2025
2026-08-20T19:48:15Z  Certum Timestamp 2026, Asseco Data Systems S.A.
2026-08-20T19:48:16Z  Apple Inc., Timestamp Signer NWK1

# 16 minutes later it was committed into the Bitcoin blockchain
block 963342  mined 2026-08-20T20:04:12Z
block 963346  mined 2026-08-20T20:32:06Z
block 963374  mined 2026-08-21T02:10:47Z

That last part is the one that matters. Once a hash is in a Bitcoin block, proving it existed before that block needs no authority, no server, and no company that still has to be in business. It does not make our database tamper-proof. It makes our database irrelevant.

Why not just do this yourself

A fair question, and mostly the answer is that you can. Here is what you would end up building.

Signing is the easy part

Ed25519 is twenty lines. Then you discover Python prints 7.0 where JavaScript prints 7, your two services disagree on the canonical bytes, and every receipt one signs is rejected by the other — with no error, just "invalid". Three such rules, all of them silent.

The part that bites later

Receipts are public and permanent. The first time someone puts a customer email or an API key in one, you cannot take it back. A 28-key blocklist matched per underscore-segment stops it — and it has to catch prompt_hash and private_key_pem, which the obvious implementation does not.

The part you cannot do alone

A signature proves what. It cannot prove when — your own timestamp is worth exactly as much as your own log. That needs a party who is not you: a timestamp authority, or a blockchain. Both are wired in here.

None of it is novel. It is standard cryptography, RFC 3161, and OpenTimestamps — assembled, tested across two languages against byte-level fixtures, and honest about where the guarantees stop. That is the whole offer.

Three things, and only three

Identity, receipts, verification. Private task data never enters the Registry — a field whitelist and a key blocklist, on the client and again on the server.

Identity

A DID is derived from the public key: did:agentoath:sha256(pubkey). The same key is always the same identity, anyone can recompute it offline, and a new key is a new identity with no history.

Notarised receipts

Signed over canonical JSON that is byte-identical in Python and JavaScript. The Registry verifies the signature before storing anything and rejects what does not verify — including receipts we would rather keep.

Verification by anyone

The verify endpoint needs no key and stores nothing. Give it a receipt and a public key. It also checks that the DID really derives from that key, so a platform vouching for itself carries no weight here.

Sixty seconds

Disabled by default — nothing is sent until you turn it on.

# Python
pip install "agentoath[timestamps]"

from agentoath.hosted import Identity, build_signed_receipt
from agentoath.timestamps import stamp_receipt, verify

receipt = build_signed_receipt(identity, receipt_id="verdict-1234",
    action="compliance.verdict.red",
    metadata={"schema": "v1", "content_digest": sha256_json(text)})
proof = stamp_receipt(receipt)      # only the hash leaves your machine

// JavaScript
npm install agentoath
import { Identity, buildSignedReceipt } from 'agentoath/hosted';

Full integration guide — the three interop rules, the blocklist, and how to prove it worked →

Attesting documents

There is no document receipt type, which is the point: a document is an ordinary receipt plus one metadata convention, so signing, the cross-language canonical form, the blocklist and the Registry's validation all keep working unchanged.

The file stays with you

Only its sha256 goes into the receipt. A digest proves "this is the same file" to whoever already has it, and proves nothing to anyone who does not — which is what you want when the thing you are attesting is a scan you may not redistribute.

Idempotent by construction

The receipt id derives from the digest, so attesting the same bytes twice produces the same receipt rather than two unrelated records. Files are streamed — a multi-gigabyte scan does not have to fit in memory.

What it is for

Being able to answer "you had this on the date you claim" with something other than your own word. Provenance for training data, chain of custody for scanned material, evidence of what a compliance check actually said.

What this does not prove

🔴 Worth reading before you rely on it. The line between mathematics and trust is drawn in full on the integration guide; the short version:

Mathematics

A receipt's contents cannot be altered — not by anyone, including us. An identity cannot be impersonated. With a timestamp proof, the time cannot be backdated. All three are checkable by you, against us.

Still trust

That we do not delete a receipt from our database, and that a list you fetch is complete. There is no hash chain here and no append-only guarantee. Hold your own copy plus an OpenTimestamps proof and neither matters.

Why say so

Because the first person who checks will find out anyway, and an overclaim on this page would cost the parts that are true. If a claim here is not backed by something you can run, it should not be here.

API

Writes need X-API-Key; reads and verification are public, with rate limits. The machine-readable spec at GET /api/v1/registry is the authority for interop — this table is a summary.

EndpointWhat it does
GET/api/v1/healthService health
GET/api/v1/registryMachine-readable spec — DID derivation, canonical JSON, signing rules. The authority for interop.
POST/api/v1/agents/register🔑Register an Ed25519 public key, get a did:agentoath DID (idempotent)
GET/api/v1/agents/{did}Full agent record, including the public key
GET/api/v1/agents/{did}/cardAgent card: identity, capabilities, receipt totals
GET/api/v1/agents/{did}/statusStatus, receipt count, average rating
GET/api/v1/agents/{did}/receiptsThat agent's public receipts
POST/api/v1/receipts/publish🔑Publish a signed receipt — rejected outright if the signature does not verify
POST/api/v1/receipts/verifyVerify a receipt independently. No key, nothing stored, anyone can call it.
GET/api/v1/receipts/{receipt_id}Look up a published receipt