Rate limits
Request caps enforced by the Billium API and how to handle them.
Billium enforces two layers of rate limiting. They are additive — a request must pass both to be served.
| Scope | Limit | Window | Keyed on |
|---|---|---|---|
| Global (per IP) | 50 requests | 60 seconds | Client IP address |
| Per API key | 300 requests | 60 seconds | First 16 characters of your API key |
The per-key limit is what matters for most production workloads — the global IP limit is a cheap first line of defence against abuse from a single source.
What happens when you're throttled
The API returns 429 Too Many Requests:
{
"statusCode": 429,
"message": "ThrottlerException: Too Many Requests",
"error": "Too Many Requests"
}A Retry-After header tells you how many seconds to wait before retrying.
Handling 429s
With the Node SDK (recommended). @billium/node retries 429 automatically with exponential backoff, honoring Retry-After. You do not need to write any retry logic for transient throttling.
Manually. Read Retry-After, sleep, and retry. Use jittered exponential backoff to avoid synchronising a retry storm across your fleet.
async function withBackoff<T>(fn: () => Promise<T>, attempts = 4): Promise<T> {
for (let i = 0; i < attempts; i++) {
try {
return await fn();
} catch (err) {
if (err instanceof BilliumApiError && err.status === 429 && i < attempts - 1) {
const delay = Math.floor(Math.random() * Math.min(500 * 2 ** i, 30_000));
await new Promise((r) => setTimeout(r, delay));
continue;
}
throw err;
}
}
throw new Error('unreachable');
}Avoiding the limit in the first place
- Batch reads. Fetch a page of 100 invoices with
limit=100instead of 100 single-item calls. - Cache lookups. Static data (e.g. a product's metadata) doesn't need to be re-fetched per request.
- Use webhooks instead of polling. If you're hitting
GET /invoices/{id}in a loop waiting forstatus === 'PAID', switch to handling theinvoice.paidwebhook — that's what webhooks are for. - Use one key per integration. Splitting load across multiple keys gives each integration its own 300 req/min budget.
Need a higher limit?
The limits above are the defaults. If your production workload genuinely needs more headroom, email hello@billium.to with your merchant ID and a description of the traffic pattern.