SDKs & verifiers
Provenance ships a full SDK for TypeScript and Python, plus tiny verifier-only
libraries for relying parties who just need to check a token. Every library speaks
the same wire contract, and the SDKs and verifiers are all proven
against the same committed cross-language vectors (packages/core/test-vectors/),
so the token format and action_payload canonicalization can never drift between
languages.
The matrix
| Library | Language | Install | Use it for |
| --- | --- | --- | --- |
| @provenance/sdk | TypeScript | pnpm add @provenance/sdk | Full client — every endpoint, typed. |
| provenance-sdk | Python ≥3.10 | pip install provenance-sdk | Full client — parity with the TS SDK. |
| provenance-verify | Python ≥3.10 | pip install provenance-verify | Offline token verify only (cryptography + stdlib). |
| provenance-verify (Go) | Go ≥1.21 | Not yet published — see below | Offline token verify only (stdlib crypto). |
| @provenance/mcp-server | — | npx @provenance/mcp-server | Use the API as MCP tools. |
Publishing to PyPI / the Go proxy is a launch step; until then, install from the monorepo (
pip install -e python/sdk).
Python SDK
from provenance import Provenance
prov = Provenance(api_key="prv_test_...", base_url="http://localhost:8080")
auth = prov.intent.authorize(
action_description="Wire $1,850 to acct_123",
agent_session_id="sess-1",
device_id=device_id,
action_payload={"to": "acct_123", "amount": 1850},
)
result = prov.intent.verify(
intent_token=auth["intent_token"],
action_description="Wire $1,850 to acct_123",
action_payload={"to": "acct_123", "amount": 1850},
)
print(result["valid"], result.get("reason"))
The Python SDK mirrors the TS resource groups (intent, approvals, claims,
policy, mandates, account, devices, decisions, webhooks, media), uses
httpx, and applies the same retry policy as the TS client — 429 (honoring
Retry-After) and 5xx are retried with exponential backoff; any other 4xx raises a
typed error immediately. Responses are plain snake_case dicts (the API's wire form).
It also ships verify_intent_token_offline, verify_webhook_signature, and
canonicalize (the action_payload hashing primitive), all identical to their TS
counterparts.
Verifier-only libraries
A downstream service such as a bank, a merchant or another agent that only needs to verify a human-intent proof shouldn't pull a whole SDK. The verifier libs are a few hundred lines with stdlib crypto:
from provenance_verify import fetch_jwks, verify_intent_token
jwks = fetch_jwks("https://api.provenance.example")
res = verify_intent_token(token, jwks)
if res.valid:
print("authentic and unexpired", res.payload["jti"])
import pv "github.com/provenance/provenance-verify"
jwks, _ := pv.FetchJWKS("https://api.provenance.example")
res := pv.VerifyIntentToken(token, jwks, 0)
if res.Valid { /* authentic + unexpired */ }
Limitations (every verifier, every language): offline verification checks
authenticity and expiry. action_payload hash binding needs the facts, and
revocation needs an online check.
For high-value actions call POST /v1/intent/verify (full check) or at least
GET /v1/intent/status/{jti}.
Cross-language guarantee
If you ever port the token format to another language, verify against
packages/core/test-vectors/tokens/intent-token-vectors.json (ES256 token cases) and
packages/core/test-vectors/canonical/ (canonical-JSON cases). Passing those vectors
is compatibility.