Skip to main content
create_seller returns a blocking SellerClient for WSGI apps; create_async_seller returns a non-blocking AsyncSellerClient for ASGI apps. Both accept the same keyword arguments and make the same decisions. Configure one client at startup and reuse it for every request. The client validates its configuration at construction, not when the first request arrives: any invalid combination raises ZCError with code malformed_input (see errors).

Options

Mapping[str, str]
Signing secrets keyed by key id: {"hsec_…": "zcsec_…"}. Every zc-signature header names the kid it was signed with, and the SDK uses it to pick the matching secret. The mapping must contain at least one entry. Provide exactly one of signing_secrets or resolve_signing_secret. Passing both, or neither, raises at construction.
Callable[[str], str | None]
A lookup function in place of the static mapping, for secrets that live in a secret manager. It receives the kid from the request’s signature header and returns the secret, or None for an unknown kid. If it returns None, the SDK denies the request with the 401 response rather than raising. If the function raises, or returns anything other than a non-empty string, the SDK raises ZCError with code signing_secret_resolution_failed.
str
An API key carrying both the usage:read and usage:write scopes. It backfills whichever of the two scoped keys you leave unset, so a single key is enough for the whole client.
str
A key with the usage:read scope, used for allowance checks (guard and check_allowance). When unset, it falls back to api_key.
str
A key with the usage:write scope, used for usage reporting (report_usage). This is handy when a separate worker reports usage. When unset, it falls back to api_key.
str
default:"https://api.zeroclick.io"
Base URL for the ZeroClick usage API. Override it only to point the SDK at a test double.
int
default:"300"
Maximum accepted difference, in seconds, between the timestamp in the zc-signature header and the current clock. The SDK denies a request outside the window with the 401 response (reason stale_timestamp).
str
default:"allow"
What guard does when the allowance API gives no usable answer after a signature has verified: "allow", "deny", or "throw". Any other value raises at construction. See outage policy below.
float
default:"1.5"
Timeout, in seconds, for calls to the ZeroClick usage API, passed to httpx per request. Despite the name, the client applies it to both allowance checks and usage reports. The SDK never retries a timed-out call.
Callable[[ZCError], None]
Called with the ZCError whenever the allowance API fails to answer during guard. The hook runs before the SDK applies the policy, whatever the policy is. Use it for operational logging and metrics; it does not change the decision.
Callable[[], float]
default:"time.time"
The time source for signature freshness checks. Inject a fixed clock in tests to verify recorded requests without patching time.time.
httpx.Client | httpx.AsyncClient
Your own configured httpx client (httpx.Client for create_seller, httpx.AsyncClient for create_async_seller), for when you need proxies, event hooks, or connection limits. When omitted, the SDK constructs one. Closing the seller client closes whichever httpx client it holds, injected or not.

Keys: one or two

api_key must carry both usage scopes. To follow least privilege, pass two scoped keys instead and omit api_key. The read key covers allowance checks, and the write key covers usage reporting:
The constructor validates coverage. If neither api_key nor the scoped key covers a side, it raises ZCError with code malformed_input naming the missing key: Provide usage_read_key (or a both-scopes api_key) for allowance checks, or Provide usage_write_key (or a both-scopes api_key) for usage reporting.

Rotating signing secrets

signing_secrets takes any number of entries, and the kid in each request selects the right one, so rotation is zero-downtime. Create the new secret. Deploy with both entries. Once ZeroClick signs only with the new kid, drop the old entry:
The key ids are not secret: they appear in every zc-signature header. See keys and secrets for the rotation workflow in the dashboard.

Outage policy

allowance_unavailable_policy applies only when the allowance API gives no answer (a timeout, a transport failure, an error status, or a malformed response), and only after a signature has verified. It never applies to a missing or invalid signature, and an allowed: false answer is a normal 402 denial, not an outage.
  • "allow" (default): serve the request. The decision is an allow with allowance == "unavailable", so you can tell it apart from a confirmed "allowed".
  • "deny": return the SDK’s 503 {"error":"allowance_unavailable"} response.
  • "throw": the SDK raises the ZCError for your application to handle.
Whatever the policy, the SDK calls on_allowance_unavailable first with the underlying error. See errors for which error codes the policy covers.

Lifecycle

Both clients hold an httpx client, so a long-lived module-level instance is the normal shape. Create the client at import time and reuse it for every request, as the quickstart examples do. For short-lived processes (scripts, workers, tests), close the client explicitly with close() / aclose(), or use it as a context manager: