Provenance API

Self-serve cryptographic timestamp receipts.

The TTTPS Provenance API seals any content hash (an AI agent output, a document, an arbitrary payload) into a tamper-evident receipt with an operator-independent timestamp. A receipt attests to WHEN a digest was seen, its ORDER, and TAMPER-EVIDENCE: it does not assert that the underlying content is correct. The raw payload is never sent or stored, only its sha256 digest.

1,000 free seals per key · no card, no approval gate · POST /v1/keys
Live status
n/a receipts sealed to date, across every key
Source: the public aggregate counter on this API.
Time source checking

Aggregate seal volume. Provenance attests when/order/tamper-evidence, not correctness.

Try it

Open-source compute, sealed in time.

The kernel is open and the contracts are public, so anyone can recompute what you got. Sealing takes that reproducible result and fixes it to a moment, tamper-evident afterwards. One establishes what is true; the other establishes when it existed. Everything below also works as plain HTTP in the reference.

1
Choose what to seal
2
Enter a value

Checked against the bound proved in Lean 4 for that metric. No key needed, nothing recorded.

Supply your own digest to bind the receipt to a full run record (cohort, model version, fold) without transmitting any of it.

3
Seal it with TTTPS

Creates a timestamped, tamper-evident receipt. This is the only step that writes a permanent record and spends one seal from your quota.

No key yet? with a thousand free seals, no approval, no card.
4
Verify the receipt

Runs with no key at all, which is the point: whoever you hand a receipt to can re-check it without an account here.

Values you enter are used to answer the request and discarded. Only a SHA-256 digest is stored, and a receipt attests when a result existed and that it has not changed since, not that it is scientifically correct.

Quickstart

Three requests, no SDK.

Everything below is plain HTTP against the production API. No install, no account approval, no card. Paste the three commands in order and the last one prints a receipt anyone can re-check.

1 · Mint a key
curl -X POST https://kpp.kenosian.com/v1/keys \
  -H 'Content-Type: application/json' \
  -d '{"email":"you@example.com","use_case":"trying tttps"}'

The response carries api_key. It is shown once and never stored on our side, only its digest, so keep it. It comes with a thousand free seals.

2 · Hash your content, then seal the hash
sha256sum myfile.txt          # or: shasum -a 256 myfile.txt

curl -X POST https://kpp.kenosian.com/v1/anchor \
  -H 'Content-Type: application/json' \
  -H 'X-API-Key: <your api_key>' \
  -d '{"content_hash":"<the 64-hex digest>"}'

You compute the digest yourself on purpose. The file never leaves your machine: this API receives the hash and nothing else, so there is no copy of your content here to leak, subpoena or lose. That is also why we cannot hash it for you. The response carries receipt_id and an absolute verify_url you can paste straight into a browser. If you would rather send the key in the body than as a header, {"content_hash":"...","key":"..."} works identically.

3 · Verify, from anywhere, with no key
curl 'https://kpp.kenosian.com/v1/verify?receipt_id=<your receipt_id>'

Verification is open, so whoever you hand a receipt to can check it without credentials and without asking you for anything. A tampered or backdated receipt comes back as verified: false with the reason, rather than as an error. For an artifact that has to survive offline review, exchange the receipt for a signed certificate at POST /v1/export/certificate, which a third party checks against the public key published in the issuer DID document.

Full request and response schemas for every endpoint: API reference below
Framework Integrations

Eight frameworks, one receipt.

Every integration seals its framework's output digest through the same endpoints documented below. This table is the only place integration status is published, so it cannot fall out of step with another page. Three packages are built and verified with their upload to PyPI still pending.

Framework Status Install What it does
smolagents Native ttt-mcp
pip install smolagents-openttt
Connects over MCP with no adapter package at all. A published step callback is the MCP-free alternative.
LangChain Published pip install langchain-openttt Callback handler. Seals each LLM call's output hash.
LiteLLM Published pip install litellm-openttt CustomLogger with sync, async and fail-open paths.
LlamaIndex Published pip install llamaindex-openttt BaseCallbackHandler covering chat and completion.
vLLM Published pip install vllm-openttt ASGI middleware. Carries W3C traceparent into the receipt.
Ollama Upload pending ollama-openttt Reverse proxy. Seals the final NDJSON line of a stream.
DeepEval Upload pending deepeval-openttt BaseMetric. Cross-checks the receipt against the backend.
Ragas Upload pending ragas-openttt SingleTurnMetric. Carries receipt id through the sample.
API Reference

One provenance model. Every endpoint that serves it.

Interactive reference generated from this API's OpenAPI spec, so the list below is the live surface rather than a hand-kept copy of it: key issuance, anchoring, verification, the per-key receipt dashboard, the public counter and its badge, and offline certificate export with the issuer DID document that certificates are checked against. Verification is reachable two ways, as a POST with a JSON body or as a GET with a receipt_id query parameter, which is the clickable form returned in verify_url.

Two field-naming details worth stating plainly, since integration code has gotten this wrong before: POST /v1/anchor returns the digest under a field literally called receipt (alongside receipt_id, content_hash, time, time_source, and verify_url), not chain_digest, that name doesn't exist in this API. There is also no fail_open field anywhere in a server response: fail-open is client-side behavior, a caller that catches a PoT-backend error and falls back locally rather than blocking, not something the server reports about itself. The full request/response schemas below are generated directly from this API's OpenAPI spec, so they reflect the real field names, not a paraphrase. The aggregate counter shown at the top of this page is a read-only public endpoint, and it is documented below alongside the rest, together with the Shields endpoint that renders it as a badge. On keys: anchoring accepts yours either as an X-API-Key header or as a key field in the JSON body, whichever your client makes easier. The receipt dashboard takes the header only, and it is the one endpoint that refuses to answer without a key at all, because what it returns is the receipt history belonging to that single key and there is no anonymous version of that. Verification is open to everyone and needs no key, which is the point: a receipt is worth something precisely because the person you hand it to can check it without your permission.