There is no key to paste into your client, no secret in a config file, and no local process to keep running.
Add the server URL to your client.
Your client opens Hub to authorise.
Enter a key your account owns.
SDKs
Two packages, one verification contract.
Both run on Node.js 18 or later, default to api.affix-io.com, and expect AffixIO ML-DSA-65 attestation on the payload in production. The difference is how the host proves.
Zero-knowledge
affixio
Your host generates an UltraHonk proof over a bundled Noir circuit. AffixIO verifies it, signs the result with ML-DSA-65, and anchors the digest in the Merkle audit.
npm install affixio
import { AffixSDK } from "affixio";
const sdk = new AffixSDK({
apiKey: process.env.AFFIX_API_KEY
});
Proving Barretenberg UltraHonk via @aztec/bb.js, over bundled circuits including simple_yesno and yesno.
Modesauto falls back to local prove when AffixIO is unreachable, offline always proves locally and queues, online requires a live licence and still proves locally.
Storage JSON under .affix/ by default, with pluggable Redis, SQL or custom get/set backends for documents and the queue.
Audit Client batches of up to 50,000 digests per Merkle audit submission.
Carriers PII-free QR and barcode output. Presentment links use your host base only.
Where UltraHonk is too heavy, Light binds a yes or no decision and its witness with a shared light key using HMAC-SHA256. AffixIO still attests the digest with ML-DSA-65.
npm install affixio
import { AffixSDK } from "affixio";
// Light HMAC prove is the default
const sdk = new AffixSDK({
apiKey: process.env.AFFIX_API_KEY
});
Proving AffixIO Light HMAC-SHA256 on Node crypto. These are not SNARKs, and the trade is stated plainly.
Dependencies Node crypto plus optional QR libraries. No Noir, no bb.js.
Flush Adaptive sync roughly every second, with higher batch ceilings once ingest rises above 20 proofs per second.
Signing AffixIO ML-DSA-65 attests a proof when it is verified with requestAttestation: true or sent to POST /v1/attest/proof; the digest is appended to the (unsigned, rolling 50,000-leaf) Merkle audit tree. See trust model.
Pick Light when presentment has to feel instant and the threat model accepts an HMAC-bound decision rather than a full SNARK. Pick the enterprise package when the proof itself has to stand on its own.
API surface
What sits behind the SDKs and the MCP tools.
Everything below is the same HTTP surface, whether you call it from Node, curl, or an agent holding an OAuth token. Base URL https://api.affix-io.com. Authenticate with Authorization: Bearer or X-API-Key.
Circuits, prove and verify
GET /v1/circuitsCatalogue of available circuits
POST /v1/circuits/{id}/proveGenerate a proof, optionally attest, anchor the digest
POST /v1/circuits/{id}/verifyVerify a proof and spend the digest on success
POST /v1/witness/prepareBuild witness inputs without proving
POST /v1/aggregate/verifyVerify up to 25 proofs in one request
Attestation
POST /api/attestSign a client payload with ML-DSA-65 (wrapped, server_verified:false; not a proof attestation)
POST /v1/attest/proofServer-verify an UltraHonk proof and ML-DSA-65 sign the verified result
POST /api/attest/verifyCheck a payload against its attestation
GET /v1/attestation/public-keyPublish the verification key
GET /.well-known/affix-mldsa65.jsonSame key at a well-known path, no auth
Merkle audit
GET /v1/merkleRoot, leaf count, algorithm, limits
GET /v1/merkle/proof/{digest}Inclusion proof for a digest
POST /v1/merkle/auditAppend a single audit leaf
POST /v1/merkle/audit/batchAppend up to 1,000 leaves per request
POST /v1/merkle/verify-proofCheck inclusion client-side against a root
Gates, spend and revocation
POST /v1/gate/verifyAdmit or refuse, with optional consume
GET /v1/spent/{digest}Look up whether a digest has been spent
POST /v1/spent/revokeMark a proof spent or revoked
GET /v1/edge/spent-packBulk spent set for edge sync
GET /v1/verify/reason-codesThe reason codes a gate can return
Carriers and presentment
POST /v1/token/issueShort token carrier
POST /v1/link/issueLink carrier for presentment
POST /v1/claims/issueJWT or SD-JWT claim
POST /v1/wallet/passWallet pass payload
POST /v1/otp/issueOne-time code carrier
POST /v1/nfc/encodeNFC payload, with BLE, EMV and magstripe equivalents
Higher-assurance gate operations
POST /v1/devicesRegister a device, secret returned once
POST /v1/gate/multifactor/startMulti-factor gate session
POST /v1/gate/quorum/startQuorum approval across devices
POST /v1/delegate/issueDelegation token with verify and consume
POST /v1/mdl/verifyMobile driving licence device response
Identity parsing
POST /v1/mrz/parseParse a passport MRZ and suggest a prove path. Passport PII is not stored.
POST /v1/aamva/parseParse AAMVA PDF417 from a driving licence. Licence PII is not stored.
Open, no key required
GET /api/healthService status, circuit readiness, policy version
GET /api/governance-statsLeaf counts and circuit breakdown
GET /v1/merkle/rootCurrent Merkle root snapshot
These three are the fastest way to confirm the service is live before you write any integration code.
Engineering contract
The behaviour you have to design around.
Retries, replays and double spend are where verification integrations usually break. These rules are part of the contract, not implementation detail.
Rate limiting
The default is 10 requests per second per key, scoped to the key or to key and IP. Read your remaining budget from the response rather than guessing.
Exceeding it returns 429 with Retry-After. Back off on that header instead of a fixed sleep.
Idempotency
Send Idempotency-Key on prove and verify POSTs. A replay inside 24 hours returns the original 2xx body and marks it.
POST /v1/circuits/yesno/verify
Idempotency-Key: 4f1c...9ab
200 OK
Idempotency-Replayed: true
This is what makes a network timeout safe to retry without minting a second result.
Single use by design
A successful verify spends the digest. Presenting it again returns 409 double_spend_detected. That is the intended behaviour for a one-time eligibility proof, not an error to route around.
If you need repeat checks without consuming, use the non-consuming read paths instead.
Tracing and limits
Every response carries X-Request-Id. Log it. It is the reference that makes a support conversation short.
JSON bodies are capped at 2 MB. Responses are sent no-store, apart from the attestation public key, which is cacheable for an hour.
Connection flow
The key stays with AffixIO.
The client opens AffixIO Hub in your browser. After you sign in and enter an account-owned API key, the client receives a short-lived OAuth token bound to this MCP server.
The LLM sees tool definitions and tool results. It does not receive your Hub password or raw API key.
What the client holds
An access token bound to https://www.affix-io.com/mcp/, valid for one hour.
What stays in Hub
The API key itself, matched to your account on every tool call.
Staying connected
Clients that request offline access receive a refresh token they can exchange without another sign-in.
Cutting access
Revoke the connection in Hub, or revoke the key to stop every connection using it.
Client support
Built to the remote MCP standard.
Use any client that implements Streamable HTTP, protected-resource discovery and OAuth 2.1 with PKCE.
ChatGPT
Add the URL as a custom connector or remote MCP server where your plan supports it.
Claude
Add a remote connector, then complete the AffixIO authorisation screen in your browser.
Cursor and coding clients
Configure the remote server URL. OAuth-capable clients open Hub when authentication is required.
Gemini and agent frameworks
Native OAuth clients connect directly. Older frameworks may need their remote MCP bridge.
Tool surface
The API contract remains the source of truth.
The server exposes authenticated read and write tools for AffixIO /v1 and supported /api paths. Hub administration, API key management, OAuth administration and webhook administration stay outside the MCP tool surface.
affix_api_readGET requests against published AffixIO API paths
affix_api_writePOST, PATCH and DELETE with destructive-action signalling
affix-openapiCurrent OpenAPI schema as an MCP resource
affix_api_read
Send an authenticated GET request to an AffixIO /v1 or /api endpoint. Takes path and an optional query object.
readOnlyHint true
idempotentHint true
openWorldHint false
Clients that respect these annotations can run reads without prompting the user each time.
affix_api_write
Send an authenticated POST, PATCH or DELETE. Takes method, path, optional query and a JSON body. Requires the mcp:write scope on the token.
readOnlyHint false
destructiveHint true
idempotentHint false
The destructive annotation is deliberate. A verify call spends a proof, and that is not reversible.
Paths the server refuses
Account, key, OAuth and webhook administration are excluded from the tool surface. A connected model cannot mint keys, read your key list, register OAuth clients or change webhook secrets.
Being readable by people is no longer the whole job.
Answer engines summarise and cite. Agents read a contract and then act on it. Both behave better against a site that publishes structure instead of leaving it to be inferred from prose.
None of this is a ranking trick, and nobody can promise placement in a generated answer. What it does is remove the reasons a model skips you: no machine contract, no stable URL, no clear answer near the question, no way to act once it has decided you are relevant. The list below is what we run on this site, and you can check every item against the live files.
01
Publish the contract, not just the pitch
An OpenAPI schema is the difference between a model describing your product and a model calling it. Without one, an agent guesses your paths and fails quietly. Keep it generated from the running service so it cannot drift.
02
Write an llms.txt and keep it short
A plain-text brief at the root gives a model the summary you would give a new engineer: what the product does, the terms you use, the endpoints that matter, what you do not claim. Ours sits at /llms.txt with a longer companion at /llms-full.txt.
03
Answer inside the first forty words
Write the heading as the question a person would type, then answer it directly underneath before any context. Extractive systems lift the sentence next to the heading. If your answer arrives in paragraph four, it does not get quoted.
04
Mark up what the page already says
JSON-LD for Organization, SoftwareApplication, FAQPage and HowTo removes ambiguity about which text is the answer and which is commentary. Mark up content that exists on the page. Schema describing text a reader cannot see is a liability.
05
Give numbers, not adjectives
Ten requests per second, 50,000 leaves per batch, a 24 hour idempotency window. Specific figures survive summarisation because they are quotable. Descriptions like fast and scalable are dropped, and they are unverifiable anyway.
06
Use the well-known paths
Conventional locations are checked without being told. We publish agent.json, OAuth protected-resource metadata for MCP discovery, security.txt, and the ML-DSA-65 public key at a well-known path on the API host.
07
Ship a server, not only documentation
Documentation gets a model to describe you. An MCP server lets it do the work in front of the user, which is the point at which you stop being a search result and start being part of the workflow. Read access with clear annotations is enough to start.
08
Keep URLs still
Citations are cached and reused for months. A canonical that moves, a redirect chain, or a docs path that changes with every release turns an earned reference into a dead link. Version the content, not the address.
09
Set crawler policy on purpose
max-snippet:-1 and max-image-preview:large tell engines they may quote you properly. Decide separately, and explicitly, which AI crawlers you allow in robots.txt. Blocking everything and expecting citations is not a strategy.
10
Date the page and mean it
A visible last-updated date and a matching dateModified in structured data help a model decide whether your figure or a competitor's older one is current. Only move the date when the content actually changes.
11
Define your own vocabulary
If your product invents terms, define them somewhere stable and link to it. Ours is the glossary. A model that cannot resolve your term either omits it or invents a meaning, and the second is worse.
12
State the limits
Say what the product does not do. Models weight sources that bound their claims, and buyers reach the same conclusion. We say plainly that AffixIO is not a compliance certification, and that Light proofs are not SNARKs.
Machine surfaces on this site
Every entry is live. Fetch any of them and compare against what this page says.
Key custody, SDK choice, retries and discoverability.
Does the LLM receive my AffixIO API key?
No. Hub checks the key and issues the MCP client a revocable OAuth token. The raw key is not included in that token.
Which LLMs can use the server?
The model is not the connecting component. Its MCP client or host must support remote Streamable HTTP and OAuth. Current ChatGPT, Claude, Cursor and Gemini clients support remote MCP in relevant products.
What happens when a key is revoked?
The MCP connection stops resolving that key. OAuth access tokens are also short-lived, and refresh connections can be revoked independently.
What is the difference between affixio UltraHonk and Light modes?
The enterprise package proves locally with UltraHonk over bundled Noir circuits, which suits servers with a zero-knowledge budget. Light proves with AffixIO Light HMAC-SHA256 on Node crypto, for phones, kiosks and ordinary hosts where UltraHonk is too heavy. Light proofs are not SNARKs.
Both need Node.js 18 or later, default to api.affix-io.com, keep an offline queue, anchor Merkle audit, and receive ML-DSA-65 attestation from AffixIO.
How do I authenticate with the AffixIO API?
Send your key as Authorization: Bearer <key> or X-API-Key: <key> against https://api.affix-io.com. The default limit is 10 requests per second per key, reported on every response through X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. Going over returns 429 with Retry-After.
How do I safely retry a verify request?
Send an Idempotency-Key on prove and verify POSTs. A repeat within 24 hours returns the original successful body with Idempotency-Replayed: true, so a timeout can be retried without minting a second result.
Remember that a successful verify spends the digest. Presenting it again returns 409 double_spend_detected, which is the intended behaviour for a one-time proof.
How do you make an API discoverable to AI answer engines and agents?
Publish a machine contract instead of only marketing copy: an OpenAPI schema, an llms.txt brief at the site root, JSON-LD for content that is actually visible on the page, well-known manifests such as agent.json and OAuth protected-resource metadata, and an MCP server so an agent can act rather than only read.
Then write for extraction. Answer directly under the heading, give figures rather than adjectives, keep canonical URLs stable, set crawler policy deliberately, and state what the product does not do.
What is the AffixIO MCP server?
An MCP surface over the verification API so agents use real tools, not invented routes.
Should I ignore OpenAPI if I have MCP?
No. OpenAPI remains the HTTP source of truth.
How should agents cite AffixIO?
llms.txt, OpenAPI, and the for-agents page.
Post-quantum readiness
Post-quantum deadlines now reach businesses, not only government.
Encrypted traffic and signed records captured today can be stored now and broken later, once a quantum computer can run the maths. Security teams call it harvest now, decrypt later. The response is to move the evidence you rely on onto signatures that still stand up after today's public-key cryptography is retired.
By 2028
Know your cryptography
The NCSC expects a full discovery of where you depend on cryptography, and an initial migration plan. This is the position suppliers and auditors ask about first.
By 2031
Migrate the priorities
Your highest-priority systems move to post-quantum algorithms. New evidence you issue should already be signed with a standardised scheme, not one being deprecated.
By 2035
Finish the move
The NCSC sets 2035 for full migration. NIST IR 8547 sets the same year to retire RSA, ECDH and ECDSA across US federal systems, so the UK and US timelines meet here.
How the rulings apply to you
Guidance for government, pressure for everyone in the supply chain.
The NCSC dates are guidance, and the technical baseline regulators reference for operators of essential services under the NIS Regulations. In the US, the Quantum Computing Cybersecurity Preparedness Act 2022 already requires federal agencies to inventory their cryptography and plan migration, with NSM-10 pointing at the same 2035 horizon. Most private companies are not bound to the dates directly. If you sell into government, finance, healthcare or critical infrastructure, you will be asked to show where you stand against them.
Last updated . Figures on this page are defaults and can differ under contract. The machine-readable version is at /mcp/llms.txt.
MCP access is not unlimited permission
An authenticated MCP connection does not automatically authorize every proposed action. AI assistants and personal-superintelligence applications need the same tool-side checks. Calling an AffixIO tool does not automatically protect unrelated tools; enforce the gate before each covered operation.