Rate Limits
Limits are per endpoint, not one account-wide number, and they're keyed by client IP for unauthenticated calls or by user for authenticated ones.
Current limits
| Endpoint | Limit |
|---|---|
POST /api/v1/sms/send/ | 120 / minute |
POST /api/sms/send/ (dashboard) | 120 / minute |
POST /api/external/send/ | 120 / minute |
GET /api/v1/sms/received/ | 120 / minute |
GET /api/devices/<id>/tasks/ (gateway polling) | 60 / minute |
GET /api/v1/sms/<id>/ | Not currently rate-limited |
GET /api/v1/account/stats/ | Not currently rate-limited |
The two unthrottled read endpoints are still expected to be called sensibly — see the polling interval recommendation below rather than treating the absence of an enforced limit as an invitation to poll continuously.
When you exceed a limit
JSON
// 429 Too Many Requests
Retry-After: 14
{ "detail": "Request was throttled. Expected available in 14 seconds." }The Retry-After header is authoritative — it's the number of seconds until the request would succeed, computed server-side. Prefer it over a fixed guess.
Recommended retry behavior
- On
429, wait at least theRetry-Aftervalue before retrying — don't retry immediately in a loop. - For status polling against
GET /api/v1/sms/<id>/, poll no faster than every 15–20 seconds per message — that's the fastest a status could plausibly have changed, since it's gated by the same ~20-second device poll described in How Connecfy Works. Polling faster just adds load without new information. - For bulk sending, 120/minute on
v1/sms/send/is the practical ceiling per account regardless of how many SIMs you have — pace a large batch to that rate rather than firing it all at once and handling the resulting 429s. - For an inbound sync loop against
GET /api/v1/sms/received/, polling every 15–30 seconds is more than enough for near-real-time delivery and stays well under the limit even with a handful of parallel integrations sharing one key.
More on building this correctly: Building Reliable Integrations.