Rate Limits#
API rate limits and platform-specific quotas.
API Rate Limits#
By Plan#
| Plan | Requests/minute | Requests/day | Burst |
|---|---|---|---|
| Free | 60 | 10,000 | 10 |
| Pro | 600 | 100,000 | 100 |
| Business | 3,000 | 500,000 | 500 |
| Enterprise | 6,000+ | Custom | 1,000 |
Rate Limit Headers#
Every response includes rate limit headers:
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 599
X-RateLimit-Reset: 1705318260| Header | Description |
|---|---|
X-RateLimit-Limit | Max requests per window |
X-RateLimit-Remaining | Requests remaining |
X-RateLimit-Reset | Unix timestamp when limit resets |
Rate Limit Response#
When rate limited:
HTTP/1.1 429 Too Many Requests
Retry-After: 60
{
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit exceeded",
"details": {
"limit": 600,
"reset_at": "2024-01-15T10:31:00Z"
}
}
}Platform Rate Limits#
Each messaging platform has its own rate limits:
WhatsApp Business#
| Tier | Messages/Day | How to Upgrade |
|---|---|---|
| Tier 1 | 1,000 | Start here |
| Tier 2 | 10,000 | Good quality |
| Tier 3 | 100,000 | Sustained quality |
| Tier 4 | Unlimited | High volume |
Quality Score: Affects tier progression
- User responses
- Block rate
- Spam reports
Instagram#
| Scope | Limit |
|---|---|
| Per user | 250 messages/24 hours |
| API calls | 200/user/hour |
Facebook Messenger#
| Scope | Limit |
|---|---|
| Per recipient | 250 messages/24 hours |
| API calls | 200/user/hour |
| Batch | 1000 messages/batch |
Telegram#
| Scope | Limit |
|---|---|
| Private chats | ~30 messages/second |
| Groups | Varies by size |
| Bot API | 30 requests/second |
| Bulk notifications | 25-30/second |
Slack#
| Scope | Limit |
|---|---|
| Web API | 1 request/second (tier 1-4) |
| Posting messages | 1/channel/second |
| Events API | No explicit limit |
Discord#
| Scope | Limit |
|---|---|
| Per channel | 5 messages/5 seconds |
| Per user DM | 5 messages/5 seconds |
| Global | Varies by endpoint |
SMS (Twilio)#
| Number Type | Limit |
|---|---|
| Long code | 1 message/second |
| Toll-free | 3 messages/second |
| Short code | 100 messages/second |
Handling Rate Limits#
Exponential Backoff#
import time
import random
def send_with_backoff(send_func, max_retries=5):
for attempt in range(max_retries):
try:
return send_func()
except RateLimitError as e:
if attempt == max_retries - 1:
raise
# Exponential backoff with jitter
delay = (2 ** attempt) + random.uniform(0, 1)
time.sleep(delay)Request Queuing#
For high-volume messaging:
import asyncio
from collections import deque
class RateLimitedQueue:
def __init__(self, rate_per_second: float = 1.0):
self.queue = deque()
self.rate = rate_per_second
self.last_request = 0
async def enqueue(self, request):
self.queue.append(request)
await self._process()
async def _process(self):
while self.queue:
now = time.time()
wait_time = (1 / self.rate) - (now - self.last_request)
if wait_time > 0:
await asyncio.sleep(wait_time)
request = self.queue.popleft()
self.last_request = time.time()
try:
await request.execute()
except RateLimitError:
self.queue.appendleft(request)
await asyncio.sleep(60) # Wait for resetPlatform-Specific Handling#
class PlatformRateLimiter:
LIMITS = {
"whatsapp": {"per_second": 80, "daily": 1000},
"telegram": {"per_second": 30},
"slack": {"per_second": 1},
"sms": {"per_second": 1},
}
def __init__(self, platform: str):
self.limits = self.LIMITS.get(platform, {})
self.window_start = time.time()
self.request_count = 0
def can_send(self) -> bool:
now = time.time()
# Reset window if needed
if now - self.window_start >= 1:
self.window_start = now
self.request_count = 0
# Check rate
per_second = self.limits.get("per_second", float("inf"))
return self.request_count < per_second
def record_request(self):
self.request_count += 1Best Practices#
1. Respect Limits#
Always check rate limit headers and wait appropriately.
2. Implement Queuing#
Queue messages during high-volume periods instead of hitting limits.
3. Use Batch APIs#
Where available, batch multiple operations in one request.
4. Monitor Usage#
Track your API usage to anticipate limit issues:
query UsageStats {
application {
usage {
messagesThisMonth
apiCallsToday
}
}
}5. Plan for Spikes#
Account for traffic spikes in your rate limit strategy.
6. Upgrade When Needed#
Contact sales for higher limits on Enterprise plans.
Webhook Rate Limits#
Delivery Rate#
Outeract delivers webhooks as fast as your server accepts them. If your server is slow:
- Webhooks queue up
- Delivery may be delayed
- Eventually, oldest events may be dropped
Recommendation#
Return 200 OK immediately and process asynchronously:
@app.post("/webhook")
async def webhook(request: Request, background_tasks: BackgroundTasks):
body = await request.json()
background_tasks.add_task(process_webhook, body)
return {"received": True} # Return immediatelyMonitoring Rate Limits#
Check Current Usage#
query RateLimitStatus {
rateLimitStatus {
limit
remaining
resetAt
percentUsed
}
}Set Up Alerts#
Configure alerts when approaching limits:
- 80% usage warning
- 95% critical alert
- Rate limit hit notification