DocsRate limits

Guide

Rate limits

Each API key may make 120 requests per minute. Every response tells you how many you have left, and a refused request tells you how long to wait.

The limit

The limit is per key, not per project. A minute starts with a key's first request and lasts 60 seconds; the count then starts again at zero. It is a fixed window, not a rolling one.

Note · Counted per server instance

The counters live in the memory of the server that handled the request, and start again if it restarts. Treat the headers as the truth for the response you are holding, not as a guarantee about the next one.

How requests are counted
Limit
120 requests per minute
Counted per
API key; two keys are counted separately
Window
Fixed: 60 seconds from a key's first request
Counts
Every request with a valid key, including ones that fail or are refused
Does not count
Requests without a valid key (401)
Kept
In one server instance's memory

Headers

Every response to a request with a valid key carries three headers.

HeaderValue
X-RateLimit-LimitThe limit: 120.
X-RateLimit-RemainingRequests left in the current window.
X-RateLimit-ResetSeconds until the window ends. A duration, not a timestamp.
Retry-AfterOnly on 429. The same number of seconds as X-RateLimit-Reset.
A normal responseCaptured
HTTP/1.1 200 OKX-RateLimit-Limit: 120X-RateLimit-Remaining: 119X-RateLimit-Reset: 60Content-Type: application/json; charset=utf-8

Handling 429

When a request is refused, wait the number of seconds in Retry-After and send it again. Nothing was done with the refused request, so repeating it is safe.

  • Add a little random delay if several workers share a key, so they do not all retry in the same instant.
  • Give up after a few attempts and report the failure, instead of looping forever.
  • Better still, stay under the limit: watch X-RateLimit-Remaining and slow down as it approaches zero. Waiting for webhooks instead of polling GET /v1/calls/:id removes most of the requests an integration makes.
Wait and retrycURL
#!/bin/sh# Repeats a request while the API answers 429, waiting as Retry-After says.attempt=0while :; do  status=$(curl -s -o response.json -D headers.txt -w "%{http_code}" \    "http://localhost:4000/v1/agents" \    -H "Authorization: Bearer $OXUMI_API_KEY")  [ "$status" != "429" ] && break
  attempt=$((attempt + 1))  [ "$attempt" -ge 5 ] && break
  wait=$(awk 'tolower($1) == "retry-after:" { print $2 + 0 }' headers.txt)  sleep "${wait:-1}"done
echo "$status"cat response.json
Over the limitCaptured
HTTP/1.1 429 Too Many RequestsX-RateLimit-Limit: 120X-RateLimit-Remaining: 0X-RateLimit-Reset: 16Retry-After: 16Content-Type: application/json; charset=utf-8
{"statusCode":429,"message":"Rate limit of 120 requests per minute exceeded."}