Errors

The Well API error envelope and the status-code catalog returned by every operation.

Errors use a single, consistent envelope and standard HTTP status codes. Document them once here; each operation page lists the status codes it can return.

Error envelope

Every error response is a JSON object with a stable machine-readable code, the HTTP status, a short title, a human-readable message, and a meta block carrying a trace_id for support.

{
  "code": "SCHEMA_VALIDATION_ERROR",
  "status": 400,
  "title": "Validation Error",
  "message": "data.attributes.title is required",
  "details": { "path": "data.attributes.title", "issue": "required" },
  "meta": { "trace_id": "a1b2c3", "log_id": "a1b2c3" }
}
  • code — a stable SCREAMING_SNAKE_CASE error code. Branch on this, not on the message.
  • status — the HTTP status code, mirrored in the body.
  • title — a short, stable human-readable title.
  • message — a human-readable message; may change without notice.
  • details — optional field-level context (returned in development).
  • meta.trace_id — correlate with support; include it when reporting an issue.
Do not parse message. Match on the code and the HTTP status.

Status-code catalog

HTTPTypical code valuesMeaning
400BAD_REQUEST, SCHEMA_VALIDATION_ERROR, INVALID_JSONMalformed request or failed Zod validation. The details object names the offending field.
401UNAUTHORIZEDMissing or invalid credentials. See Authentication.
403FORBIDDENAuthenticated but not permitted — e.g. a workspaceId you have no membership on, or an owner/admin-only action.
404NOT_FOUND, <RESOURCE>_NOT_FOUND (e.g. COMPANY_NOT_FOUND, DOCUMENT_NOT_FOUND, WEBHOOK_NOT_FOUND)The resource does not exist, or is outside your workspace scope (the two are indistinguishable by design).
409<RESOURCE>_ALREADY_EXISTS (e.g. EMAIL_ALREADY_EXISTS, PROVIDER_ALREADY_EXISTS), DEFAULT_VIEW_READONLYConflict — a uniqueness violation or an edit to a read-only resource.
422domain validation codesSemantically invalid even though well-formed (e.g. an unprocessable state transition).
429rate-limitToo many requests — AI endpoints are capped at 20/min per workspace. Back off and retry.
500INTERNAL_SERVER_ERRORUnexpected server error. Safe to retry idempotent reads; report persistent failures.

Validation errors (400)

Request bodies are validated against a Zod schema before any work happens. A failure returns 400 with SCHEMA_VALIDATION_ERROR and a details object pointing at the field — fix the body and retry; the request had no side effects.

Not-found vs forbidden

A resource outside your workspace scope returns 404, not 403 — the API does not reveal the existence of rows you cannot access. A 403 means the operation is denied (e.g. group ownership), not that a specific row is hidden.