> ## Documentation Index
> Fetch the complete documentation index at: https://docs.1to1ai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> How the API signals errors and how to handle them.

The API follows a **pure REST** contract: the HTTP status code is the success
or error signal.

## Response shape

<CodeGroup>
  ```json Success theme={null}
  { "message_uuid": "...", "wamid": "..." }
  ```

  ```json Error theme={null}
  {
    "code": "WINDOW_CLOSED",
    "message": "The 24-hour messaging window is closed. Send an approved template to reopen it."
  }
  ```
</CodeGroup>

A success returns the payload directly, with no envelope. An error always
returns `{ code, message }` — both fields are guaranteed.

<Tip>
  Switch on `code`: it is stable and part of the contract. The `message` is
  helpful human text and may be refined between API versions without notice.
  Messages are delivered in English (industry standard, same pattern as
  Stripe, GitHub or Linear). If you need to display them translated to the
  end user, map them in your client by `code`.
</Tip>

## Status families

| HTTP  | Meaning                                                                          | Retry?                        |
| ----- | -------------------------------------------------------------------------------- | ----------------------------- |
| `2xx` | Success — `200` read, `201` created, `202` accepted (async), `207` multi-status. | —                             |
| `4xx` | Request error — auth, validation, or missing resource.                           | No, fix it first.             |
| `429` | Rate limit exceeded.                                                             | Yes, after the `Retry-After`. |
| `5xx` | Server error.                                                                    | Yes, with backoff.            |

## Code catalog

<Note>
  The HTTP status of each code is **typical**: a specific endpoint may return a
  different status if context warrants it. The authoritative per-endpoint status
  lives in the **API Reference**. The table here is a general reference, not a
  binding per-endpoint contract.

  The conversation-resolution ambiguity codes (`PHONE_NUMBER_AMBIGUOUS`,
  `USERNAME_AMBIGUOUS`) can surface on **any** endpoint that accepts a
  `conversation` reference by `phone`/`username`, even if its API Reference lists
  other `409` codes.
</Note>

### Auth and tenant

| Code                      | HTTP | Description                                                                                        |
| ------------------------- | ---- | -------------------------------------------------------------------------------------------------- |
| `INVALID_API_TOKEN`       | 401  | The token does not exist or has been revoked. Generate a new one in Settings → API Token.          |
| `TOKEN_BUSINESS_MISMATCH` | 403  | The token does not belong to the business slug in the URL. Verify they refer to the same business. |

### Rate limit

| Code                  | HTTP | Description                                                                                                             |
| --------------------- | ---- | ----------------------------------------------------------------------------------------------------------------------- |
| `RATE_LIMIT_EXCEEDED` | 429  | You exceeded the 60 req/min bucket. Wait the seconds from the `Retry-After` header. See [Rate limits](/en/rate-limits). |

### Validation

| Code                   | HTTP | Description                                                                                             |
| ---------------------- | ---- | ------------------------------------------------------------------------------------------------------- |
| `INVALID_REQUEST`      | 400  | The body failed schema validation (missing field, wrong type, value out of range).                      |
| `INVALID_CURSOR`       | 400  | The pagination cursor is invalid or expired. Restart the listing without a cursor.                      |
| `BATCH_LIMIT_EXCEEDED` | 400  | The action group exceeds the maximum allowed in a single request. The `message` carries the actual cap. |

### Conversation, contact, and channel

| Code                                | HTTP | Description                                                                                                                                              |
| ----------------------------------- | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CONVERSATION_NOT_FOUND`            | 404  | The `conversation` identifier (`uuid`, `whatsapp_user_id`, `username`, or `phone`) does not resolve to any conversation in the business.                 |
| `CONTACT_NOT_FOUND`                 | 404  | The contact identifier does not resolve to any contact in the business.                                                                                  |
| `PHONE_NUMBER_AMBIGUOUS`            | 409  | Several contacts share that phone number (recycled numbers / separate identities). Identify the conversation by `whatsapp_user_id` or `uuid`.            |
| `USERNAME_AMBIGUOUS`                | 409  | Several contacts share that username. Identify the conversation by `whatsapp_user_id` or `uuid`.                                                         |
| `CHANNEL_NOT_CONFIGURED`            | 422  | The conversation has no WhatsApp channel configured. Connect one in the dashboard before sending.                                                        |
| `TESTER_CONVERSATION_NOT_WRITABLE`  | 422  | Tester conversations do not accept real WhatsApp sends. Use a real one, or restrict the action to tags/notes/mailbox.                                    |
| `TRANSCRIPTION_REQUIRED_TO_RESOLVE` | 422  | `POST /conversation/resolve`: the conversation has inbound media awaiting transcription. Complete the manual transcription from the dashboard and retry. |

### Tags

| Code                        | HTTP | Description                                                                                                             |
| --------------------------- | ---- | ----------------------------------------------------------------------------------------------------------------------- |
| `TAG_NOT_FOUND`             | 404  | The tag does not exist for this business.                                                                               |
| `TAG_ALREADY_ASSIGNED`      | 409  | The tag is already assigned to this conversation.                                                                       |
| `TAG_NOT_ASSIGNED`          | 404  | The tag is not assigned, so it cannot be removed.                                                                       |
| `TAG_AMBIGUOUS`             | 409  | Multiple tags match that name. Use `tag_uuid` to disambiguate.                                                          |
| `TAG_BUSINESS_MISMATCH`     | 400  | The tag belongs to a different business.                                                                                |
| `CANNOT_ASSIGN_DEFAULT_TAG` | 422  | The tag is system-managed (handled by the backend, e.g. the pending-conversion tag) and cannot be assigned via the API. |
| `CANNOT_REMOVE_DEFAULT_TAG` | 422  | The tag is system-managed (handled by the backend, e.g. the pending-conversion tag) and cannot be removed via the API.  |

### Mailboxes and categories

| Code                         | HTTP | Description                                                                  |
| ---------------------------- | ---- | ---------------------------------------------------------------------------- |
| `CATEGORY_NOT_FOUND`         | 404  | The mailbox category does not exist for this business.                       |
| `CATEGORY_BUSINESS_MISMATCH` | 403  | The category belongs to a different business.                                |
| `AMBIGUOUS_CATEGORY`         | 409  | Multiple categories match that name. Use `category_uuid` to disambiguate.    |
| `MAILBOX_NOT_FOUND`          | 404  | The mailbox does not exist for this business.                                |
| `MAILBOX_ALREADY_ASSIGNED`   | 409  | The conversation is already in that mailbox.                                 |
| `AMBIGUOUS_MAILBOX`          | 409  | Multiple mailboxes match that name. Use `mailbox_uuid` to disambiguate.      |
| `NO_MAILBOXES_IN_CATEGORY`   | 422  | The category has no mailboxes configured. Add at least one in the dashboard. |

### Precondition guards

| Code                      | HTTP | Description                                                                                          |
| ------------------------- | ---- | ---------------------------------------------------------------------------------------------------- |
| `WINDOW_CLOSED`           | 422  | The 24h window is closed. Send an approved [template](/en/templates) to reopen it.                   |
| `WALLET_BLOCKED`          | 402  | The token wallet for the required AI model is empty or blocked. Top up to continue.                  |
| `VISION_WALLET_BLOCKED`   | 402  | The vision token wallet is empty. Vision processing requires top-up.                                 |
| `VISION_BLOCKED`          | 402  | The thread's vision pipeline is blocked. Resolve the pending media in the dashboard before retrying. |
| `NO_AI_EMPLOYEE_ASSIGNED` | 422  | No AI employee is assigned to this conversation. Assign one before running the action.               |

### Owner ↔ executor coherence (schedules)

| Code             | HTTP | Description                                                                                                              |
| ---------------- | ---- | ------------------------------------------------------------------------------------------------------------------------ |
| `OWNER_MISMATCH` | 422  | The scheduled message's executor does not match the conversation's current owner. Reassign or cancel the schedule first. |

### AI employees and execution

| Code                           | HTTP | Description                                                                                           |
| ------------------------------ | ---- | ----------------------------------------------------------------------------------------------------- |
| `AI_EMPLOYEE_NOT_FOUND`        | 404  | The AI employee does not exist for this business.                                                     |
| `AMBIGUOUS_AI_EMPLOYEE`        | 409  | Multiple employees match that name. Use `ai_employee_uuid` to disambiguate.                           |
| `AI_EMPLOYEE_ALREADY_ASSIGNED` | 409  | That AI employee is already assigned to the conversation.                                             |
| `INVALID_ASSIGNEE_FOR_RUN_AI`  | 409  | The conversation is human-owned and no `ai_employee` was specified. Pass one or reassign an AI first. |
| `AI_EXECUTION_FAILED`          | 500  | The AI execution failed unexpectedly. Retry; if it persists, check the employee's dashboard.          |
| `ACTIONS_DEPTH_EXCEEDED`       | 422  | Chained AI actions exceed the maximum depth allowed in a single request.                              |

### Scheduled message action

| Code                                | HTTP | Description                                                                                                            |
| ----------------------------------- | ---- | ---------------------------------------------------------------------------------------------------------------------- |
| `SCHEDULED_MESSAGE_ACTION_REQUIRED` | 422  | There is an active scheduled message on the conversation. Specify `scheduled_message_action` (`reassign` or `cancel`). |
| `SCHEDULED_MESSAGE_ACTION_INVALID`  | 400  | The `scheduled_message_action` value is invalid. Must be `reassign` or `cancel`.                                       |

### Uploads

| Code                                 | HTTP | Description                                                                                                           |
| ------------------------------------ | ---- | --------------------------------------------------------------------------------------------------------------------- |
| `INVALID_FILE_TYPE`                  | 400  | The file type is not allowed. See the documentation for the list of accepted MIME types.                              |
| `FILE_TOO_LARGE`                     | 400  | The file exceeds the maximum size for its category.                                                                   |
| `STORAGE_QUOTA_EXCEEDED`             | 413  | The business has reached its storage quota. Free up space or upgrade the plan.                                        |
| `STORAGE_QUOTA_CLEANUP_INSUFFICIENT` | 507  | Storage is full and automatic cleanup could not free enough space for this upload. Free up space or upgrade the plan. |
| `FILE_NOT_FOUND`                     | 404  | No file matches that `file_uuid` for this business.                                                                   |
| `FILE_NOT_UPLOADED`                  | 422  | The file was registered but the upload was never confirmed. Re-upload before referencing it.                          |
| `SIZE_MISMATCH`                      | 422  | The actual size of the uploaded file does not match the size declared in `request-upload`.                            |
| `MIME_MISMATCH`                      | 422  | The actual MIME type does not match the declared one. Re-upload with the correct `Content-Type`.                      |
| `UPLOAD_FAILED`                      | 500  | The upload could not be completed due to a storage error. Retry.                                                      |

### Messages

| Code                  | HTTP | Description                                                                                                                                                                    |
| --------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `PREPARE_FAILED`      | 500  | The message could not be prepared (DB or upstream error). Retry.                                                                                                               |
| `SEND_FAILED`         | 502  | Sending to WhatsApp failed. Check the channel's health and retry.                                                                                                              |
| `BSUID_SEND_DISABLED` | 409  | The contact has no phone number, and sending via its BSUID (business-scoped user ID) is disabled for this business. Use a contact with a phone number or enable BSUID sending. |

### Quick replies and templates

| Code                                         | HTTP | Description                                                                                                                             |
| -------------------------------------------- | ---- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `QUICK_REPLY_NOT_FOUND`                      | 404  | The quick reply does not exist for this business.                                                                                       |
| `QUICK_REPLY_AMBIGUOUS`                      | 409  | Multiple quick replies match that name. Use `quick_reply_uuid` to disambiguate.                                                         |
| `QUICK_REPLY_EMPTY`                          | 422  | The quick reply has no actions configured. Add at least one in the dashboard.                                                           |
| `TEMPLATE_NOT_FOUND`                         | 404  | The template does not exist for this business.                                                                                          |
| `TEMPLATE_NOT_APPROVED`                      | 422  | The template is not approved by Meta. Approval is required before sending.                                                              |
| `AUTH_TEMPLATE_REQUIRES_PHONE`               | 409  | An authentication template cannot be sent to a contact without a phone number: Meta requires it. Send to a contact with a phone number. |
| `TEMPLATE_AMBIGUOUS`                         | 409  | Multiple templates match that name. Specify `language` to disambiguate.                                                                 |
| `TEMPLATE_VARIABLES_INVALID`                 | 422  | The body variables do not match the template (wrong count, missing index, or empty value).                                              |
| `TEMPLATE_HEADER_MISMATCH`                   | 400  | The header type does not match what the template declares (e.g. template expects an image but you sent text).                           |
| `TEMPLATE_FAKE_REQUIRES_TESTER_CONVERSATION` | 422  | This template is a fake (test-only) template and can only be sent to tester conversations.                                              |

### Generic operations

| Code            | HTTP | Description                                                       |
| --------------- | ---- | ----------------------------------------------------------------- |
| `FETCH_FAILED`  | 500  | Could not load the data required to complete this request. Retry. |
| `UPDATE_FAILED` | 500  | The change could not be applied (DB error). Retry.                |
| `UNKNOWN_ERROR` | 500  | Unexpected error. Contact support if it persists.                 |
