Rate Limits
Understand and handle CanalAPI rate limits.
CanalAPI applies rate limits to protect platform stability and to fairly allocate capacity. Limits are evaluated independently across several dimensions — breaching any one dimension returns 429.
Limit dimensions
| Dimension | Applies to | Notes |
|---|---|---|
| Per-key RPM / TPM / concurrency | Billed endpoints (/v1/chat/completions, /v1/messages, /v1/embeddings, …) | Configured under API Keys |
| Per-account RPM / TPM | All endpoints (summed across keys) | Tied to your plan tier |
| Per-model | Models with strict upstream throttling | Determined by the upstream |
| Per-IP on public endpoints | GET /v1/models, /api/public/*, /api/fx/latest | Default 60 req/min/IP |
| Per-IP on auth endpoints | Sign up / sign in / reset password | Anti-bruteforce |
Refer to the console for the actual numbers — they evolve with capacity and plans.
Response headers
Successful billed requests return standard rate-limit headers so clients can self-throttle:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Cap of the current window |
X-RateLimit-Remaining | Remaining in the current window |
X-RateLimit-Reset | Unix seconds at which the window resets |
Retry-After | (only on 429) Suggested wait, in seconds |
HTTP/1.1 200 OK
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 597
X-RateLimit-Reset: 1730000060Hitting a limit
When a limit is exceeded, CanalAPI returns:
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 5
{
"error": {
"message": "Rate limit exceeded.",
"type": "rate_limit_error",
"code": "rate_limit_exceeded"
}
}If the failure is due to a quota (subscription allowance or wallet balance exhausted), code is more specific:
insufficient_balance— wallet is empty; top up in Billing or activate a subscription.quota_exhausted— the per-key cap has been reached.
Recommended handling
- Honour
Retry-Afterwhen present. Sleep for at least that many seconds before the next attempt. - Otherwise use exponential backoff with jitter, e.g.
min(2^attempt, 30) * (0.75 + random() * 0.5)seconds. - Cap retries (commonly 5). Beyond that, surface the error to the caller.
- Watch for client-side bursts. Fan-out from a single user click should be throttled in the client.
- Self-throttle from
X-RateLimit-Remaining— slowing down preemptively is cheaper than backing off after429.
Capacity tips
- Use streaming for long completions to lower wall-clock per request, so retries cost less.
- Batch independent prompts where possible.
- For ingest-heavy workloads, prefer smaller, faster models when accuracy permits.
- Stagger large scheduled jobs to avoid hour-boundary bursts.
Quotas
Quotas and instantaneous rate limits are two different mechanisms:
- Rate limits (RPM / TPM) — short-window throughput protection; goal is to smooth traffic.
- Quotas — cumulative spend caps over longer periods; goal is to prevent runaway costs.
Configurable in the console:
- Per-key quota — total USD a single key may spend; pauses the key on breach.
- Subscription quota — period quota with a chosen overage policy (deny / allow within limit / fall back to pay-as-you-go). See Subscriptions.
- Alert thresholds — email when balance / quota crosses a threshold.
Use both so you can react before being cut off.