Rate Limits
To protect system stability and ensure fair usage, the API enforces rate limits.
Rate Limit Tiers
The API implements two tiers of rate limiting:
Per-Token Limits
Each Bearer token is limited to 30 requests per minute. This ensures individual tokens cannot overwhelm the system.
Per-Account Limits
All tokens associated with your account share a combined limit of 60 requests per minute. This prevents excessive usage across multiple tokens.
Rate Limit Response
When you exceed a rate limit, the API returns a 429 Too Many Requests response with a Retry-After header indicating how many seconds to wait before retrying.
Example:
HTTP/1.1 429 Too Many Requests
Retry-After: 60
Content-Type: application/json
The response body includes additional information about which limit was exceeded:
{
"error": "Rate limit exceeded",
"limitType": "jti", // "jti" for per-token, "sub" for per-account
"limit": 30 // The limit that was exceeded
}
The limitType field indicates which limit you've hit:
"jti": Per-token limit exceeded"sub": Per-account limit exceeded
Handling Rate Limits
When you receive a 429 response:
- Check the
Retry-Afterheader - This tells you exactly how long to wait - Implement exponential backoff - If retrying multiple times
- Add jitter - Randomise retry delays slightly if making parallel requests
Example Implementation
async function fetchWithRetry(url, options, maxRetries = 5) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch(url, options);
if (response.status !== 429) {
return response;
}
// Parse retry delay from header
const retryAfter = response.headers.get('Retry-After');
let delaySeconds = retryAfter ? parseInt(retryAfter) : Math.pow(2, attempt);
// Add jitter (±10% randomisation)
const jitter = delaySeconds * 0.1 * (Math.random() * 2 - 1);
delaySeconds = Math.max(1, delaySeconds + jitter);
console.log(`Rate limited. Waiting ${delaySeconds} seconds before retry ${attempt + 1}/${maxRetries}`);
await new Promise(resolve => setTimeout(resolve, delaySeconds * 1000));
}
throw new Error(`Failed after ${maxRetries} retries`);
}
Need Higher Limits?
If you're routinely hitting rate limits, please contact Scoffable to discuss your requirements. We can help optimise your integration or adjust limits if needed.