Rate limits and throughput
Per-organization API rate limits, Retry-After semantics, and what governs carrier-side message throughput.
Two different things limit how fast messages move, and they are easy to conflate:
- API rate limits. How many requests per second AgentMessage accepts
from your organization. Exceeding them returns
429 RATE_LIMITED. - Carrier-side throughput. How fast carriers deliver your messages once accepted. This is governed by your 10DLC registration, not by AgentMessage.
API rate limits
Rate limits are applied per organization. When a limit is exhausted the API
returns 429 with code RATE_LIMITED and a Retry-After header carrying a
positive whole number of seconds:
HTTP/1.1 429 Too Many Requests
Retry-After: 1{
"success": false,
"error": {
"code": "RATE_LIMITED",
"message": "rate limited",
"request_id": "01JTBQH2FZ8K1RXC0WJ4Z9P3VM"
}
}Wait at least Retry-After seconds before retrying. Retry-After is sized
to the longer of the per-second and per-minute refill waits, so honoring it
beats fixed-interval retries. Read endpoints such as GET /v1/messages are
not rate limited.
Send limits scale with usage
POST /v1/messages is limited by a per-organization ladder that rises with
your lifetime spend. Each rung enforces a per-second and a per-minute bucket;
a request is admitted only when both have room. Current ladder:
| Tier | Lifetime spend | Per second | Per minute |
|---|---|---|---|
| 1 | $0 to $100 | 1 | 60 |
| 2 | $100 to $500 | 5 | 300 |
| 3 | $500 to $5,000 | 20 | 1,200 |
| 4 | $5,000+ | 100 | 6,000 |
Tier promotions apply automatically as your lifetime spend crosses each threshold and take effect shortly after the crossing; no request or review is needed.
Other rate-limited routes
A few sensitive routes carry their own per-organization limits:
| Route | Limit |
|---|---|
POST /v1/api-keys and POST /v1/api-keys/{id}/rotate | 10 per minute, shared between create and rotate |
POST /v1/webhooks/deliveries/{id}/replay | 10 per minute by default |
POST /v1/contacts/{contact_number}/erase | 100 per hour by default |
POST /v1/consent and POST /v1/consent/bulk | Per-organization; a bulk call counts by the number of records in the body. A batch larger than your per-minute allowance returns 422 VALIDATION_FAILED with a details.records hint to split it. |
All of these return the same 429 shape with Retry-After when exhausted.
Handling 429s well
- Honor
Retry-After; it is the earliest moment a retry can succeed. - Add jitter when many workers share one organization key, so they do not retry in lockstep.
- For sustained send volume, queue on your side and drain at your tier's per-second rate instead of bursting and backing off.
Carrier-side throughput
Passing the API rate limit does not mean instant delivery. Once a message is accepted, delivery speed is governed by the carriers, based on your 10DLC registration: brand, campaign, and the carriers' own per-campaign limits. Throughput varies by campaign and by carrier. API rate limits and carrier limits are additive; your effective send rate is the lower of the two.
For how carrier throughput is determined and what you can do about it, see How throughput works in the 10DLC help center.