Error Reference
HTTP status codes and error response bodies.
Error Format
All errors return a JSON body with an error object and a machine-actionable recovery hint:
{
"error": {
"message": "Human-readable description",
"type": "error_type",
"code": "error_code"
},
"recovery": {
"action": "register_provider",
"endpoint": "POST /v1/providers",
"method": "POST",
"body_template": { "provider": "anthropic", "api_key": "<your_api_key>" },
"docs_url": "https://brainstormrouter.com/llms-agent-playbook.txt#phase-2",
"message": "Provider requires your own API key (BYOK). Register via POST /v1/providers."
}
}
The recovery field is present on every error response. AI agents can follow the action and endpoint programmatically instead of parsing error messages.
Recovery headers are also set on the HTTP response:
| Header | Example |
|---|---|
X-BR-Recovery-Action | register_provider |
X-BR-Recovery-Endpoint | POST /v1/providers |
X-BR-Recovery-Docs | https://brainstormrouter.com/llms-agent-playbook.txt#phase-2 |
Recovery Actions
| Error Type | Recovery Action | Endpoint |
|---|---|---|
budget_exceeded | increase_budget | PATCH /v1/agent-limits |
model_unavailable | use_alternative_model | GET /v1/catalog/runnable |
byok_required | register_provider | POST /v1/providers |
rate_limit_error | retry_after | Same endpoint + wait_ms |
upstream_error | retry_with_fallback | Same endpoint |
kill_switch_active | check_status | GET /v1/killswitch/status |
guardrail_blocked | check_guardrails | GET /v1/guardrails/config |
server_error | retry_after | Same endpoint + wait_ms: 5000 |
auth_error | authenticate | POST /v1/register |
Status Codes
400 — Bad Request
Invalid request body, missing required fields, or malformed input.
{
"error": {
"message": "Missing required field: model",
"type": "invalid_request_error"
}
}
Common causes:
- Missing
modelormessagesin completions request - Invalid alias body format (must be flat
{ "alias": "provider/model" }, not nested) - Empty strings in alias keys or values
401 — Unauthorized
Missing, invalid, or expired API key.
{
"error": {
"message": "Invalid API key",
"type": "authentication_error"
}
}
Common causes:
- Missing
Authorizationheader - Key doesn't start with
br_live_orbr_test_ - Key has been revoked
- Key has expired (check
expires_at)
402 — Payment Required
Budget limit exceeded for the API key or agent.
{
"error": {
"message": "Budget limit exceeded",
"type": "budget_exceeded",
"code": "budget_exceeded"
}
}
Returned when:
- API key's
budget_limit_usdfor the currentbudget_periodis exhausted - Per-agent budget (
/v1/agent-limits) is exceeded
403 — Forbidden
API key lacks the required permission for this endpoint.
{
"error": {
"message": "Forbidden: requires config.write",
"type": "forbidden"
}
}
Each endpoint requires a specific RBAC permission. Common permission issues:
| Endpoint | Required Permission | Roles That Have It |
|---|---|---|
PUT /v1/aliases | config.write | admin, operator |
POST /v1/api-keys | config.write | admin, operator |
POST /v1/chat/completions | router.write | admin, developer, agent |
GET /v1/models | router.read | admin, developer, operator, agent |
429 — Too Many Requests
Rate limit exceeded.
{
"error": {
"message": "Rate limit exceeded (60 RPM). Retry after 1s.",
"type": "rate_limit_error",
"code": "rate_limit_exceeded"
}
}
Rate limits are set per API key (rate_limit_rpm). The Retry-After header indicates when to retry.
500 — Internal Server Error
Unexpected server error. If persistent, check the status page or contact support.
503 — Service Unavailable
The requested service is temporarily unavailable.
{
"error": {
"message": "Requires database",
"type": "service_unavailable"
}
}
Common causes:
- Database not configured (for config/alias endpoints)
- All providers for the requested model are circuit-broken
- OpenAPI spec not loaded (for
/openapi.json)
Provider-Specific Errors
When the upstream provider returns an error, BrainstormRouter forwards it with the original status code and wraps it:
{
"error": {
"message": "The model `gpt-5-turbo` does not exist",
"type": "provider_error",
"code": "model_not_found",
"provider": "openai"
}
}
If a fallback model is configured, BrainstormRouter automatically retries with the fallback before returning an error.