Integration overview
Every integration runs the same verifying code: embed the Python SDK, deploy it as your own service, or call that service from a transport-only client.
Your backend asks a holder to prove a predicate, such as "over 18", "KYC grade at least A3" or "credential active", and gets a decision without ever seeing attributes, documents or identifiers. The SDK issues that request and validates the answer for a verifier agency: a relying party such as a bank, a marketplace or a platform.
The MintID code, meaning the chain, the proof core and the SDKs, is licensed under Apache-2.0, and every package manifest declares it. Its source is published from the main repository, at gitlab.com/mintid/mintid, with a read-only mirror for each client:
| Mirror | Package | Registry |
|---|---|---|
| https://gitlab.com/mintid/sdk-typescript | @mintid-net/verifier-client | npm (npm install @mintid-net/verifier-client) |
| https://gitlab.com/mintid/verifier-mcp | @mintid-net/verifier-mcp | npm (npm install -g @mintid-net/verifier-mcp) |
| https://gitlab.com/mintid/sdk-holder | @mintid-net/holder (with its WebAssembly module) | npm, from the first release whose signed manifest lists it |
| https://gitlab.com/mintid/sdk-python | mintid-agent (with mintid-proof-core) | PyPI (pip install mintid-agent); mintid-verifier-sdk on PyPI too |
| https://gitlab.com/mintid/sdk-go | Go module gitlab.com/mintid/sdk-go | fetched from the mirror |
The verifier SDK itself (mintid-verifier-sdk) is in the main project and on PyPI (pip install mintid-verifier-sdk). Install lines are in getting started.
The same verifying code, whether you embed it, host it or call it
Every deployment runs the same single verifying core — the Python SDK, with its proof engine built in at a fixed version. Nothing else ever validates a presentation, and the protocol’s single-core rule makes that binding on every deployment.
| Mode | What you run | For whom |
|---|---|---|
| Embedded | Your Python backend imports mintid-verifier-sdk and calls validate_presentation in-process | Python backends; lowest latency, fewest moving parts |
| Service | The same SDK wrapped in a thin first-party HTTP service you self-deploy next to your backend | Any backend language; operational isolation |
| Client | @mintid-net/verifier-client (TypeScript, Node) — a transport-only client of your own service instance | Node/TypeScript backends; further languages as demand appears |
Transport-only has two consequences:
- Clients carry no cryptography and no policy. The TypeScript client is a thin HTTP layer; 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, with no configuration switch:
- 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, finalised chain height); every requested predicate proven; issuer operational with a current status root; a final proven-state re-check; and irreversible nonce consumption as the accept gate.
- Presentations live 10 seconds. The lifetime is a constant.
- Chain reads are proven or they don’t count. Every answer from a chain node is checked with a cryptographic store proof against your trust anchor — today, a node you run yourself — and a claimed absence that cannot be proven fails closed. There is no “trust this node” mode.
- Retention is closed. The only thing kept is a minimal decision record — the session, the outcome, the reason code, a digest of the bound context and the time. 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:
- Getting started — verifier obligations first, then installation channels and current status.
- Becoming a verifier — what registration puts on chain, and which steps are still done by hand.
- Python SDK — the embedded mode.
- Service mode — the deployable + the OpenAPI contract.
- TypeScript client.
- Conformance & versioning — how "every SDK behaves identically" is enforced, and what our version numbers promise.
- Protocol state — what is stable, draft and absent, before you commit a date to anyone.
- @mintid-net/holder — the holder library compiled to WebAssembly, for a page or a service that keeps its own custody record.
- Agent clients — the runtime side of an agent credential, in Python and TypeScript: the payment loop, a policy checked before any challenge, minting from a separate holder.
- Agent-to-agent handshake — an agent proves a human behind it at the start of an A2A or MCP session (provisional).
- Verify a release — the signed release manifest, and how to check a package or an image against it with the release key alone.
- Check a presentation in the browser — the proof core compiled to WebAssembly verifies a synthetic presentation on your own device, then refuses it twice on purpose; nothing is sent anywhere.