Skip to content
API referenceRate limits

Rate limits

Each key spends from one window of 60 units a minute. Every server shares it, and so does every way in: REST and the console’s playground.

What a request costs

1 unit
Every request but the heavy reads below, whatever its answer.
5 units
A read that works through a lot of the restaurant’s records, such as a report over a year of days.

A HEAD costs what its GET does, since it runs it. A replayed write counts, and so does a refusal once the key is known.

Where you stand

Every answer to a known key carries three headers. A 401 carries none: the key is not known, so there is no window to report.

RateLimit-LimitThe key's units a minute: 60.
RateLimit-RemainingUnits left in this minute's window, after this request.
RateLimit-ResetSeconds until the window starts again.

Past the window, the answer is 429 rate_limited with Retry-After in seconds. Pace against RateLimit-Remaining rather than a guess.

Unknown keys

  • From one network, at most 30 requests every 60 seconds may carry a key that is well-formed but unknown, revoked or expired; past that, such a request is 429 rate_limited instead of 401. A network is an IPv4 address, or an IPv6 address’s /64.
  • A missing or malformed key is refused at once and counts toward nothing. A valid key is never refused by this limit.

Backing off

Wait Retry-After seconds and send the same request again; for a write, with the same Idempotency-Key (see Idempotency). A key that is not valid will not start working by waiting.

JavaScript
async function call(url, init) {
  for (;;) {
    const response = await fetch(url, init);
    if (response.status !== 429) return response;
    // Wait as long as the API says; keep the same Idempotency-Key for a write.
    const seconds = Number(response.headers.get("retry-after") ?? "1");
    await new Promise((resolve) => setTimeout(resolve, seconds * 1000));
  }
}