Errors & Retry Guidance
Overview
The MultiRoute API uses standard HTTP status codes and returns structured JSON error responses. This page describes:
- The common error response format.
- Typical HTTP status codes you may encounter.
- How to implement retries and handle rate limiting.
Error response format
On non-2xx responses, the API returns a JSON body with at least an error object:
{
"error": {
"type": "invalid_request_error",
"message": "The `model` field is required.",
"code": "missing_model"
}
}
Fields:
error.type: A high-level category such as:"invalid_request_error""authentication_error""authorization_error""rate_limit_error""server_error"
error.message: Human-readable description, safe to log.error.code(optional): Machine-readable error code for programmatic handling.
Deployments may include additional fields (such as request_id or details) to help with debugging.
Common HTTP status codes
Below are typical status codes and how to handle them:
200–299: Success
The request succeeded. For streaming endpoints, you may see 200 OK with a streamed body.
400 Bad Request
The request is malformed or violates validation rules (for example, missing fields, invalid parameter types, or unsupported values).
- Action: Inspect
error.messageanderror.code, correct the request, and retry only after fixing the client.
401 Unauthorized
Authentication failed—usually because:
-
The
Authorizationheader is missing. -
The token or API key is invalid, expired, or revoked.
-
Action: Verify that you are sending the correct key or token, and that it has not been revoked. Do not blindly retry without fixing the credential.
403 Forbidden
The credential is valid but does not have permission to perform this action (for example, using an inference-only key for a config endpoint).
- Action: Use a credential with the appropriate scopes or roles. Do not automatically retry.
404 Not Found
The requested resource or endpoint does not exist.
- Action: Check the URL path, version prefix (
/v1), and HTTP method.
409 Conflict
A conflict occurred, such as attempting to create a resource that already exists or update a config with conflicting changes.
- Action: Read the error details, reconcile the state on your side, and retry if appropriate.
429 Too Many Requests
You have hit a rate limit or quota.
- Action:
- Implement exponential backoff (for example, wait 1s, then 2s, 4s, 8s, up to a max).
- Respect any
Retry-Afterheader if present. - Avoid tight loops that immediately retry on 429.
5xx Server errors
Server-side errors such as:
500 Internal Server Error502 Bad Gateway503 Service Unavailable504 Gateway Timeout
These usually indicate transient issues in MultiRoute or an upstream provider.
- Action: Implement idempotent retries with backoff for safe operations. Avoid retrying unsafe operations that cannot be repeated without side effects.
Retry strategy
For robust clients, MultiRoute recommends:
- Idempotent requests: Design calls (particularly reads and idempotent writes) so they can be safely retried.
- Exponential backoff: Increase delay between retries (for example, 1s, 2s, 4s, 8s) with a maximum backoff (for example, 30s).
- Jitter: Add randomness to retry delays to avoid thundering herds.
- Retry on:
- Network errors (connection reset, DNS issues, timeouts).
- HTTP 429, 500, 502, 503, 504 (subject to idempotency).
- Do not retry on:
- 400, 401, 403, 404, or other errors caused by invalid input or insufficient permissions.
Example: handling errors in Node
async function callWithRetries(fetchFn, maxRetries = 3) {
let attempt = 0;
while (true) {
try {
const res = await fetchFn();
if (res.ok) return res;
if (
res.status === 429 ||
(res.status >= 500 && res.status < 600)
) {
if (attempt >= maxRetries) return res;
const delayMs = Math.min(1000 * 2 ** attempt, 30000);
await new Promise((r) => setTimeout(r, delayMs));
attempt++;
continue;
}
return res; // Non-retryable status
} catch (err) {
if (attempt >= maxRetries) throw err;
const delayMs = Math.min(1000 * 2 ** attempt, 30000);
await new Promise((r) => setTimeout(r, delayMs));
attempt++;
}
}
}