Rate limits and errors
The Bonfire REST API protects every community with rate limits and returns predictable error codes. Understanding both lets your integration degrade gracefully instead of failing loudly.
How rate limiting works
Limits are applied per API key. Each response includes headers describing your current budget:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Requests allowed in the current window |
X-RateLimit-Remaining | Requests left in the window |
X-RateLimit-Reset | Unix timestamp when the window resets |
When you exceed the limit, the API responds with 429 Too Many Requests and a Retry-After header (seconds to wait). The right behavior is to back off and retry, not to hammer the endpoint.
async function callWithBackoff(fn, attempt = 0) {
const res = await fn();
if (res.status === 429 && attempt < 5) {
const wait = Number(res.headers.get("Retry-After") || 1);
await new Promise((r) => setTimeout(r, wait * 1000));
return callWithBackoff(fn, attempt + 1);
}
return res;
}
Error model
Errors use standard HTTP status codes with a consistent JSON body:
{
"error": {
"code": "forbidden",
"message": "Key is missing the content:write scope."
}
}
| Status | Meaning | Typical fix |
|---|---|---|
400 | Malformed request | Check body and parameters |
401 | Missing/invalid key | Verify the Bearer token |
403 | Insufficient scope | Grant the required scope |
404 | Resource not found | Check IDs and base URL |
409 | Conflict | Resource already exists / state clash |
422 | Validation failed | Fix the field errors returned |
429 | Rate limited | Honor Retry-After |
5xx | Server error | Retry with backoff; transient |
Why it matters
Treating 429 and 5xx as retryable, and 4xx (except 429) as terminal, keeps your integration resilient. Always read the error.code rather than parsing the human message, which may change.
Related
- Authenticate with the Bonfire API
- API Design Principles
- Webhooks
FAQ
Are limits per key or per community? Per key, so independent integrations don't starve each other.
Should I retry a 403?
No — fix the key's scope first. Retrying won't help.
Do webhooks count against my rate limit? No. Webhooks are pushed to you and are independent of your API request budget.
Are 5xx errors safe to retry?
Yes, with backoff. Use idempotent design so retries don't duplicate writes.