Skip to main content

Rate limits

Limits apply per project (not per token, not per user, not per IP) and are shared across every endpoint — the quota is one pool, so calls to /v1/messages and /v1/crm/tickets draw from the same budget. The three windows stack, and the tightest one wins. The daily cap is the one that matters: at a steady pace it is roughly 40 requests per hour, which is what the hourly window is sized around. The minute window lets a batch job move at 60 a minute for a short stretch; the hourly window is what stops that stretch from spending the whole day in a few minutes.
1,000 per day is a hard ceiling per project, not a soft target. Once you hit it, every request returns 429 until the window rolls over. Size your polling intervals and batch jobs against it before you go to production.Minting a second token does not double your quota. All tokens issued against the same project share one budget. To isolate a noisy job from your transactional path, put them in separate projects.
If you cross a limit:
The message names the window you hit and when it frees up, so you can tell a one-minute burst apart from a spent hourly allowance or a spent daily budget.
The MCP server is outside these limits. Tool calls on POST /v1/mcp are not counted against the per-minute or per-day quota. That is convenient and also a footgun: an agent stuck in a loop generates real upstream traffic with nothing stopping it, so cap it on your side.

Read the headers instead of waiting for the 429

Every response carries the state of each window, so you can self-throttle before you get blocked: The same trio exists for -minute and -hour. A healthy integration watches X-RateLimit-Remaining-day and slows itself down as it approaches zero, rather than sprinting into a wall. Every window is rolling, not aligned to a clock boundary: each one opens on your first request and closes a minute, an hour or 24 hours later.
Need more throughput (e.g. bulk-syncing a CRM with hundreds of thousands of contacts)? Email support@keebai.com with your expected volume and we’ll raise the cap on your project.

What does not count

Requests to /health are exempt. Broadcasts count as one request each, not one per recipient — POST /v1/messages/bulk with 5,000 recipients costs a single unit, which makes it far cheaper than looping over POST /v1/messages.

How to handle 429 properly

Retrying a minute-window 429 and retrying a day-window 429 are different problems. Exponential backoff over a few seconds clears the first and does nothing for the second — if your daily budget is gone, no amount of waiting inside the request path will bring it back. Read Retry-After-<window> and decide:
Don’t tight-loop retries — you’ll burn the rest of the quota on requests that were never going to succeed.

Staying under 1,000 a day

Prefer webhooks over polling

A poll every minute is 1,440 requests a day — over budget before you send anything. Subscribe to events and let Keebai push instead.

Batch your sends

One bulk broadcast costs one request regardless of recipient count. A loop over 500 contacts costs 500.

Cache what rarely changes

Channels, templates, branches, and services change on a human timescale. Fetch them once at boot, not once per message.

One project per workload

The quota is per project, so tokens are not how you isolate. Give a noisy batch job its own project and it cannot starve your transactional path.

Error format

Every error is wrapped in the same envelope, with a stable machine-readable code and, on some errors, a details object:
Branch on code, never on message — the wording can change, the slug will not.

Best practices

Idempotency

Design retries to be safe. GET and DELETE are idempotent out of the box; for POST/PATCH, dedupe on your side with stable identifiers.

Sensible timeouts

Set a client timeout between 10 and 30 seconds. Lower kills legitimate requests; higher locks your thread on transient slowness.

Log everything useful

Log status, request id (when the API returns one in headers), and duration. Future-you will thank you.

Circuit breaker

On repeated 5xx, pause requests for a few seconds. Your system stays up for everything else that doesn’t depend on Keebai.

In production

  • Monitor latency, error rate, and status codes. An alert on error rate >5% catches issues before users do.
  • Rotate tokens every 90 days, incident or not. Mint, deploy, validate, revoke the old.
  • Audit Last used in the tokens table periodically. Tokens unused for months are revoke candidates.
  • Suspect us? Check status.keebai.com first — it reports availability per component and any open incident, and it runs outside our cluster so it stays up when the API does not. If nothing is reported there, email support@keebai.com.