Errors & Rate Limits
The EscapeLife API uses standard HTTP status codes. All error responses include a machine-readable detail field.
Error response format
{
"detail": "API key not found",
"status_code": 401,
"request_id": "req_7gh92mp"
}Validation errors (422) include a full errors array:
{
"detail": [
{
"loc": ["body", "type"],
"msg": "Input should be one of: sop, rate_plan, menu, policy, faq, ...",
"type": "literal_error"
}
]
}HTTP status codes
400Bad Request
The request body or query params are invalid. Check the error detail for the specific field.
401Unauthorized
Missing or invalid API key. Check your Authorization header.
403Forbidden
Your API key does not have the required scope for this operation.
404Not Found
The requested resource does not exist or belongs to a different property.
409Conflict
A resource with this identifier already exists (e.g. duplicate property slug).
422Unprocessable Entity
The request is well-formed but contains semantic errors. See the errors array in the response body.
429Too Many Requests
Rate limit exceeded. Check the Retry-After header.
500Internal Server Error
Something went wrong on our end. Retry with exponential backoff.
503Service Unavailable
Temporary downtime. Check status.escapelife.ai.
Rate limits
All endpoints (default)1,000 req / min per API keyPOST /knowledge/ingest60 req / min per propertyPOST /ai/chat120 req / min per propertyPOST /ai/voice/session30 req / min per propertyWhen rate limited, the response includes a Retry-After header with the number of seconds to wait.
async function fetchWithRetry(url: string, options: RequestInit, retries = 3): Promise<Response> {
const res = await fetch(url, options);
if (res.status === 429 && retries > 0) {
const retryAfter = parseInt(res.headers.get("Retry-After") ?? "1", 10);
await new Promise((r) => setTimeout(r, retryAfter * 1000));
return fetchWithRetry(url, options, retries - 1);
}
return res;
}