Rate limits
The /v1 API enforces two independent, fixed-window rate limits:
| Scope | Default | Env var |
|---|---|---|
| Per API key | 60 requests/min | OCTO_API_RATE_LIMIT_PER_MIN |
| Per workspace | 600 requests/min | OCTO_API_WS_RATE_LIMIT_PER_MIN |
Exceeding either limit returns:
| HTTP | type / code | When | SDK exception |
|---|---|---|---|
429 | rate_limit_error | Per-key or per-workspace rate limit exceeded | RateLimitError |
Pacing headers
Section titled “Pacing headers”Every response — success and 429 alike — carries the current budget so an
agent can pace itself proactively instead of only reacting to a 429:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Requests allowed in the window |
X-RateLimit-Remaining | Requests left in the current window (0 once exceeded) |
X-RateLimit-Reset | Unix time (seconds) when the window resets |
Retry-After | Seconds to wait before retrying (on 429 only) |
The headers report whichever of the two limits (per-key or per-workspace) you
are closest to hitting. Slow down as X-RateLimit-Remaining approaches 0.
Handling 429s
Section titled “Handling 429s”import timefrom openai import RateLimitError
try: resp = client.responses.create(model="claude-sonnet-4-6", input="...")except RateLimitError as e: retry_after = int(e.response.headers.get("retry-after", "1")) time.sleep(retry_after) # retryIf you’re consistently hitting the per-key limit, spread load across multiple keys minted for different automated clients (see Get an API key) rather than retrying in a tight loop — the per-workspace limit still applies across all of a workspace’s keys combined.
See Errors for the full error table.