> ## Documentation Index
> Fetch the complete documentation index at: https://help.ciarem.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Errores, límites y paginación

> El vocabulario de errores, los límites de uso, la paginación y cómo evoluciona la API.

## Errores

Los errores usan códigos de estado convencionales con un `detail` legible por máquina:

| Estado | Significado                                        | Ejemplo de `detail`                                                                                                                                   |
| ------ | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| 400    | La solicitud está mal dirigida                     | `{"code": "invalid_channel", …}`, `{"code": "channel_id_required", …}`                                                                                |
| 401    | La clave falta, no existe o fue revocada           | `"missing_bearer_token"`, `"invalid_api_key"`                                                                                                         |
| 402    | Saldo de WhatsApp insuficiente para lo que pediste | `{"code": "wa_insufficient_balance", …}`                                                                                                              |
| 403    | Credencial válida, pero no permitida aquí          | `"api_key_required"`, `"scale_plan_required"`, `"trial_expired"`, `"subscription_required"` — consulta [Autenticación](/api-reference/authentication) |
| 404    | El recurso no existe en tu organización            | `"not_found"`, `{"code": "contact_not_found", …}`                                                                                                     |
| 409    | Conflicto                                          | `{"code": "duplicate_contact", …}`, `{"code": "messaging_limit_exceeded", …}`                                                                         |
| 422    | El cuerpo de la solicitud no pasó la validación    | mensajes por campo, o `{"code": …}`                                                                                                                   |
| 429    | Superaste el límite de uso                         | `"rate_limited"` — reintenta según el encabezado `Retry-After`                                                                                        |

Los errores estructurados siempre llevan un `code` estable sobre el que puedes ramificar; las claves adicionales (como `conflicting_contact_id` en un contacto duplicado) te dan lo necesario para resolverlo. Cada forma de error está publicada en la [referencia de la API](/api-reference/openapi).

### Enviar una plantilla

`POST /v1/templates/{id}/send` rechaza la solicitud **completa** en vez de encolar una parte, así que un rechazo nunca te deja a medio enviar ni te cuesta nada. Los códigos sobre los que conviene ramificar:

| `code`                                                           | Estado    | Qué hacer                                                                                                                                                                                               |
| ---------------------------------------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `channel_id_required`                                            | 400       | Tu cuenta tiene más de un número de WhatsApp. Elige uno — la respuesta lista los ids elegibles.                                                                                                         |
| `invalid_channel`                                                | 400       | El `channel_id` no es un número activo de la cuenta de WhatsApp de esta plantilla.                                                                                                                      |
| `template_not_sendable`                                          | 409 / 422 | La plantilla no está `APPROVED` (409), o nunca podrá enviarse — el botón de una tarjeta del carrusel no tiene forma de llenarse (422).                                                                  |
| `messaging_limit_exceeded`                                       | 409       | El lote es mayor que lo que queda del límite móvil de 24 horas de WhatsApp. `remaining` indica cuántos cabrían.                                                                                         |
| `wa_insufficient_balance`                                        | 402       | Recarga la billetera de WhatsApp; no se encoló nada.                                                                                                                                                    |
| `contact_not_found`                                              | 404       | `index` indica cuál destinatario.                                                                                                                                                                       |
| `missing_variables`                                              | 422       | `tokens` lista lo que le falta a ese destinatario — incluido `header.media` cuando la plantilla tiene encabezado de medios y no enviaste una URL.                                                       |
| `unknown_variables` / `unknown_url_suffixes`                     | 422       | Enviaste una clave que la plantilla no usa. Se habría descartado en silencio, así que la rechazamos.                                                                                                    |
| `media_too_large` / `media_type_mismatch` / `media_fetch_failed` | 422       | Nosotros descargamos `header_media_url`; debe ser públicamente accesible, del tipo del encabezado y dentro del límite de tamaño de WhatsApp para ese tipo (5 MB imagen, 16 MB video, 100 MB documento). |
| `idempotency_key_in_flight`                                      | 409       | Una solicitud anterior con este `Idempotency-Key` todavía se está encolando.                                                                                                                            |

`GET /v1/templates/{id}/send-requirements` te dice qué necesita una plantilla **antes** de enviar, así que la mayoría de estos nunca tienen que ocurrir.

## Límites de uso

Cada organización tiene un presupuesto compartido de **20 solicitudes por segundo** entre todas sus claves — **5 por segundo** durante la prueba gratuita. Por encima del presupuesto, las solicitudes devuelven `429` con un encabezado `Retry-After` (segundos; siempre `1`, porque la ventana es de un segundo).

Cada respuesta — incluido el `429` — lleva tu presupuesto actual, para que puedas dosificar sin contar llamadas tú mismo:

| Encabezado              |                                                                       |
| ----------------------- | --------------------------------------------------------------------- |
| `X-RateLimit-Limit`     | Solicitudes permitidas por ventana.                                   |
| `X-RateLimit-Remaining` | Solicitudes restantes en la ventana actual.                           |
| `X-RateLimit-Reset`     | Cuándo se reinicia la ventana, como marca de tiempo Unix en segundos. |

Lee `X-RateLimit-Remaining` y baja el ritmo conforme se acerca a cero, en vez de correr hasta el `429`. Si tu integración realmente necesita más, habla con nosotros.

<Note>
  Una solicitud es una solicitud, sin importar cuánto haga. `POST /v1/templates/{id}/send` cuenta una sola vez lleve un destinatario o cien — así que agrupar destinatarios en un solo envío es la forma más barata de mantenerte dentro del presupuesto. Lo que acota el volumen real de mensajes es el propio límite móvil de 24 horas de WhatsApp, no este.
</Note>

## Reintentar de forma segura

`POST /v1/templates/{id}/send` acepta un encabezado **`Idempotency-Key`**. Envía la misma clave otra vez dentro de 24 horas y recibes la campaña original en lugar de un segundo envío — que es lo que quieres tras un timeout, cuando realmente no puedes saber si la solicitud llegó. Usa una clave nueva para cada envío distinto.

## Paginación

Los endpoints de listado devuelven:

```json theme={null}
{ "items": [ … ], "next_cursor": "cnt_…" }
```

Pasa `next_cursor` de vuelta como `?cursor=` para traer la siguiente página; un cursor `null` significa que llegaste al final. Los cursores son opacos — no los parsees.

Las listas de propiedades y etapas del funnel no se paginan: devuelven el conjunto completo, sin `next_cursor`.

## Compatibilidad

Esta es una API joven y en rápido movimiento — espera que evolucione. Dos hábitos mantienen tu integración estable:

* La mayoría de los cambios son **aditivos**: nuevos endpoints, nuevos parámetros opcionales, nuevos campos de respuesta, nuevos valores en campos de texto. Tolera campos y valores desconocidos — ignora lo que no reconozcas.
* Cada cambio del contrato aparece en el [changelog](/es/api-reference/changelog) — revísalo cuando algo se vea distinto.
