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:

HeaderMeaning
x-ratelimit-limitThe maximum number of requests allowed in the window.
x-ratelimit-remainingRequests left in the current window.
x-ratelimit-resetWhen 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:

429 response
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):

client.ts
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, respect retry-after if 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-remaining to 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.