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

# Errores

> Cómo la API señala los errores y cómo manejarlos.

La API sigue un contrato **REST puro**: el status code HTTP es la señal de
éxito o error.

## Forma de la respuesta

<CodeGroup>
  ```json Éxito 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>

Un éxito devuelve el payload directo, sin envelope. Un error devuelve siempre
`{ code, message }` — ambos campos están garantizados.

<Tip>
  Haz `switch` sobre `code`: es estable y forma parte del contrato. El
  `message` es texto humano de ayuda y puede afinarse entre versiones de la
  API sin aviso. Los mensajes se entregan en inglés (estándar de industria,
  mismo patrón que Stripe, GitHub o Linear). Si necesitas mostrarlos
  traducidos al usuario final, mapéalos en tu cliente por `code`.
</Tip>

## Familias de status

| HTTP  | Significado                                                                        | ¿Reintentar?               |
| ----- | ---------------------------------------------------------------------------------- | -------------------------- |
| `2xx` | Éxito — `200` lectura, `201` creación, `202` aceptado (async), `207` multi-status. | —                          |
| `4xx` | Error del request — auth, validación o recurso inexistente.                        | No, corrígelo primero.     |
| `429` | Rate limit excedido.                                                               | Sí, tras el `Retry-After`. |
| `5xx` | Error del servidor.                                                                | Sí, con backoff.           |

## Catálogo de códigos

<Note>
  El status HTTP de cada código es **típico**: el endpoint puntual puede devolver
  otro status si el contexto lo justifica. El authoritative por endpoint vive en
  su especificación OpenAPI. La tabla aquí es referencia general, no
  contrato vinculante por endpoint.

  Los códigos de ambigüedad de resolución de conversación (`PHONE_NUMBER_AMBIGUOUS`,
  `USERNAME_AMBIGUOUS`) pueden aparecer en
  **cualquier** endpoint que acepte una referencia `conversation` por
  `phone`/`username`/`whatsapp_user_id`, aunque su especificación liste otros
  códigos `409`.
</Note>

### Auth y tenant

| Code                      | HTTP | Descripción                                                                                        |
| ------------------------- | ---- | -------------------------------------------------------------------------------------------------- |
| `INVALID_API_TOKEN`       | 401  | El token no existe o fue revocado. Genera uno nuevo en Settings → API Token.                       |
| `TOKEN_BUSINESS_MISMATCH` | 403  | El token no pertenece al slug del negocio en la URL. Verifica que ambos refieran al mismo negocio. |

### Rate limit

| Code                  | HTTP | Descripción                                                                                                          |
| --------------------- | ---- | -------------------------------------------------------------------------------------------------------------------- |
| `RATE_LIMIT_EXCEEDED` | 429  | Superaste el bucket de 60 req/min. Espera los segundos del header `Retry-After`. Ver [Rate limits](/es/rate-limits). |

### Validación

| Code                   | HTTP | Descripción                                                                                          |
| ---------------------- | ---- | ---------------------------------------------------------------------------------------------------- |
| `INVALID_REQUEST`      | 400  | El body no pasó la validación de schema (campo faltante, tipo incorrecto, valor fuera de rango).     |
| `INVALID_CURSOR`       | 400  | El cursor de paginación es inválido o expiró. Reinicia el listado sin cursor.                        |
| `BATCH_LIMIT_EXCEEDED` | 400  | El grupo de acciones excede el máximo permitido en una sola request. El `message` lleva el cap real. |

### Conversación, contacto y canal

| Code                                | HTTP | Descripción                                                                                                                                                                                                             |
| ----------------------------------- | ---- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CONVERSATION_NOT_FOUND`            | 404  | El identificador de `conversation` (`uuid`, `whatsapp_user_id`, `username` o `phone`) no resuelve a ninguna conversación del negocio.                                                                                   |
| `CONTACT_NOT_FOUND`                 | 404  | El identificador de contacto no resuelve a ninguno del negocio.                                                                                                                                                         |
| `PHONE_NUMBER_AMBIGUOUS`            | 409  | Varios contactos comparten ese teléfono (números reciclados / identidades separadas). Identifica la conversación por `whatsapp_user_id` o `uuid`.                                                                       |
| `USERNAME_AMBIGUOUS`                | 409  | Varios contactos comparten ese username. Identifica la conversación por `whatsapp_user_id` o `uuid`.                                                                                                                    |
| `CHANNEL_NOT_FOUND`                 | 404  | La `channel` (clave pública del canal) enviada en la referencia no resuelve a ningún canal del negocio. Es obligatoria en todo request; cópiala en **Configuración → Canales** o lista tus canales con `GET /channels`. |
| `CHANNEL_NOT_CONFIGURED`            | 422  | La conversación no tiene un canal de WhatsApp configurado. Conecta uno en el dashboard antes de enviar.                                                                                                                 |
| `TESTER_CONVERSATION_NOT_WRITABLE`  | 422  | Las conversaciones tester no aceptan envíos reales a WhatsApp. Usa una real, o limita la acción a tags/notas/mailbox.                                                                                                   |
| `TRANSCRIPTION_REQUIRED_TO_RESOLVE` | 422  | La acción `mark_resolved` no puede cerrar la conversación: tiene media entrante con transcripción pendiente. Completa la transcripción manual desde el dashboard y reintenta.                                           |

### Tags

| Code                        | HTTP | Descripción                                                                                                   |
| --------------------------- | ---- | ------------------------------------------------------------------------------------------------------------- |
| `TAG_NOT_FOUND`             | 404  | El tag no existe para este negocio.                                                                           |
| `TAG_ALREADY_ASSIGNED`      | 409  | El tag ya está asignado a esta conversación.                                                                  |
| `TAG_NOT_ASSIGNED`          | 404  | El tag no está asignado, por lo que no se puede remover.                                                      |
| `TAG_AMBIGUOUS`             | 409  | Hay varios tags con ese nombre. Usa `tag_uuid` para desambiguar.                                              |
| `TAG_BUSINESS_MISMATCH`     | 400  | El tag pertenece a otro negocio.                                                                              |
| `CANNOT_ASSIGN_DEFAULT_TAG` | 422  | El tag es de sistema (lo administra el backend, ej. el de conversión pendiente) y no puede asignarse por API. |
| `CANNOT_REMOVE_DEFAULT_TAG` | 422  | El tag es de sistema (lo administra el backend, ej. el de conversión pendiente) y no puede removerse por API. |

### Mailboxes y categorías

| Code                         | HTTP | Descripción                                                                        |
| ---------------------------- | ---- | ---------------------------------------------------------------------------------- |
| `CATEGORY_NOT_FOUND`         | 404  | La categoría de mailbox no existe para este negocio.                               |
| `CATEGORY_BUSINESS_MISMATCH` | 403  | La categoría pertenece a otro negocio.                                             |
| `AMBIGUOUS_CATEGORY`         | 409  | Hay varias categorías con ese nombre. Usa `category: { uuid }` para desambiguar.   |
| `MAILBOX_NOT_FOUND`          | 404  | El mailbox no existe para este negocio.                                            |
| `MAILBOX_ALREADY_ASSIGNED`   | 409  | La conversación ya está en ese mailbox.                                            |
| `AMBIGUOUS_MAILBOX`          | 409  | Hay varios mailboxes con ese nombre. Usa `mailbox: { uuid }` para desambiguar.     |
| `NO_MAILBOXES_IN_CATEGORY`   | 422  | La categoría no tiene mailboxes configurados. Agrega al menos uno en el dashboard. |

### Guards de precondición

| Code                      | HTTP | Descripción                                                                                                       |
| ------------------------- | ---- | ----------------------------------------------------------------------------------------------------------------- |
| `WINDOW_CLOSED`           | 422  | La ventana de 24h está cerrada. Envía una [plantilla](/es/templates) aprobada para reabrirla.                     |
| `WALLET_BLOCKED`          | 402  | El wallet de tokens del modelo AI requerido está vacío o bloqueado. Recarga para continuar.                       |
| `VISION_WALLET_BLOCKED`   | 402  | El wallet de vision tokens está vacío. El procesamiento de visión requiere recarga.                               |
| `VISION_BLOCKED`          | 402  | El pipeline de visión del thread está bloqueado. Resuelve la media pendiente en el dashboard antes de reintentar. |
| `NO_AI_EMPLOYEE_ASSIGNED` | 422  | La conversación no tiene un empleado AI asignado. Asigna uno antes de ejecutar la acción.                         |

### Coherencia owner ↔ executor (schedules)

| Code             | HTTP | Descripción                                                                                                                   |
| ---------------- | ---- | ----------------------------------------------------------------------------------------------------------------------------- |
| `OWNER_MISMATCH` | 422  | El executor del scheduled message no coincide con el owner actual de la conversación. Reasigna o cancela el schedule primero. |

### Empleados AI y ejecución

| Code                           | HTTP | Descripción                                                                                          |
| ------------------------------ | ---- | ---------------------------------------------------------------------------------------------------- |
| `AI_EMPLOYEE_NOT_FOUND`        | 404  | El empleado AI no existe para este negocio.                                                          |
| `AMBIGUOUS_AI_EMPLOYEE`        | 409  | Hay varios empleados con ese nombre. Usa `ai_employee: { uuid }` para desambiguar.                   |
| `AI_EMPLOYEE_ALREADY_ASSIGNED` | 409  | Ese empleado AI ya está asignado a la conversación.                                                  |
| `INVALID_ASSIGNEE_FOR_RUN_AI`  | 409  | La conversación es human-owned y no se pasó `ai_employee`. Especifica uno o reasigna un AI primero.  |
| `AI_EXECUTION_FAILED`          | 500  | La ejecución del AI falló inesperadamente. Reintenta; si persiste, revisa el dashboard del empleado. |
| `ACTIONS_DEPTH_EXCEEDED`       | 422  | Las acciones AI encadenadas exceden la profundidad máxima permitida en una request.                  |

### Scheduled message action

| Code                                | HTTP | Descripción                                                                                                        |
| ----------------------------------- | ---- | ------------------------------------------------------------------------------------------------------------------ |
| `SCHEDULED_MESSAGE_ACTION_REQUIRED` | 400  | Hay un scheduled message activo en la conversación. Especifica `scheduled_message_action` (`reassign` o `cancel`). |
| `SCHEDULED_MESSAGE_ACTION_INVALID`  | 400  | El valor de `scheduled_message_action` es inválido. Debe ser `reassign` o `cancel`.                                |

### Uploads

| Code                                 | HTTP | Descripción                                                                                                                        |
| ------------------------------------ | ---- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `INVALID_FILE_TYPE`                  | 400  | El tipo de archivo no está permitido. Ver la documentación para la lista de MIME types aceptados.                                  |
| `FILE_TOO_LARGE`                     | 400  | El archivo excede el tamaño máximo para su categoría.                                                                              |
| `STORAGE_QUOTA_EXCEEDED`             | 413  | El negocio alcanzó su cuota de storage. Libera espacio o sube de plan.                                                             |
| `STORAGE_QUOTA_CLEANUP_INSUFFICIENT` | 507  | El storage está lleno y la limpieza automática no pudo liberar suficiente espacio para este upload. Libera espacio o sube de plan. |
| `FILE_NOT_FOUND`                     | 404  | No existe un archivo con ese `file_uuid` para este negocio.                                                                        |
| `FILE_NOT_UPLOADED`                  | 422  | El archivo fue registrado pero el upload nunca se confirmó. Re-súbelo antes de referenciarlo.                                      |
| `SIZE_MISMATCH`                      | 422  | El tamaño real del archivo subido no coincide con el declarado en `request-upload`.                                                |
| `MIME_MISMATCH`                      | 422  | El MIME type real no coincide con el declarado. Re-sube con el `Content-Type` correcto.                                            |
| `UPLOAD_FAILED`                      | 500  | El upload no se pudo completar por un error de storage. Reintenta.                                                                 |

### Mensajes

| Code                  | HTTP | Descripción                                                                                                                                                                                 |
| --------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `PREPARE_FAILED`      | 500  | El mensaje no se pudo preparar (error de DB o upstream). Reintenta.                                                                                                                         |
| `SEND_FAILED`         | 502  | El envío a WhatsApp falló. Verifica la salud del canal y reintenta.                                                                                                                         |
| `BSUID_SEND_DISABLED` | 409  | El contacto no tiene teléfono y el envío por su identidad BSUID (business-scoped user ID) está deshabilitado para este negocio. Usa un contacto con teléfono o habilita el envío por BSUID. |

### Respuestas rápidas y plantillas

| Code                                         | HTTP | Descripción                                                                                                                                                                                                                                                    |
| -------------------------------------------- | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `QUICK_REPLY_NOT_FOUND`                      | 404  | La respuesta rápida no existe para este negocio.                                                                                                                                                                                                               |
| `QUICK_REPLY_AMBIGUOUS`                      | 409  | Hay varias respuestas rápidas con ese nombre. Usa `quick_reply: { uuid }` para desambiguar.                                                                                                                                                                    |
| `QUICK_REPLY_EMPTY`                          | 422  | La respuesta rápida no tiene acciones configuradas. Agrega al menos una en el dashboard.                                                                                                                                                                       |
| `TEMPLATE_NOT_FOUND`                         | 404  | La plantilla no existe para este negocio.                                                                                                                                                                                                                      |
| `TEMPLATE_NOT_APPROVED`                      | 422  | La plantilla no está aprobada por Meta. La aprobación es requisito para enviar.                                                                                                                                                                                |
| `AUTH_TEMPLATE_REQUIRES_PHONE`               | 409  | No se puede enviar una plantilla de autenticación a un contacto sin teléfono: Meta exige el número. Envía a un contacto con teléfono.                                                                                                                          |
| `TEMPLATE_AMBIGUOUS`                         | 409  | El mismo nombre y `language` existe en 2 o más canales de WhatsApp conectados. El request no permite elegir a qué canal pertenece la plantilla, así que la ambigüedad no se puede resolver desde la integración. Contacta a soporte para resolver la colisión. |
| `TEMPLATE_VARIABLES_INVALID`                 | 422  | Las variables del body no coinciden con la plantilla (conteo incorrecto, índice faltante o valor vacío).                                                                                                                                                       |
| `TEMPLATE_HEADER_MISMATCH`                   | 400  | El tipo de header no coincide con el que declara la plantilla (ej: la plantilla espera imagen y enviaste texto).                                                                                                                                               |
| `TEMPLATE_FAKE_REQUIRES_TESTER_CONVERSATION` | 422  | La plantilla es del módulo Tester (fake) y solo puede enviarse a conversaciones tester.                                                                                                                                                                        |

### Operaciones genéricas

| Code            | HTTP | Descripción                                                                    |
| --------------- | ---- | ------------------------------------------------------------------------------ |
| `FETCH_FAILED`  | 500  | No se pudieron leer los datos necesarios para completar el request. Reintenta. |
| `UPDATE_FAILED` | 500  | El cambio no se pudo aplicar (error de DB). Reintenta.                         |
| `UNKNOWN_ERROR` | 500  | Error inesperado. Contacta a soporte si persiste.                              |
