Rate limits
The provider can answer with HTTP 429 when account or channel limits kick in. The dashboard key API does not set RPM, TPM, concurrency or a budget for a key. Below: what the key settings lack, and how to handle 429 in a client.
Per-key quota settings
The key API does not publish numeric default quotas and does not offer these settings:
| Metric | Key API support |
|---|---|
| Requests per minute | Not exposed by the key API |
| Tokens per minute | Not exposed by the key API |
| Concurrent requests | Not exposed by the key API |
Per-key configuration
A key can have a name, a Premium or Cheap channel, a Premium fallback for Cheap and an expiry date, and its usage appears in the statistics. RPM/TPM, concurrency, budgets, model lists, IP filters and IDE restrictions cannot be set through the dashboard key API.
Supported settings:
- Name and Premium or Cheap channel
- Optional Premium fallback for a Cheap key
- Optional future expiry
Rate limit headers
If the provider sends these headers, rely on them when retrying. The key API does not guarantee that they are present:
| Header | Description |
|---|---|
X-RateLimit-Limit | Most requests allowed in the current window |
X-RateLimit-Remaining | Requests remaining in the current window |
X-RateLimit-Reset | Time when the rate limit window resets (Unix timestamp) |
Handling 429 errors
When the limit is reached, the API answers with HTTP 429. Retry with an exponentially growing delay:
import time
import requests
def request_with_backoff(url, headers, data, max_retries=5):
for attempt in range(max_retries):
response = requests.post(url, headers=headers, json=data)
if response.status_code == 429:
wait = 2 ** attempt # 1, 2, 4, 8, 16 seconds
print(f"Rate limited. Retrying in {wait}s...")
time.sleep(wait)
continue
return response
raise Exception("Max retries exceeded")async function requestWithBackoff(
url: string, options: RequestInit, maxRetries = 5
) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const res = await fetch(url, options);
if (res.status === 429) {
const wait = 2 ** attempt * 1000;
console.log(`Rate limited. Retrying in ${wait}ms...`);
await new Promise(r => setTimeout(r, wait));
continue;
}
return res;
}
throw new Error("Max retries exceeded");
}Best practices
- If the headers are there, check X-RateLimit-Remaining and Retry-After before retrying.
- Named keys help you account for workloads separately, but they do not create separate quotas.
- Retry with exponential backoff plus jitter.
- Cap automated workloads on the client side and watch customer cost. Key budgets cannot be set through this API.