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 stableSCREAMING_SNAKE_CASEerror 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.
message. Match on the code and the HTTP status.Status-code catalog
| HTTP | Typical code values | Meaning |
|---|---|---|
| 400 | BAD_REQUEST, SCHEMA_VALIDATION_ERROR, INVALID_JSON | Malformed request or failed Zod validation. The details object names the offending field. |
| 401 | UNAUTHORIZED | Missing or invalid credentials. See Authentication. |
| 403 | FORBIDDEN | Authenticated but not permitted — e.g. a workspaceId you have no membership on, or an owner/admin-only action. |
| 404 | NOT_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_READONLY | Conflict — a uniqueness violation or an edit to a read-only resource. |
| 422 | domain validation codes | Semantically invalid even though well-formed (e.g. an unprocessable state transition). |
| 429 | rate-limit | Too many requests — AI endpoints are capped at 20/min per workspace. Back off and retry. |
| 500 | INTERNAL_SERVER_ERROR | Unexpected 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.