Saltar a contenido

Errores, estados y límites

Ciclo de vida de un mensaje

Todo mensaje (individual o de broadcast) avanza por estos estados, visibles en el portal (sección Mensajes):

Estado Significado
pending Recibido por Arplyx, esperando que el worker lo procese.
queued En cola para salir al canal. Si hubo un fallo transitorio, queda acá entre reintentos.
sent Entregado a Meta.
delivered El proveedor confirmó entrega en el dispositivo del destinatario.
read El destinatario lo leyó (cuando el canal lo informa).
failed Falló de forma definitiva: se agotaron los reintentos o el error no es recuperable. El detalle del mensaje muestra el código y la descripción del último error.

Reintentos: los errores transitorios (problemas de red, 5xx del proveedor, rate limit) se reintentan automáticamente con backoff exponencial, hasta 5 intentos por defecto. Los errores permanentes (número inválido, cuenta desvinculada, credenciales rechazadas) marcan el mensaje failed sin reintentar.

De dónde salen delivered y read

  • Meta Official: llegan por el webhook de tu app de Meta. Si no lo configuraste, los mensajes quedan en sent. Ver el paso 6 de la guía Meta.

Para reaccionar a estas transiciones en tiempo real desde tu sistema, usá webhooks.

Vida útil de un mensaje: ttlSeconds, retención e idempotencia

Estos tres conceptos están relacionados — un mensaje vive ttlSeconds (default 24 h, recortado a la retención de tu plan) desde que se crea:

  • Al expirar, el mensaje se elimina (el registro completo: estados, historial de intentos). No pasa a failed ni dispara webhook: simplemente deja de existir en la próxima pasada de la purga (corre cada pocas horas).
  • Por eso GET /messages/{id} responde 404 para mensajes purgados: diseñá tu reconciliación asumiendo que los mensajes viejos desaparecen según la retención del plan (3 días en Free, 30 en el resto).
  • La deduplicación por externalId vive lo mismo que el mensaje: mientras el registro exista, repetir el externalId devuelve el original (o 409 si el payload difiere). Una vez purgado, ese externalId queda reutilizable y un request repetido crearía (y enviaría) un mensaje nuevo. Si tu sistema puede reintentar operaciones viejas, agregale al externalId un componente temporal (ej. turno-4812-2026-07-04).

En la práctica los reintentos de envío se agotan mucho antes del TTL (5 intentos con backoff, minutos), así que un mensaje que no pudo salir va a estar failed — con su webhook y su error.code — bastante antes de expirar.

Rate limits

Hoy la API pública no aplica límite de requests por segundo: el único límite es la cuota mensual del plan (429 quota_exceeded, sin header Retry-After; usá el campo resetsAt del body). Dimensioná tus workers con criterio — si más adelante agregamos un límite operativo, lo vamos a anunciar en la documentación con antelación.

Catálogo de errores HTTP

Todas las respuestas de error tienen un campo error; algunas agregan message o campos extra.

Status error Cuándo
400 validation_error El payload no pasa la validación. El cuerpo incluye details: una lista de { "path": "campo.afectado", "message": "..." } por cada problema.
401 Missing x-api-key header / Invalid API key Falta la clave, es inválida o fue revocada.
409 conflict El externalId ya existe con un payload distinto. Elegí otro externalId o repetí el payload original.
422 invalid_whatsapp_account El whatsappAccountId no existe o no es tuyo.
422 invalid_media El mediaId no existe (o ya se borró), no es tuyo, o no es JPEG/PNG cuando el contenido es image. El cuerpo incluye code (media_not_found / media_type_mismatch). Ver adjuntos.
413 media_too_large POST /media: el archivo supera los 20 MB.
429 media_pending_limit POST /media: tenés más de 200 archivos subidos sin usar. Se liberan al enviarse o a la hora.
403 templates_not_available Intentaste enviar una plantilla en el plan Free. El envío de plantillas (proactivo) está disponible desde el plan Starter.
403 feature_not_available La función no está disponible en tu plan (ej.: GET /inbound-messages fuera de Pro, webhooks fuera de Basic/Pro). El cuerpo incluye plan.
403 key_scope_violation La API key está scopeada a una cuenta y pediste operar sobre otra.
404 account_not_found El whatsappAccountId indicado en una consulta no existe o no es tuyo.
422 whatsapp_account_required La consulta necesita whatsappAccountId (tenés más de una cuenta vinculada, o ninguna) — ver remitentes entrantes.
429 quota_exceeded Cuota mensual agotada. El cuerpo incluye limit, used y resetsAt (cuándo se renueva: primer día del mes, UTC).
500 Internal server error Error inesperado de Arplyx. Reintentá con el mismo externalId (es seguro por idempotencia); si persiste, contactanos.

Ejemplo de validation_error:

{
  "error": "validation_error",
  "details": [
    { "path": "to.phoneE164", "message": "Invalid E.164 phone number" }
  ]
}

Los errores exclusivos de broadcast (lista vacía, plan sin broadcasts, etc.) están en Broadcasts por API.

Cuotas y límites por plan

Límites técnicos vigentes

Esta tabla describe los límites que aplica hoy la API: son los valores con los que el gateway responde 429 quota_exceeded, útiles para programar el manejo de errores de tu integración. Los planes comerciales y sus condiciones de contratación están en preparación (ver arplyx.com) y pueden no coincidir con estos números; el límite aplicable a tu cuenta es el que devuelve el propio 429 en su campo limit.

Plan Mensajes/mes Cuentas WhatsApp Retención de historial Broadcasts
Free 500 1 3 días No
Starter 2.000 1 30 días No
Basic 10.000 3 30 días Sí
Pro 20.000 5 30 días Sí
  • La cuota es compartida entre la API, el portal y los broadcasts: todo mensaje individual cuenta.
  • Se renueva el día 1 de cada mes (UTC). El cuerpo del error 429 te dice exactamente cuándo (resetsAt).
  • Tope adicional por broadcast: 5.000 destinatarios.
  • ttlSeconds se recorta a la retención del plan (en Free, un mensaje no puede vivir más de 3 días en cola).
  • La retención aplica al contenido de los mensajes (salientes y entrantes). El agregado de remitentes entrantes (hasWritten, firstInboundAt) no se purga: persiste mientras exista la cuenta de WhatsApp, en todos los planes.

¿Necesitás más volumen? Escribinos a info@arplyx.com.