@zeroclickai/sellers implements the ZeroClick billing guard for web-native TypeScript backends. It verifies that ZeroClick signed each forwarded request, checks the buyer’s allowance before you do the work, builds the refusal responses ZeroClick expects, and settles what was used. This page guards one route with it. The quickstart covers the same flow across all three SDKs, and the integration contract defines what the guard implements.
You need the keys from the quickstart: a signing secret (
zcsec_…) with its key id (hsec_…), and an API key (zc_…) with the usage:read and usage:write scopes. You can pass a scoped key per direction instead; see configuration. This page uses a service product-watch with a meter requests; substitute your own slugs.Install
Request, Response, fetch, AbortSignal, and Web Crypto APIs. It works in any runtime that provides those, including current Node.js and compatible edge runtimes. Nothing in the SDK is framework-specific; you adapt at the boundary, covered below.
Guard a route
Configure the client once, then useguard before doing work and withUsage on the successful response:
withUsage stamps the validated zc-usage header on the response so ZeroClick settles the usage synchronously; ZeroClick strips the header before the agent sees the response. Set it on successful (2xx) responses only. Settle usage covers the asynchronous alternative for work that outlives the request.
Decisions, not exceptions
guard always verifies the signature before it calls the allowance API. Its result is an explicit decision:
action: "allow"carries the verified context (zcRequestId,zcAgentId, the signature timestamp, and thekidthat verified) and an allowance status of"allowed"or"unavailable".action: "deny"carries areasonand the exactResponseto return. Invalid signatures produce a401, business denials produce the seller402 payment_requiredbody, and fail-closed allowance outages produce a503.
decision.response unchanged: each body is exactly what ZeroClick expects back from your API. The API reference lists every deny reason, and errors draws the line between decisions and thrown ZCErrors.
Anonymous probes
Signed anonymous probes are valid requests. To price a pay-as-you-go challenge, ZeroClick forwards the agent’s unpaid request upstream with no agent id: the signature verifies, anddecision.context.zcAgentId is null. Only the paid retry carries the agent id (agt_…). Treat probes like any other request: run the same guard and return the same responses. The 402 refusal a probe earns is exactly what ZeroClick re-prices for the agent.
Framework integration
Adapt your framework’s request object to a web-nativeRequest at the boundary. Preserve the exact method, URL, headers, and body bytes. The SDK reads a clone, so the original request body remains readable in your handler. Return the SDK-provided Response directly, or adapt it back to the framework’s response type.
A framework that already speaks web standards needs no glue. Hono hands you the untouched request as c.req.raw:
Request and returns a Response. The handle function above drops in as export async function POST(request: Request) in a route.ts file.
Next steps
Configuration
Every
createSeller option: rotation, split keys, timeouts, outage policy.API reference
Every export, decision shape, and deny reason.
Errors
ZCError codes and what throws where.Charge up to a maximum
Bill work you can’t size up front, like output tokens.