Rate limits
How many requests flow trigger URLs accept, how the limits answer, and how to retry.
The limits below apply to flow trigger URLs (POST /hooks/{token}).
Limits for the REST API will be published with it.
| Limit | Counted per | Answer |
|---|---|---|
| 60 requests a minute | flow trigger URL | 429, {"status": "rate_limited"} |
| 1,000 requests an hour | account, all URLs together | 429, {"status": "rate_limited"} |
| 120 requests a minute | client IP address | 429, plain text Too many requests |
| Templates automations may send per day | account and its projects | 429, {"status": "template_limit_reached"} |
| 3 templates from automations in any 24 hours | customer | 429, {"status": "customer_limit_reached"} |
The minute and hour windows are fixed: they reset at the start of each clock minute and hour. The per-address limit is a sliding one-minute window that exists to slow down guessing of URLs; a single integration stays well below it.
Every request to a valid URL counts towards the per-URL and per-account limits, including
requests refused afterwards for another reason (a body that is not JSON, a flow that is
switched off) and repeats of an Idempotency-Key already used. Requests refused for their
Content-Type or their size are not counted.
The two template limits are checked before a contact or conversation is created, and runs that are queued but have not sent their template yet count towards them.
When our counters are unavailable
If we cannot count requests, flow trigger URLs refuse the request with
503 service_unavailable rather than accept it unlimited: each accepted request can end in
a paid WhatsApp template.
Retrying
- Retry
429and503with exponential backoff, starting at about a minute. - Send the same
Idempotency-Keyon every retry of one event, so a request that was accepted but whose answer you did not receive starts nothing new. See Idempotency. - Do not retry other
4xxanswers unchanged: they fail the same way every time. The full list is in Responses and errors.