Errors
One error envelope, stable codes, human-readable messages.
Jelliu uses conventional HTTP status codes and returns every error in the same JSON envelope:
Messages are for people, codes are for code
Messages are written for the person reading them, and the language depends on the endpoint. Jelliu’s customers are Spanish-speaking, so many product-facing messages are in Spanish, while others are in English. Both of these are real responses:
Never parse or match message. It is not translated consistently and can be reworded without notice. Switch on error.code and the HTTP status.
HTTP status codes
For 5xx responses the real cause is logged on our side and never returned. The body carries a generic message: Internal server error, or An unexpected error occurred with code INTERNAL_ERROR.
Common error codes
The status shown is the usual one. A few codes are returned with a different status on specific endpoints (for example VALIDATION_FAILED with 409 or 422), so read the status and the code together.
Validation errors
Validation failures return 400 with code VALIDATION_FAILED and a details field. Depending on the endpoint, details takes one of two shapes.
Field map. Most create and update endpoints report errors grouped by field:
Issue list. Other endpoints return a flat list of issues, each with a dotted path:
Handle both: if details is an array, read path and message from each item; if it is an object, read fieldErrors.
No details. Some input problems are caught outside the endpoint’s own validation and come back as VALIDATION_FAILED with only a Spanish message:
These requests used to fail with 500 INTERNAL_ERROR. Fix the value and send the request again.
Size limits
A JSON or form body larger than 1 MB, or an uploaded file larger than the route’s limit (20 MB for knowledge documents, 10 MB for a web chat attachment), is refused with 413:
An oversized file gets El archivo es demasiado grande para esta operación. A few routes answer their own size errors instead: the CSV contact upload returns 400 VALIDATION_FAILED (Uploaded file is too large (max 10MB).), and a web chat attachment checked after upload returns the widget’s own 413 body. Do not retry a 413 unchanged: split the batch or shrink the file.
Metadata
metadata is included only for the four codes below, and only with keys from a fixed allowlist. Everything else stays server-side. The keys you will typically see:
No active subscription
A workspace whose subscription is not active, trialing or past_due is refused some features with 403 BILLING_ERROR, metadata.tier: "none" and metadata.kind: "subscription_required". Use kind to tell this apart from a plan that lacks a feature, and send the user to choose a plan. The message names the feature:
Retrying does not help until the workspace subscribes. Reading and exporting your own data is not affected. The list of refused operations is in Billing and usage.
Retrying
- Retry
429and503after the number of seconds in theRetry-Afterheader. 409 AGENT_PROVISIONINGalso carriesRetry-After.- Other
4xxerrors, including413, will fail again until the request, the key or the resource state changes. - For other
5xxerrors, retry with exponential backoff.

