v1 · preview

Try webhook signature, alert.created, location_withheld or 429.

↑ ↓ moveEnter openEsc close

How it works

Rate limits

Requests and query time per minute, what happens when you go over, the headers that count them and why webhooks beat polling in a loop.

On this page

Each client has two limits per minute. Both exist so that an integration that queries too much doesn’t take capacity away from anyone’s alerts, yours included.

The two limits

LimitDefault
Requests per minute600
Query time per minute30 seconds

The second is less usual. Each request spends the time it takes to resolve, so a long list counts for more than a single alert: asking for 500 alerts from a month uses more of that budget than asking for one by its id. If your integration often asks for large lists, paginate with lower limit values or, better, stop polling and use webhooks.

Both can be raised by contract.

The token endpoint (POST /v1/oauth/token) also has its own limit, per IP. Request a token once an hour and reuse it (see Renewing it).

Headers

Responses carry how much headroom you have left:

HeaderWhat it says
X-RateLimit-LimitYour limit.
X-RateLimit-RemainingWhat you have left in the current window.

When you go over

The API responds 429 in application/problem+json, with the Retry-After header: the seconds you have to wait before trying again.

async function request(url, options = {}, attempts = 3) {
  const res = await fetch(url, options);
  if (res.status === 429 && attempts > 0) {
    const wait = Number(res.headers.get('Retry-After') ?? 1);
    await new Promise((r) => setTimeout(r, wait * 1000));
    return request(url, options, attempts - 1);
  }
  return res;
}

Always respect Retry-After. Retrying earlier only lengthens the wait.

Webhooks instead of polling in a loop

The most common cause of a 429 is asking every few seconds “are there any new alerts?”. It’s what webhooks do best: every alert reaches you in a second or two, without using a single request.

  • To find out what’s happening: webhooks.
  • To catch up after an outage: GET /v1/events.
  • To load the state at start-up or look for something specific: the lists, paginated.