Errors
Every error code with its HTTP status, which ones you can actually hit on v1, and the dashboard-only codes that never appear there.
Errors use the standard envelope — see Response envelope. Branch on error.code, never on the message text.
Codes and statuses
| Code | HTTP | Meaning |
|---|---|---|
UNAUTHORIZED | 401 | Missing, malformed, revoked, or unknown API key |
FORBIDDEN | 403 | Authenticated, but not permitted — on v1, the access gate |
NOT_FOUND | 404 | No such resource in this workspace |
VALIDATION_ERROR | 422 | The request body or parameters were rejected |
RATE_LIMITED | 429 | Too many requests — see Rate limits |
USAGE_LIMIT_REACHED | 402 | Out of credits, over quota, or a spend cap was hit |
FILE_TOO_LARGE | 413 | Upload exceeds the plan's size limit |
UNSUPPORTED_FILE_TYPE | 415 | Not one of PDF, DOCX, TXT, MD, CSV |
SOURCE_PROCESSING_FAILED | 500 | A knowledge source failed to process |
CHATBOT_INACTIVE | 403 | The chatbot is not active |
DOMAIN_NOT_ALLOWED | 403 | The request's origin is not on the chatbot's allowlist |
AI_PROVIDER_ERROR | 502 | An upstream AI provider failed |
INTERNAL_ERROR | 500 | Something unexpected |
What you can hit on v1 today
v1 is three read-only GET endpoints, so in practice you will see:
UNAUTHORIZED— key problems.FORBIDDEN— the three-layer access gate. SeeRATE_LIMITED— one of the two 120-per-minute limits.INTERNAL_ERROR— rare, and worth reporting.
The upload, chatbot, and domain codes belong to other surfaces — the dashboard, the widget's public endpoints, and knowledge ingestion — and are listed here because one client library usually handles all of them.
Dashboard-session codes
These four exist in the same catalogue and never appear on `/api/v1`:
| Code | HTTP |
|---|---|
EMAIL_NOT_VERIFIED | 403 |
ACCOUNT_SUSPENDED | 403 |
TWO_FACTOR_REQUIRED | 403 |
ACCOUNT_DELETED | 403 |
They describe the state of a signed-in user session, and API keys have no user session. In particular, when a workspace owner is suspended or deleted, v1 does not return ACCOUNT_SUSPENDED — it returns the ordinary access-gate 403 with "API access is not enabled for this workspace.", identical to an entitlement gap, so a key holder cannot detect a moderation action.
Handling them
async function apiGet(path) {
const res = await fetch(`https://app.evoriqa.com/api/v1${path}`, {
headers: { Authorization: `Bearer ${process.env.EVORIQA_API_KEY}` },
});
const body = await res.json();
if (body.success) return body.data;
switch (body.error.code) {
case "RATE_LIMITED":
throw new RetryableError(body.error.message); // back off and retry
case "FORBIDDEN":
throw new Error("API access is off for this workspace — check the gate.");
default:
throw new Error(`${body.error.code}: ${body.error.message}`);
}
}Retry RATE_LIMITED with backoff and INTERNAL_ERROR sparingly. Do not retry UNAUTHORIZED or FORBIDDEN — nothing about them changes on a second attempt.
Where to go next
Last updated