Documentation

Provenant API

One typed action in, one signed proof out. Base URL https://api.useprovenant.xyz in production, or http://127.0.0.1:8000 when you run the sandbox locally.

Quickstart (sandbox)

The sandbox runs the full API with no provider keys — identity and notarization are simulated so you can integrate offline, then flip to real fulfillment by setting one environment variable. Requires Python 3.10+.

# 1. install git clone <your-repo> provenant && cd provenant python -m venv .venv && . .venv/bin/activate # Windows: .venv\Scripts\activate pip install -r requirements.txt # 2. run the test suite (37 tests) python -m pytest -q # 3. start the API uvicorn tangible.api:app --reload

Start a verification (simulated — returns a signed proof immediately):

curl -X POST http://127.0.0.1:8000/v1/actions/verify-identity \ -H "Content-Type: application/json" \ -d '{"name":"Dana Lee","email":"dana@example.com"}'
Prefer the terminal-free path? Run python agent_demo.py to watch a mock agent hit the notarization wall, call the tool, and verify the returned proof end to end.

Going live (Stripe)

The verify_identity verb becomes real the moment a Stripe key is present — no code change. Stripe test mode is free.

  • Create a Stripe account and copy your test secret key (sk_test_…).
  • Enable Identity at dashboard.stripe.com/identity (test mode is free).
  • Set the key and restart:
export STRIPE_API_KEY=sk_test_xxx # Windows: $env:STRIPE_API_KEY="sk_test_xxx" uvicorn tangible.api:app --reload

Now verify-identity returns a real hosted url. Open it, complete Stripe's verification (test document images in test mode), then poll GET /v1/identity/{action_id} until status is verified and a signed proof appears. Full deploy steps (Render + custom domain + webhook) are in SETUP_LIVE.md.

Actions

An action is a typed request to perform one real-world verb. Every action resolves to one of: verified/completed (with a proof), pending (awaiting a human session), rejected (failed validation or compliance), or failed.

Proofs

A proof is a JSON object of substantive claims plus a key_id, content_hash, signature, and public_key. Verify it offline, or via POST /v1/verify. Verification recomputes the canonical hash and checks the signature against the trusted key for key_id — not the embedded key — so a re-signed forgery is rejected.

Authentication

The local sandbox is unauthenticated for development. Production uses a bearer API key on every request:

Authorization: Bearer pk_live_xxx
Request a key by emailing hello@useprovenant.xyz. Keys are scoped per environment (test / live).

Verify identity

POST/v1/actions/verify-identity

Starts an IAL2 identity-verification session. Returns immediately; with Stripe configured the response is pending with a hosted url.

FieldTypeNotes
namestringrequired
emailstringrequired
return_urlstringoptional redirect after the session
{ "action_id": "idv_8e7fdc36…", "status": "pending", "url": "https://verify.stripe.com/…", "provider": "stripe", "proof": null }

Get identity status

GET/v1/identity/{action_id} — polls the provider; once verified, the response includes a signed proof.

Notarize

POST/v1/actions/notarize Sandbox

Notarizes a document via remote online notarization. Sandbox fulfillment today; licensed RON network in private beta.

FieldTypeNotes
document_namestringrequired
document_sha256stringrequired, 64 hex chars
jurisdictionstring2-letter US state code
partiesarrayeach: name, email, role
idempotency_keystringoptional, retry-safe
curl -X POST http://127.0.0.1:8000/v1/actions/notarize \ -H "Content-Type: application/json" \ -d '{"document_name":"Promissory Note", "document_sha256":"7d784f…", "jurisdiction":"TX", "parties":[{"name":"Jordan","email":"jordan@acme.com"}]}'

GET/v1/actions/{action_id} returns a stored notarization result.

Verify a proof

POST/v1/verify — body { "proof": { … } }. Returns { "valid": true, "reason": "valid" }. Also runs offline: python -m tangible.verify proof.json.

Revoke

POST/v1/proofs/{proof_id}/revoke — marks a proof revoked. Subsequent verification returns valid: false, reason: "proof has been revoked".

Ledger

GET/v1/ledger/verify — recomputes the hash chain and returns { valid, reason, entries }. Any tampering, insertion, or reordering breaks the chain.

Webhooks

POST/v1/webhooks/stripe — receives Stripe Identity events. Subscribe to identity.verification_session.verified; set STRIPE_WEBHOOK_SECRET to enforce signature verification. On a verified event, Provenant finalizes the session and issues the proof — no polling needed.

Errors

StatusMeaning
200OK — check the body's status for rejected actions
400Bad request or webhook signature failure
404Unknown action or session id
422Validation error (bad email, malformed sha256, duplicate parties)

Questions? hello@useprovenant.xyz →