Base URL
/v1/ and speak JSON over HTTPS.
Authentication
Authenticate with an API key as a bearer token. Keys start withzc_ and are shown once. Create them in the dashboard under Settings → API keys. See keys and secrets.
Auth requirements differ by route group:
- Usage endpoints accept API keys only, with the split read and write scopes above. A dashboard session cannot call them.
- Sellers (including signing secrets), Services, Meters, Plans, Plan meter prices, Analytics, and Sandbox accept an API key (
admin:readfor reads,admin:writefor writes) or a dashboard session. - API keys, Organizations, Users, and Stripe Connect (except
POST /v1/stripe-connect/account-link, which acceptsadmin:write) are dashboard-session-only. An API key gets403 {"error":"auth_type_not_allowed"}. This is why API keys cannot mint more API keys.
403 {"error":"insufficient_scope"}.
Conventions
Ids are prefixed strings, returned in theid field and used in path and query parameters:
Lists are parent-scoped and unpaginated. List endpoints filter by a required parent id (
GET /v1/services?sellerId=sel_…, GET /v1/meters?serviceId=svc_…, GET /v1/plan-meter-prices?planId=pln_…) and return the full set in one response. There are no cursors or page parameters.
Timestamps are ISO 8601 strings in UTC. There are no webhooks; poll the analytics endpoints instead.
Errors
Errors return a machine-readable envelope, with an optional human-readablereason:
The errors reference catalogs every code.