Rate Limits & Idempotency
SendComms uses rate limiting to ensure fair usage and protect our infrastructure. We also support idempotency keys to prevent duplicate requests from being processed multiple times.
Rate Limit Headers
All API responses include headers to help you track your rate limit status:
X-RateLimit-Limit: 5 # Max requests in window
X-RateLimit-Remaining: 3 # Requests remaining
X-RateLimit-Reset: 1766452500 # Unix timestamp when limit resetsRate Limit Exceeded Response
When you exceed your rate limit, you'll receive a 429 status code:
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Please try again later.",
"limit": 5,
"remaining": 0,
"reset": 1766452500,
"retryAfter": 39
}
}Best Practice
Use the Retry-After header to determine when to retry your request. Implement exponential backoff for production applications.
Rate Limits by Service
Rate limits vary by service and plan, and are applied per account — every API key on the account shares the same counters. The per-minute and per-day windows are fixed windows; the monthly window is a calendar month that resets at 00:00 UTC on the 1st. Sandbox requests made with ansc_test_key are answered before the rate limiter runs, so they never consume live quota.
💬 SMS API
| Plan | Per Minute | Per Day | Per Month |
|---|---|---|---|
| free | 5 | 50 | 50 |
| starter | 50 | 300 | 300 |
| pro | 200 | 1,500 | 1,500 |
| business | 500 | 6,000 | 6,000 |
| enterprise | 5,000 | 100,000 | 1,000,000 |
📧 Email API
| Plan | Per Minute | Per Day | Per Month |
|---|---|---|---|
| free | 10 | 500 | 500 |
| starter | 100 | 2,000 | 2,000 |
| pro | 500 | 10,000 | 10,000 |
| business | 1,000 | 40,000 | 40,000 |
| enterprise | 10,000 | 500,000 | 10,000,000 |
📶 Data Bundles API
| Plan | Per Minute | Per Day | Per Month |
|---|---|---|---|
| free | 2 | 50 | 50 |
| starter | 20 | 300 | 300 |
| pro | 100 | 1,500 | 1,500 |
| business | 200 | 6,000 | 6,000 |
| enterprise | 2,000 | 50,000 | 500,000 |
📱 Airtime API
| Plan | Per Minute | Per Day | Per Month |
|---|---|---|---|
| free | 2 | 50 | 50 |
| starter | 20 | 300 | 300 |
| pro | 100 | 1,500 | 1,500 |
| business | 200 | 6,000 | 6,000 |
| enterprise | 2,000 | 50,000 | 500,000 |
Idempotency
Idempotency keys prevent duplicate requests from being processed multiple times. This is critical for payment-related operations like SMS, data purchases, and airtime top-ups.
Prevent Double Charges
Same purchase isn't processed twice
No Duplicate Messages
Same SMS/email isn't sent multiple times
Safe Retries
Network retries don't cause issues
Usage
Include an idempotency_key in your request body:
curl -X POST https://api.sendcomms.com/api/v1/sms/send \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+233540800994",
"message": "Your OTP is 123456",
"idempotency_key": "order-12345-otp-sms"
}'Cached Response
When a duplicate request is detected, we return the cached response with an indicator:
{
"success": true,
"data": {
"transaction_id": "sms_mjhw8xkw_6f97ab63ff91",
"message_id": "SMf9c2ebdffd58b516f6895b02051c4b21",
"status": "sent",
"to": "+233540800994"
},
"_idempotent": {
"replayed": true,
"message": "Duplicate request - returning cached response"
}
}How It Works
- Idempotency keys are cached for 24 hours
- Keys are scoped per customer and per service
- Use UUIDs or unique order IDs as keys
- Responses include
X-Idempotent-Replay: trueheader
Supported Endpoints
| Endpoint | Idempotency |
|---|---|
| POST /api/v1/sms/send | Supported |
| POST /api/v1/email/send | Supported |
| POST /api/v1/data/purchase | Supported |
