SDK docs · sdk/00

Integration overview

One verifying core, three ways to consume it: embed the Python SDK, self-deploy it as a service, or talk to your own service through a transport-only client.

MintID lets a verifier agency (a relying party: a bank, a marketplace, a platform) accept privacy-preserving identity presentations: a holder proves predicates — "over 18", "KYC grade at least A3", "credential active" — without revealing attributes, documents or identifiers. The SDK is how your backend asks for and validates those presentations.

One verifying core, three ways to consume it

Every deployment runs the same single verifying core (the Python SDK with its pinned Rust proof engine). Nothing else ever validates a presentation — that is a protocol rule (single-core, SPEC §14.4), not a packaging convenience.

ModeWhat you runFor whom
EmbeddedYour Python backend imports mintid-verifier-sdk and calls validate_presentation in-processPython backends; lowest latency, fewest moving parts
ServiceThe same SDK wrapped in a thin first-party HTTP service you self-deploy next to your backendAny backend language; operational isolation
Client@mintid/verifier-client (TypeScript, Node) — a transport-only client of your own service instanceNode/TypeScript backends (PHP next)

Two things follow from "transport-only" and are worth internalizing:

  • Clients carry no cryptography and no policy. The TS client is a few hundred lines of HTTP; it cannot verify, cache, weaken or skip anything. If your client-side code ever seems to need a verification feature, the feature belongs to the service.
  • The service is yours. Pointing your client at somebody else's verifier service would delegate the decision itself. Service mode adds transport, never authority.

What the SDK enforces that you cannot turn off

These are constants and closed types in the code — not configuration:

  1. The nine acceptance conditions run in full, in order, on every presentation: active verifier and exact origin on proven chain state; registered request key; unused nonce; inside the deadline; proof bound to the exact challenge (origin, verifier id, request key, nonce, policy, finalized chain height); every requested predicate proven; issuer operational with a current status root; a final proven-state recheck; and irreversible nonce consumption as the accept gate.
  2. Presentations live 10 seconds. The lifetime is a constant.
  3. Chain reads are proven or they don't count. Every RPC answer is verified with cryptographic (ics23) proofs against a trust anchor; claimed absence of a record fails closed. There is no "trust this node" mode.
  4. Retention is a closed schema. The only thing kept is a minimal decision record — session id, outcome, reason code, a 32-byte context digest, timestamp. Proof bytes, claim values and personal data structurally do not fit.

The decision model

Validation returns a decision, never throws for a rejection. reason_code comes from a closed vocabulary shared byte-for-byte across the Python SDK, the HTTP contract and every client — see reason codes. Transport-level problems (malformed body, service refusing to work from unproven chain state) are errors; domain rejections are data.

Where to go next:

  1. Getting started — verifier obligations first, then installation channels and current status.
  2. Python SDK — the embedded mode.
  3. Service mode — the deployable + the OpenAPI contract.
  4. TypeScript client.
  5. Conformance & versioning — how "every SDK behaves identically" is enforced, and what our version numbers promise.