Error Handling
The REPLR API uses conventional HTTP status codes and returns consistent JSON error objects so you can programmatically detect and recover from failures.
Error Response Format
All errors return a consistent JSON structure. HTTP status codes are always meaningful -- a 4xx indicates a client error and a 5xx indicates a server-side issue.
{
"error": "error_code",
"message": "Human-readable description",
"details": {},
"request_id": "req_abc123"
}| Field | Type | Description |
|---|---|---|
error | string | Machine-readable error code (e.g. bad_request, unauthorized). |
message | string | Human-readable description of what went wrong. |
details | object | Additional context. Present for validation_error and some other codes. |
request_id | string | Unique identifier for the request. Include this when contacting support. |
Error Codes
Every error response includes one of the following error codes. Use the code (not the message) for programmatic error handling.
| HTTP Status | Error Code | Description |
|---|---|---|
400 | bad_request | Invalid request body or parameters. |
400 | validation_error | Field validation failed (details includes field-level errors). |
401 | unauthorized | Missing or invalid authentication. |
401 | token_expired | Access token has expired. |
403 | forbidden | Insufficient permissions or scope. |
403 | plan_limit | Feature not available on current plan. |
404 | not_found | Resource does not exist. |
409 | conflict | Resource already exists (e.g., duplicate email). |
413 | payload_too_large | Request body exceeds size limit. |
422 | unprocessable_entity | Request understood but cannot be processed. |
429 | rate_limit_exceeded | Too many requests. |
500 | internal_error | Server error. |
502 | upstream_error | AI provider temporarily unavailable. |
503 | service_unavailable | Service under maintenance. |
Validation Errors
When the error code is validation_error, the details object contains a fields map with per-field error messages. Use this to display inline form errors or build targeted retry logic.
{
"error": "validation_error",
"message": "Validation failed",
"details": {
"fields": {
"email": "Must be a valid email address",
"password": "Must be at least 8 characters"
}
}
}The fields object keys correspond to request body parameter names. Each value is a human-readable string describing the validation failure for that field. Multiple fields can fail simultaneously.
Handling Errors
Always check the HTTP status code before parsing the response body. For transient errors (429, 502, 503), implement retry logic with exponential backoff. For client errors (400-422), fix the request before retrying.
async function replrFetch(url, options = {}) {
const res = await fetch(url, {
...options,
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
...options.headers,
},
});
if (!res.ok) {
const error = await res.json();
switch (error.error) {
case "token_expired":
// Refresh the token and retry
await refreshToken();
return replrFetch(url, options);
case "rate_limit_exceeded":
// Wait and retry with backoff
const retryAfter = res.headers.get("Retry-After") || 5;
await new Promise((r) => setTimeout(r, retryAfter * 1000));
return replrFetch(url, options);
case "validation_error":
// Surface field-level errors to the UI
console.error("Validation errors:", error.details.fields);
throw new ValidationError(error.details.fields);
default:
throw new Error(`[${error.error}] ${error.message} (request: ${error.request_id})`);
}
}
return res.json();
}Troubleshooting
Common errors and how to resolve them.
unauthorized- •Verify your API key or Bearer token is correct and not truncated.
- •Check that the Authorization header format is exactly: Bearer <token>.
- •Confirm the token has not been revoked in the dashboard.
rate_limit_exceeded- •Implement exponential backoff with jitter between retries.
- •Check the Retry-After header for the recommended wait time.
- •Review your plan's rate limits at /billing and upgrade if needed.
upstream_error- •Retry the request with exponential backoff (the AI provider may be temporarily down).
- •Check the REPLR status page for ongoing incidents.
- •If the error persists, try switching to a different model.
plan_limit- •Upgrade your plan at /billing to unlock the feature.
- •Review available features for each plan in the pricing page.
Request IDs
Every API response includes an X-Request-Id header with a unique identifier for that request. Error response bodies also include the ID in the request_id field.
Always log request IDs
When contacting support about a failed request, include the request_id. This allows the team to trace the exact request through the system and diagnose the issue faster.
const res = await fetch("https://api.replr.ai/v1/replrs", {
headers: { Authorization: `Bearer ${API_KEY}` },
});
// Always available, even on success
const requestId = res.headers.get("X-Request-Id");
console.log("Request ID:", requestId);
if (!res.ok) {
const error = await res.json();
// Also available in the error body
console.error("Error request ID:", error.request_id);
}