POST /api/public/v1/chats/{chatId}/messages) is rate-limited on a fixed time window. On the public API, the bucket is your API key’s own id — not your account — so two keys belonging to the same user throttle independently, and one key can’t exhaust the other’s budget. When you exceed the limit, the API returns 429 RATE_LIMITED immediately without consuming provider quota or credits.
How it works
The limit is enforced before any provider call. A rate-limited request never reaches the LLM, never triggers a tool call, and never reserves or spends credits. This protects shared provider budgets from accidental or runaway client loops. Every send response — success or429 — carries these headers:
If you are rate limited, the response body follows the standard error envelope:
Upstream limits
The underlying LLM route (OpenRouter free tier) has its own daily and per-minute caps. These are separate from the application-level rate limit and may also produce errors. If you see a provider-level rejection after passing the application gate, treat it as an upstream quota issue and retry later.Best practices
- Implement exponential backoff with jitter when you receive a
429. - Surface the error to the user with a friendly message instead of silently retrying.
- Do not auto-retry immediately; the window is fixed and short retries are unlikely to succeed.