Rate limits and retries
Every API key is rate-limited independently. When a key sends requests faster than its allowance, the API returns 429 Too Many Requests with the rate_limited error code instead of processing the call.
Limit headers
Successful and rate-limited responses both carry the current window state, so you can pace yourself before you ever hit a 429:
| Header | Meaning |
|---|---|
x-ratelimit-limit | The maximum number of requests allowed in the window. |
x-ratelimit-remaining | Requests left in the current window. |
x-ratelimit-reset | When the window resets (and the count returns to the limit). |
Limits are configured per key — each key has a per-minute allowance (default 120, configurable per key up to 10,000). Read the headers rather than hard-coding a number; the value you see is the live limit for the key making the call.
The 429 response
A rate-limited request returns the standard error envelope with the rate_limited code, plus the limit headers above. When a retry-after header is present, wait at least that many seconds before retrying:
HTTP/1.1 429 Too Many Requests
x-ratelimit-limit: 120
x-ratelimit-remaining: 0
x-ratelimit-reset: 1718530800
retry-after: 7
{
"ok": false,
"error": {
"code": "rate_limited",
"message": "The workspace or key exceeded a rate limit."
},
"request_id": "req_abc123"
}The SDK retries for you
The SDK automatically retries 429 and 5xx responses with exponential backoff and jitter, honouring the retry-after header when present. It retries twice by default; tune it with maxRetries (set 0 to disable):
const bt = new Blueticked({
apiKey: process.env.BLUETICKED_API_KEY!,
maxRetries: 4, // default is 2; set 0 to handle retries yourself
});If retries are exhausted, the SDK throws a typed BluetickedError with code: "rate_limited" and status: 429 — see Error codes.
Backoff guidance (raw HTTP)
- On a
429, respectretry-afterif present; otherwise back off exponentially (for example 0.3s, 0.6s, 1.2s) with a little random jitter to avoid thundering-herd retries. - Use
x-ratelimit-remainingto slow down before you are blocked — pause when it approaches zero rather than sending until you are rejected. - Spread bulk work over time. For large fan-outs, prefer a campaign — it queues and paces sends server-side instead of you looping over
messages.send. - Cap total retries so a persistently throttled caller fails loudly rather than retrying forever.