Errors
Error envelope shape, error codes, retry guidance, and rate-limit headers.
Most API errors use an error envelope with a machine code and a human message.
{
"error": {
"code": "NOT_FOUND",
"message": "Vault not found"
}
}Error Codes
| Code | HTTP status | Meaning | Retry guidance |
|---|---|---|---|
BAD_REQUEST | 400 | Invalid path, query, or body input | Fix the request before retrying |
UNAUTHORIZED | 401 | Authentication is missing or invalid | Add a valid bearer key or session |
FORBIDDEN | 403 | The supplied key or session is not allowed | Do not retry until access changes |
NOT_FOUND | 404 | Resource not found or feature disabled | Check the identifier or feature availability |
CONFLICT | 409 | Request conflicts with existing state | Refresh state before retrying |
VERSION_RETIRED | 410 | Basket version was retired | Follow the successor URL |
PAYLOAD_TOO_LARGE | 413 | Request body exceeds the API body limit | Send a smaller body |
RATE_LIMITED | 429 | Rate limit exceeded | Retry after the Retry-After value |
SERVICE_UNAVAILABLE | 503 | Fail-safe, graph materialization, Redis, or upstream data is unavailable | Retry after the Retry-After value when present |
INTERNAL_ERROR | 500 | Unexpected server error | Retry with backoff and include request context if reporting |
VERSION_RETIRED is emitted by immutable basket version routes. This retired-version response is a legacy exception that includes the field success set to false alongside the error object. Parse error.code and use the successor pointer plus the Link header with rel="successor-version".
{
"success": false,
"error": {
"code": "VERSION_RETIRED",
"message": "Basket version 42 for \"rwa-tbill-conservative\" was retired. Use the latest version at /v1/baskets/rwa-tbill-conservative.",
"retired_at": "2026-07-01T00:00:00Z",
"successor_url": "https://api.philidor.io/v1/baskets/rwa-tbill-conservative"
}
}Rate Limit Headers
Responses include rate-limit headers when rate limiting is applied.
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Requests allowed in the active window |
X-RateLimit-Remaining | Requests remaining in the active window |
X-RateLimit-Reset | Unix timestamp for reset |
X-RateLimit-Window | Window length such as 60s |
Retry-After | Seconds to wait before retrying |
Anonymous public reads use IP-based limits. API-key requests use the key's configured per-minute limit on public routes.
Retry Pattern
Handle 429 and 503 first. If Retry-After is present, wait that many seconds before retrying.
Use exponential backoff for 500 responses. Do not retry 400, 401, 403, or 404 without changing the request or credentials.