Configuring the endpoint
ZeroClick derives the endpoint from the origin of your upstream base URL plus/zeroclick/access. Any path on the base URL is dropped: https://api.example.com/v1 gives https://api.example.com/zeroclick/access.
To host it elsewhere, set an override:
GET the same path returns the current accessEndpointUrl, plus salesEnabled (can buyers make new purchases) and servicingEnabled (can existing customers still recover and rotate keys). Changing those two is not self-serve — email help@zeroclick.ai.
The mint route is always the write route plus /{accessId}/keys.
Request headers
Both calls arrive asPOST with:
The account write
POST /zeroclick/access
Every money field is a string with exactly six decimal places.
parseMoneyUsd converts one to an integer count of millionths of a dollar (“micros”) so you never do floating-point math on money; formatMoneyUsd converts back.
Why the write is a complete picture
The write describes how the account should look, not what changed. Replay it, receive it twice, or receive an old one late: applying the newest version you have seen always leaves the account correct. That is whycreditGrantedUsd and creditReversedUsd are running totals rather than deltas.
deriveCreditDelta nets the two totals into one purse movement, and returns one of four outcomes:
The key mint
POST /zeroclick/access/zacc_8h2m4x0q9k1f/keys
maxKeys tells ZeroClick how many live keys this account may hold (the SDK sends 1 automatically when remintPolicy is "rotating"), and keyExpiresAt lets ZeroClick tell the buyer when to come back for a new one. Both are optional.
200
remintPolicy.
What your handlers receive
WriteInput, passed to onWrite:
MintInput, passed to onMint, is the same minus entitlement, with dedupeKey of mint:{requestId}. Its accessId comes from the URL path rather than a body.
What your handlers can return
onWrite:
onMint:
Before either handler runs, the SDK answers
401 on a missing, stale, or invalid signature, and 400 if the body is malformed or its agent does not match the signed zc-agent-id.
Retries, timeouts, and failures
Account writes are at-least-once. Expect duplicates, and expect a retry after a network timeout that happened after you committed.
When a delivery permanently fails, the buyer is made whole automatically: a reserved payment is released, a captured one is refunded. You never owe a refund for an account you did not create. If the refund itself fails, ZeroClick flags the account internally and follows up — there is nothing for you to do.
Because ZeroClick considers the write applied when you answer
200 with lifecycle: "active", do not start anything irreversible after that point.
Buyer-facing routes on your pay URL
Your customer’s agent uses these to manage a purchase, all on your pay URL (https://acme.pay.zeroclick.io) and all authenticated with the agent’s own bearer token. You do not implement them — ZeroClick does — but you may want to point agents at them.
Free plans
A$0 subscription or subscription_usage plan can create an account, but only for a buyer who has verified their email address — that is what stops one person minting unlimited free accounts. A buyer without a verified email cannot claim a live free plan. Once created, the free account is durable and recoverable across that verified buyer’s agents, just like a paid account.
Signature, for stacks without an SDK
The stateful helpers ship in the TypeScript SDK today. On any other stack, implement the two routes and verify the signature yourself. It is HMAC-SHA256 over these seven lines joined by\n — the ordinary canonical string plus a trailing purpose:
Select the purpose from the route you matched, never from anything in the request. That is what stops a signature captured from ordinary proxied traffic from authorizing an account write. Compare against the
v1= value in constant time, and reject a t= more than 5 minutes old or in the future.