REST API v1 · Reference
Rate limits
Per-endpoint token buckets, the headers that say what is left, and what to do when a bucket is empty.
API reference · Rate limits
How limits work
Limits are per-endpoint token buckets scoped to your workspace — not to your plan. Burst is how many requests you can fire back-to-back from a full bucket; sustained is how fast it refills. Separately, how fast WhatsApp actually delivers is governed by the messaging tier Meta assigns your phone number. When a workspace has more than one key, each key may use at most half of any bucket.
Every answer says what is left. Each response, a success or an error, carries three headers for the bucket the request used: RateLimit-Limit (the bucket’s burst size), RateLimit-Remaining (requests left) and RateLimit-Reset (seconds until the bucket is full again). When a request uses more than one bucket (your key’s half and the workspace’s), they describe the one closer to running out. A 401 has none (no bucket was used), and neither has an answer given while the limiter cannot be reached.
# A success from POST /send (bucket: 200, refilling 50 a second)
HTTP/1.1 200 OK
RateLimit-Limit: 200
RateLimit-Remaining: 187
RateLimit-Reset: 1
# The bucket is empty
HTTP/1.1 429 Too Many Requests
Retry-After: 1
RateLimit-Limit: 200
RateLimit-Remaining: 0
RateLimit-Reset: 4Handling Rate Limit Errors
A 429 Too Many Requests means the bucket is empty. It carries a Retry-After header in seconds: wait at least that long, then retry with exponential backoff — a burst of immediate retries will simply drain the bucket again. To avoid the 429 at all, slow down when RateLimit-Remaining gets low: spread what is left over RateLimit-Reset seconds, or pause until then.
A retry after a 429 or a dropped connection is safe with an Idempotency-Key: see Idempotency.
Every bucket
Each resource page lists the rows for its own endpoints.
| Bucket | Endpoints | Burst | Sustained |
|---|---|---|---|
| Reads | /messages · /conversations · /contacts · /templates · /phone-numbers · GET /webhooks · Instagram reads · GET /payment-requests/{id} | 600 | 60 / sec |
| Send | /send | 200 | 50 / sec |
| Media upload | /media | 200 | 50 / sec |
| Webhook admin | POST /webhooks | 60 | 30 / sec |
| Webhook changes | PATCH /webhooks/{id} · DELETE /webhooks/{id} | 60 | 1 / sec |
| Contact writes | POST /contacts · PATCH /contacts/{id} | 120 | 10 / sec |
| Contact erasure | DELETE /contacts/{id} | 20 | 1 / 3 sec |
| Inbox writes | PATCH /conversations/{id} · POST /conversations/{id}/notes (each its own bucket) | 120 | 10 / sec |
| Broadcast cancel | DELETE /broadcasts/{id} | 30 | 1 / 2 sec |
| Webhook secret rotation | POST /webhooks/{id}/rotate | 5 | 5 / hour |
| Template create | POST /templates | 50 | 50 / hour |
| Broadcast create | POST /broadcasts | 10 | 10 / hour |
| CRM writes | POST /leads · PATCH /leads/{id} · notes · POST /tasks · PATCH /tasks/{id} | 120 | 10 / sec |
| Instagram reply | POST /instagram/send | 120 | 30 / sec |
| Instagram comments | POST /instagram/comments/{id}/reply · /hide (each its own bucket) | 60 | 1 / sec |
| Instagram posts | POST /instagram/posts · POST /instagram/posts/{id}/cancel | 60 | 1 / sec |
| Instagram media | POST /instagram/media | 30 | 1 / 2 sec |
| Instagram live posts | GET /instagram/posts/recent | 30 | 1 / 2 sec |
| WhatsApp Pay | POST /payment-requests | 30 | 1 / 2 sec |
| Lead capture URL | POST /api/leads/capture/{token} (per sending address) | 30 | 30 / min |