Rate Limits
The Mojeeb Public API is rate-limited per API key. The default is 60 requests per minute per key, with a fixed-window counter that resets every 60 seconds.
What is the default limit?
60 requests per minute per API key. Each key has its own counter — multiple keys in the same organization don't share budget. A request rejected by the rate limiter never reaches the send pipeline, never charges quota, and never creates a conversation.
Can I get a higher limit?
Yes. Per-key overrides are configurable from the dashboard's API Keys page. If you need a higher default for a high-volume integration, contact support with your expected peak rate and use case.
What happens when I hit the limit?
The API responds with 429 Too Many Requests, the standard error envelope, and full rate-limit headers:
HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1730212354
Content-Type: application/json
{
"error": {
"type": "rate_limit_error",
"code": "rate_limit_exceeded",
"message": "Too many requests. Try again in 60 seconds.",
"correlation_id": "req_01HQZ..."
}
}
| Header | Meaning |
|---|---|
Retry-After | Seconds to wait before the next request |
X-RateLimit-Limit | The configured per-minute limit on this key |
X-RateLimit-Remaining | Requests left in the current window — 0 on rejection |
X-RateLimit-Reset | Unix timestamp at which the window resets |
How should I handle 429 responses?
Honor Retry-After. Sleep for at least that many seconds, then retry the same request. Aggressively retrying without backing off will keep you throttled.
A solid retry loop:
- Send the request
- If
429, parseRetry-After - Sleep for
Retry-Afterseconds (plus a small jitter, e.g. random 0–2s, to avoid thundering-herd retries from many clients) - Retry — pair the retry with the original
Idempotency-Keyif you used one, so the eventual success doesn't double-send
For sustained traffic, smooth your send rate to stay under the limit instead of bursting and backing off — predictable rate beats reactive throttling.
Are there per-success-response headers?
Currently, no. X-RateLimit-* headers are emitted reliably on 429 rejections only. Per-2xx response counter headers are a documented gap in v1 and will land in a follow-up. Until then, rely on 429 + Retry-After for backoff signals.
Common questions
Does the limit apply to status lookups?
Yes — the limit is per key across all /v1/ endpoints, including GET /v1/whatsapp/messages/{id}. If you poll status frequently for many messages, factor that into your budget or batch your polling.
What happens if my organization has multiple API keys?
Each key has its own independent budget. A 60/min limit on Key A doesn't reduce Key B's available requests. This makes it easy to give different integrations independent budgets — a marketing automation key can be exhausted without affecting a transactional notification key.
Is there an organization-wide ceiling?
Not in v1. A customer with 10 keys at 60/min each can theoretically do 600/min organization-wide. We may add an org-level ceiling in a future release if needed; you'll be notified before any change.
What if I use the same key from multiple servers?
The limit is per key, not per server. Multiple servers sharing one key share the budget. For independent budgets across servers, issue separate keys.
Does Meta's WhatsApp rate limit interact with this?
Yes — Mojeeb's per-key limit is separate from Meta's per-business-number rate limit. A send accepted by Mojeeb (under the per-key budget) can still be throttled or rejected by Meta downstream. Meta-side throttling appears as a delivery failure on GET /v1/whatsapp/messages/{id}, not as a 429 from us.