API keys and rate limits

Server-to-server calls to the KauZap API use an API key with only the scopes it needs.

Create a key

  1. A tenant admin opens Settings, Developers, and creates a key with a name and its scopes.
  2. The key is shown once. Store it in your secret manager; we keep only a hash and its first characters.
  3. If the create response is lost and you retry with the same Idempotency-Key, the replay shows the key masked. Create a new key and revoke the one you never saw.
  4. Revoke a key there at any time. Requests with it fail straight away.

Keys look like kz_ followed by 40 letters and digits. Send them in the Authorization header:

curl https://YOUR_API/v1/conversations \
  -H "Authorization: Bearer kz_…"

Never put an API key in a browser, a mobile app or a repository. Use signed URLs when something outside your server needs to write.

Scopes

ScopeAllows
contacts:read, contacts:writeRead, create and update contacts
conversations:read, conversations:writeRead and start conversations
messages:read, messages:writeRead messages and send bot or system messages
tags:read, tags:writeRead tags and tag conversations
groups:readRead chat groups
agents:readRead agents
webhooks:manageManage webhook endpoints
signed_urls:writeMint signed URLs
tickets:read, tickets:writeRead tickets and create a ticket from a conversation

A request without the scope it needs gets 403 with code forbidden, naming the missing scope.

Rate limits

Each key has its own limit. Over it, you get 429 with a Retry-After header in seconds. Wait that long, then retry; add jitter if several workers share a key.

Safe retries

Pagination and errors

Lists are paginated with a cursor: pass the next_cursor from one page to get the next. Page sizes have a maximum.

Every error has the same shape, with a stable code to branch on:

{ "error": { "code": "forbidden", "message": "…", "details": {} } }

See the API reference for every endpoint, its scopes and schemas.