Errors
Every failed request returns the standard error envelope:
{
"success": false,
"error": {
"code": "STRING_CODE",
"message": "Human-readable description"
}
}
Error codes
| Code | HTTP status | When it happens | How to handle it |
|---|---|---|---|
VALIDATION_ERROR | 422 | The request body failed schema validation (missing or malformed fields). A message, continue, or escalation request without sessionId also returns 422 — create the session first with POST /agent/session. | Fix the request — check the field table on the endpoint you called. Not retryable as-is. |
NOT_FOUND | 404 | The session, action, escalation, or project referenced doesn't exist, doesn't belong to your project, or isn't the conversation your session token was issued for. | Fatal for that id — don't retry with the same id. See the note on 404 vs. 403 below. |
ESCALATION_RESOLVED | 409 | You tried to send a message into an escalation that's already resolved. | Fatal for that escalation — start a new one with POST /agent/escalation if the user needs help again. |
RECOVER_PENDING_FAILED | 500 | Internal error fetching pending actions on GET /agent/session/:sessionId/pending-actions. | Transient — safe to retry with backoff. |
UNSUPPORTED_MODEL | 422 | The project's configured AI model isn't supported for this operation. Can occur on /agent/message, /agent/message/stream, and /agent/continue. | Not retryable — check your project's model configuration in the dashboard. |
AI_RELAY_ERROR | 502 | The upstream AI call failed. | Transient — safe to retry. |
Generic HTTP semantics
- 401 — a credential was rejected: a missing, malformed, invalid, expired, or wrong-scope API key; a missing or invalid
X-Appilots-Session-Token; or an invalid or expiredX-Appilots-User-Token. See Authentication. - 403 — the
userIdin the request body doesn't match the verified end-user token. AlsoWORKSPACE_INACTIVEwhen the workspace has been deactivated. - 404 instead of 403 for other people's ids — the API deliberately returns
404 NOT_FOUNDrather than403 Forbiddenwhen a request references an id that exists but belongs to a different project or conversation. This is intentional: it avoids confirming to a caller that an id exists at all outside their own scope.
Retry guidance
| Situation | Retry? |
|---|---|
AI_RELAY_ERROR, RECOVER_PENDING_FAILED, or a network-level failure | Yes, with backoff. |
VALIDATION_ERROR, UNSUPPORTED_MODEL, NOT_FOUND, ESCALATION_RESOLVED | No — fix the request or the referenced id first. |
401 | No — fix the rejected credential first. For an expired end-user token, fetch a fresh one from your backend and retry. |
403 | No — send the userId from the end-user token, or omit it. |
Connection error on POST /agent/message/stream before any SSE event arrives | Yes — retry via the non-streaming POST /agent/message (see Messages & streaming). |
Related pages
- Authentication — 401 details
- Messages & streaming —
VALIDATION_ERROR,UNSUPPORTED_MODEL,AI_RELAY_ERROR,NOT_FOUNDin context - Escalations —
ESCALATION_RESOLVEDandNOT_FOUNDin context