Rate limits
The message and contact quotas per billing cycle are in Quota and usage, together with the 402/429 quota errors. This page documents only the rate limits, a separate concept.
Quotas and rate limits
Quota and rate limit are different controls:
| Quota | Rate limit | |
|---|---|---|
| What it measures | Total volume used in the billing cycle (messages, distinct contacts) | Instant speed of sends and calls |
| Window | Billing cycle being evaluated (cycle_start → cycle_end) | Seconds or minutes, unrelated to the cycle |
| Resets at | resets_at (end of the cycle) | A few seconds later (Retry-After) |
| Typical errors | 402 contact_quota_exceeded · 429 messages_quota_exceeded | 429 send_rate_spacing · 429 rate_limit_exceeded |
| Documented in | Quota and usage | This page |
Sending speed (per plan)
Each message sent through the API keeps a minimum interval from the previous send on the same number: this spacing between sends helps protect the number on WhatsApp. The interval depends on the plan:
| Plan | Minimum interval between sends | Equivalent in messages/min |
|---|---|---|
| Free | 6s | 10 msg/min |
| Lone Wolf | 1.2s | 50 msg/min |
| Business | 0.6s | 100 msg/min |
| Custom | 0.4s | 150 msg/min |
Sending before the minimum interval since the last successful send on that number returns 429 with the send_rate_spacing code and the Retry-After header (in seconds: the time left until the next allowed send):
- Retry-After: 2
{
"error": "send_rate_spacing"
} This limit is per number (main or extra): each number has its own spacing clock, so using extra numbers increases the account’s total sending capacity.
Contact refresh (per plan)
The contact refresh endpoint (POST .../contacts/{contact_id}/refresh) queries WhatsApp on the spot, unlike a simple read, so it has its own per-minute limit, which also grows with the plan:
| Plan | Refreshes/min |
|---|---|
| Free | 5 |
| Lone Wolf | 30 |
| Business | 120 |
| Custom | 600 |
Exceeding this limit returns 429 refresh_rate_limited with the Retry-After header.
Pairing extra numbers
Each POST /v1/numbers/{ref}/pair asks WhatsApp for a new code, which triggers a
notification on the number’s phone, or for a new QR code. The limit protects the number from being blocked
by WhatsApp itself for too many requests:
| Scope | Requests/min |
|---|---|
| Per number | 10 |
| Per account | 30 |
Exceeding either one returns 429 pairing_rate_limited with the
Retry-After header. See Pairing with the API.
Burst protection (the same on every plan)
These limits are fixed and apply to every plan:
messages_per_minute: 10,000 sends/minute per number (burst protection). Each number has its own count, adding up every request sent by it.recipients_per_day: 2,000 messages/day to the same recipient, per number (block protection). There is no limit on distinct recipients per day: you can reach as many contacts as you want, within the plan’s other quotas.
Internal controls
Besides the rate limits, Turbo Notify applies internal controls to protect the infrastructure and prevent abuse. These controls may temporarily restrict sending in situations such as:
- Abnormal traffic spikes coming from a single account.
- Sending patterns that could compromise the stability of the service.
- A high rate of consecutive failures or rejections.
WhatsApp’s rules
WhatsApp has its own rules and limits, which apply on top of Turbo Notify’s. Messages that recipients did not ask for, or report as spam, can lead WhatsApp to restrict the number even when you stay within those limits.
The recommendations in Protect your number help you avoid that, together with the WhatsApp policies (opens in a new tab) .
Related errors
| Status | Error code | Description |
|---|---|---|
429 | send_rate_spacing | A send before the plan’s minimum interval between messages, on the same number. |
429 | refresh_rate_limited | Contact refresh limit exceeded. |
429 | messages_per_minute_limit_exceeded | Burst protection: more than 10,000 sends/minute on the same number (see above). |
429 | recipients_per_day_limit_exceeded | Block protection: 2,000 messages/day to the same recipient, per number (see above). |
429 | warmup_limit_exceeded | Number connected only a few days ago: the daily volume is released gradually so WhatsApp does not treat the new number as suspicious. The Retry-After header tells how many seconds are left until the daily limit renews (midnight UTC). |
429 | duplicate_burst_blocked | The same text was sent to more than 20 recipients in the last hour, from the same number. Vary the content or space out the sends. |
429 | reply_ratio_too_low | Too few replies received compared with what the number sent, a sign of unsolicited sending. Reduce the volume to people who do not interact. It comes without Retry-After: waiting does not help, sending is accepted again when contacts reply or the volume drops. |
429 | pairing_rate_limited | Pairing requests (code or QR code) above the limit, see Pairing extra numbers. |
429 | rate_limit_exceeded | Your organization’s general API request limit exceeded (1,000 requests per second). Parallel requests are accepted as long as the total for the second stays below that. Wait for Retry-After and try again. |
503 | service_unavailable | Service temporarily unavailable, including when the organization’s plan could not be identified. The request was not processed. Try again in a few moments. |
For the quota errors (402 contact_quota_exceeded, 429 messages_quota_exceeded, 402 feature_not_available), see Quota and usage.
Best practices
- Respect the
Retry-Afterheader when you receive a429status. - Spread your sends over time instead of sending everything at once: your plan’s minimum spacing already sets the sustainable pace.
- Use extra numbers to increase your sending capacity.
- Monitor the API response codes to spot quickly when a limit is reached.
- Set up webhooks to follow message status without polling the API.