Core concepts

Rate limits

Per-key limits, the headers that report them, and how to back off.

Limits are counted per API key in a fixed window. They are generous enough that a well-behaved integration never sees one, and low enough that a runaway loop cannot take the service down for everyone else.

Every key gets 600 requests per 15-minute window, counted per key rather than per account — two integrations on one account do not spend each other's allowance, and one running hot does not throttle the other. | Enterprise | Agreed per contract | Agreed per contract |

Headers

Every response carries the current state of your window, whether or not you are near it.

HTTP
HTTP/1.1 200 OK
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 597
X-RateLimit-Reset: 1786100460

These come back on every response, not only on a 429 — you cannot pace against a budget you are only told about once you have already overrun it.

When the window is spent the API returns 429 with Retry-After in seconds.

A 503 means the limiter itself is down

If rate limiting is unavailable, this API answers 503 with Retry-After: 5 rather than letting the request through. An unmetered public endpoint is worse than a brief outage, and your client is a program that can wait five seconds.

GET/v1/meetings
Response 429
{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Too many requests. Retry in 12 seconds."
  }
}

Backing off

Read Retry-After and wait exactly that long. Retrying sooner counts against the next window and pushes the recovery further out.

TypeScript
async function call(url: string, attempt = 0): Promise<Response> {
  const response = await fetch(url, { headers });
  if (response.status !== 429 || attempt >= 5) return response;

  const wait = Number(response.headers.get("Retry-After") ?? 1);
  const jitter = Math.random() * 250;

  await new Promise((resolve) => setTimeout(resolve, wait * 1000 + jitter));
  return call(url, attempt + 1);
}

Stop polling

Most 429s come from polling for a meeting that is still processing. A webhook tells you the moment it is ready, and costs no requests at all.