Rate limits control how many API requests your application can make within a given time window. Throttling is the mechanism that enforces sending quotas — limiting how many emails or messages are dispatched per hour or day. Understanding both helps you design resilient integrations that never hit unexpected blocks.
Two Types of Limits
| Limit Type | What It Controls | Reset Frequency |
|---|---|---|
| API rate limit | Number of HTTP requests per minute to the API endpoints (not the number of messages sent) | Every 60 seconds (rolling window) |
| Sending throttle | Number of messages (emails, SMS, calls) actually dispatched per hour and per day | Hourly: top of each hour. Daily: midnight (your timezone) |
API Rate Limits — MigoSMTP
| Endpoint Category | Requests per Minute |
|---|---|
Email send (POST /email/send) |
300 requests/min |
Bulk email send (POST /email/send/bulk) |
60 requests/min |
Reporting & logs (GET /reports/*) |
120 requests/min |
Suppressions (POST /suppressions/*) |
60 requests/min |
Domain management (GET/POST /domains/*) |
30 requests/min |
| All other endpoints | 60 requests/min |
API Rate Limits — Telnxo
| Endpoint Category | Requests per Minute |
|---|---|
SMS send (POST /sms/send) |
300 requests/min |
Voice call initiate (POST /voice/call) |
60 requests/min |
WhatsApp send (POST /whatsapp/send) |
120 requests/min |
| Reporting & logs | 120 requests/min |
| All other endpoints | 60 requests/min |
Rate Limit Response Headers
Every API response includes rate limit information in the headers so your application can monitor usage in real time:
X-RateLimit-Limit: 300 X-RateLimit-Remaining: 247 X-RateLimit-Reset: 1717754460 Retry-After: 23
| Header | Meaning |
|---|---|
| X-RateLimit-Limit | Maximum requests allowed per minute for this endpoint |
| X-RateLimit-Remaining | Requests remaining in the current window |
| X-RateLimit-Reset | Unix timestamp when the current rate limit window resets |
| Retry-After | Seconds to wait before retrying (present on 429 responses only) |
Handling a 429 Too Many Requests Response
When you exceed the rate limit the API returns a 429 Too Many Requests response:
HTTP/1.1 429 Too Many Requests
Retry-After: 23
{
"success": false,
"error": "rate_limit_exceeded",
"message": "Too many requests. Please retry after 23 seconds.",
"code": 429
}
The correct way to handle a 429 response is exponential backoff with jitter:
// Pseudocode — exponential backoff with jitter
maxRetries = 5
baseDelay = 1000 // milliseconds
for attempt in 1..maxRetries:
response = api.send(request)
if response.status == 429:
retryAfter = response.headers['Retry-After'] * 1000
jitter = random(0, 500)
delay = max(retryAfter, baseDelay * 2^attempt) + jitter
sleep(delay)
continue
break // Success or non-retryable error
Sending Throttle vs API Rate Limit
Best Practices for Staying Within Limits
- Use the bulk send endpoint for high-volume sending — a single bulk API call dispatches hundreds of messages, using only one API request count rather than one per message.
- Monitor
X-RateLimit-Remainingin every response and slow down proactively when the value drops below 20% of the limit. - Implement exponential backoff on all API calls — not just on rate limit errors, but on any 5xx server error to handle transient failures gracefully.
- Distribute sending over time — rather than sending all emails in a burst at midnight, spread them over the day to stay within hourly limits and improve inbox placement.
- Cache API responses where possible — if your application repeatedly fetches the same template or suppression list, cache the result locally to avoid unnecessary API calls.
- Use webhooks instead of polling — rather than repeatedly calling the delivery status API for each message, subscribe to delivery webhooks to receive status updates in real time with zero polling overhead.