Skip to main content
@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

The package is ESM and uses the standard 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 use guard 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 the kid that verified) and an allowance status of "allowed" or "unavailable".
  • action: "deny" carries a reason and the exact Response to return. Invalid signatures produce a 401, business denials produce the seller 402 payment_required body, and fail-closed allowance outages produce a 503.
Return 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, and decision.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-native Request 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:
A Next.js route handler already receives a web-native Request and returns a Response. The handle function above drops in as export async function POST(request: Request) in a route.ts file.
The signature covers the raw bytes ZeroClick sent: the percent-encoded path and query exactly as requested, and the unmodified body. An adapter that re-parses and re-serializes the body, or normalizes the URL, breaks verification. Hand the original request through untouched.

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.