Rate limits
Each key carries two limits: a per-second burst limit and a monthly request cap.
The two limits
- Burst — 10 requests per second by default. Exceeding it returns
429 rate_limit_exceededwithRetry-After: 1. Steady traffic at the limit passes; a spike above it in a single second is rejected. - Monthly cap — set per key from your tier, counted per UTC calendar month and reset at the first moment of the next month.
Need more headroom? Tell us your expected volume and we will size the key to it.
Response headers
Every authenticated response carries your monthly budget so you can throttle proactively. All three are exposed to browsers via Access-Control-Expose-Headers.
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Your monthly request cap |
X-RateLimit-Remaining | Requests left in the current month |
X-RateLimit-Reset | Unix timestamp (seconds) when the monthly counter resets |
Retry-After | Seconds to wait before retrying — sent on 429 only |
X-Request-Id | Id for this call; quote it in support requests |
Checking your usage
GET /v1/_meta/usage reports the current billing period without you having to track headers.
bash
curl https://delilah-api.jsv21b.workers.dev/v1/_meta/usage \ -H "X-API-Key: dk_live_…"
json
{
"api_key_id": "…",
"org_name": "…",
"tier": "…",
"monthly_request_cap": 0,
"monthly_requests_used": 0,
"monthly_requests_remaining": 0,
"period_start": "2026-08-01T00:00:00.000Z",
"period_end": "2026-09-01T00:00:00.000Z"
}Handling 429
Pause for Retry-After seconds, then retry. Because the recommended sync pattern (see Pagination) polls the change feed rather than re-listing bills, most integrations stay far inside both limits.
http
HTTP/1.1 429 Too Many Requests
Retry-After: 1
Content-Type: application/json
{
"error": {
"code": "rate_limit_exceeded",
"message": "Burst limit 10/s exceeded.",
"request_id": "…",
"docs": "https://delilah-api.jsv21b.workers.dev/docs",
"limit": 10,
"window": "1s"
}
}A monthly-cap rejection uses the same code with a longer Retry-After and carries limit, used, and resets_at inside the error object.

