Guides · Rate limits

Rate limits

Two limits protect the API: a general per-key request rate, and your plan's monthly event quota on ingestion. Both return 429 with a Retry-After header telling you exactly how long to wait.

The two limits

LimitApplies toWhen you hit it
General API rate limitEvery endpoint. 100 requests per 15 minutes.429 with Retry-After and RateLimit-* headers.
Plan event quotaUsage ingestion (POST /usage-events and /usage-events/batch). Your plan's monthly event allotment.Single events: 429 with X-RateLimit-* + Retry-After. Batch: per-item rejections inside the 202 (see below).

Batch ingestion never returns a batch-level 429

When your plan's event quota is exhausted, POST /usage-events/batch still returns 202. The quota rejection surfaces per event, inside the response body, not as a top-level status. Always inspect each item's status in a batch response rather than trusting the 202 alone.

Response headers

A rate-limited response carries the state you need to back off precisely.

HeaderMeaning
Retry-AfterSeconds to wait before retrying. Always honor this first.
RateLimit-ResetSeconds until the general rate-limit window resets.
X-RateLimit-LimitYour plan's event quota for the current period.
X-RateLimit-RemainingEvents left in the current period.

The body is the standard error envelope:

JSON
{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Slow down and retry after the current window resets.",
    "correlationId": "OLIVE-DINOSAUR-1b2fE4",
    "details": { "retryable": true }
  }
}

Handling a 429

A 429 is retryable: true. Wait for the Retry-After interval, then retry; if it is absent, fall back to exponential backoff. Never retry in a tight loop, and never retry a 4xx that is not a 429. The SDKs implement this for you.

Reach for the SDK retry helper

The Error handling guide has a ready-made retry-with-backoff wrapper for Node.js and Python that honors Retry-After automatically.

Next steps