← Blog

·

Throughput y rate limit en la API de WhatsApp: mensajes por segundo y error 131056

Actualizado el 28/10/2026

La Cloud API de WhatsApp admite, por defecto, hasta 80 mensajes por segundo (mps) por número registrado, sumando entrada y salida, y puede subir automáticamente hasta 1.000 mps en números elegibles. Si superas ese ritmo, la API devuelve el error 130429. El error 131056 es otra cosa: es el pair rate limit, que se activa cuando envías demasiados mensajes desde el mismo número al mismo destinatario en poco tiempo.

En este artículo verás la diferencia entre throughput, pair rate limit, límites de llamadas a la API y límite de mensajes en 24 horas, qué códigos de error genera cada uno y un ejemplo de cola con backoff en Node.js y Python.

Cuatro límites que se suelen confundir

Quien integra la API de WhatsApp por primera vez suele llamar «rate limit» a todo. En la documentación de Meta son límites distintos, con causas y soluciones distintas:

LímiteQué mideErrorQué hacer
ThroughputMensajes por segundo de un número130429Bajar el ritmo y reintentar
Pair rate limitMensajes de tu número al mismo usuario en poco tiempo131056Esperar antes de volver a escribirle a ese usuario
Límite de llamadasSolicitudes de la app o de la cuenta a la API4 (app) y 80007 (cuenta de WhatsApp Business)Reducir la frecuencia de llamadas
Límite de mensajesDestinatarios únicos fuera de la ventana de atención en 24 horas, por portafolioEnvíos rechazados por encima del límiteSubir de nivel con calidad y volumen

El último no trata de velocidad, sino de alcance diario; en calidad del número en la API de WhatsApp explicamos cómo la calidad lo afecta. Aquí nos enfocamos en los tres primeros.

Throughput: cuántos mensajes por segundo

Según la página de throughput de Meta:

  • Cada número registrado en la Cloud API admite hasta 80 mps por defecto.
  • El throughput cuenta mensajes entrantes y salientes, de todos los tipos. Un número que recibe muchos mensajes tiene menos margen para enviar.
  • Los números de la app WhatsApp Business conectados a la API (coexistencia) tienen un throughput fijo de 20 mps.
  • Por encima del límite, la API responde con 130429 hasta que el ritmo vuelva al permitido.

Mejora automática a 1.000 mps

El número sube solo a hasta 1.000 mps, sin costo y sin cambio de precio, cuando cumple las tres condiciones:

  1. El portafolio comercial tiene límite de mensajes ilimitado.
  2. El número envió mensajes a 100.000 o más números únicos de usuarios fuera de la ventana de atención en un período móvil de 24 horas.
  3. El quality_score del número es amarillo (calidad media) o mejor.

Durante la mejora, que puede tardar hasta 1 minuto, el número queda inutilizable y la API devuelve el error 131057. Al terminar llega un webhook phone_number_quality_update con event igual a THROUGHPUT_UPGRADE. Para consultar el nivel actual de un número:

curl "https://graph.facebook.com/v26.0/PHONE_NUMBER_ID?fields=throughput" \
  -H "Authorization: Bearer $TOKEN"

La misma página da dos recomendaciones prácticas para quien envía en alto volumen. Primero, tu servidor de webhook debe soportar cerca de 3 veces el tráfico saliente (cada mensaje enviado genera eventos de estado) más 1 vez el tráfico entrante esperado, con latencia mediana por debajo de 250 ms y menos del 1 % de las solicitudes por encima de 1 segundo. Segundo, para mensajes con multimedia, usa IDs de archivos subidos previamente en vez de enlaces a archivos alojados en tus servidores, para aprovechar el throughput mayor.

¿Quieres probar mientras lees? Crea tu cuenta en Vectalk y envía el primer mensaje por la API oficial. Crear cuenta gratis →

Pair rate limit y el error 131056

El throughput está pensado para campañas que llegan a muchos usuarios distintos. Si envías muchos mensajes al mismo usuario, chocas con otro límite. La tabla de códigos de error de Meta describe el 131056 como demasiados mensajes enviados desde el número remitente al mismo número destinatario en un período corto. La solución indicada es esperar y reintentar, si de verdad quieres enviar más mensajes a ese número.

Meta no publica en esa documentación una cifra exacta para el pair rate limit, así que no programes contra un valor fijo. Escenarios típicos que disparan el 131056:

  • Un bot que divide una respuesta larga en diez mensajes seguidos.
  • Una integración en bucle que reenvía la misma notificación varias veces.
  • Pruebas de carga apuntadas a un único número de prueba.
  • Un envío masivo con la lista duplicada, que manda la misma plantilla dos veces a cada contacto.

La corrección casi siempre es de diseño, no de infraestructura: junta el contenido en un solo mensaje, deduplica la lista y espacia los envíos al mismo contacto. Para pruebas de carga, reparte los envíos entre varios destinatarios de prueba.

Errores de llamadas: 4, 80007 y 131048

Además de los límites de mensajes, la API también limita las llamadas:

  • 4: la app alcanzó su límite de llamadas. Meta sugiere revisar la sección de rate limit de la app en el panel y reducir la frecuencia o la cantidad de consultas.
  • 80007: la cuenta de WhatsApp Business alcanzó su límite de llamadas. Misma solución: intentar más tarde y reducir la frecuencia.
  • 131048: no es de velocidad. Indica restricciones de envío en el número por calidad; la recomendación es revisar el estado de calidad en el WhatsApp Manager. Reintentar solo lo empeora.

Los errores de consulta (4 y 80007) son frecuentes en integraciones que hacen polling, como consultar el estado de plantillas o números cada pocos segundos. Usa webhooks, que avisan cuando algo cambia.

Cola con backoff: el diseño recomendado

Para respetar todos estos límites a la vez, el diseño más simple es una cola con tres reglas:

  1. Ritmo global por número: un limitador que libera como máximo N envíos por segundo, con N por debajo del throughput del número (por ejemplo, 60 para un número estándar de 80 mps, dejando margen para los mensajes entrantes).
  2. Reintento con backoff exponencial y jitter para 130429, 4 y 80007: espera 1 s, 2 s, 4 s, 8 s… con algo de aleatoriedad, hasta un tope.
  3. Aplazamiento por destinatario para 131056: el envío vuelve a la cola de ese contacto con retraso, sin bloquear a los demás.

Los errores que no son temporales, como 131048, no deben reintentarse. Detén, registra e investiga.

Ejemplo en Node.js

const GRAPH = 'https://graph.facebook.com/v26.0';
const REINTENTO_GLOBAL = new Set([130429, 4, 80007]);
const MPS = 60; // por debajo de los 80 mps estándar

const esperar = (ms) => new Promise((r) => setTimeout(r, ms));

async function enviar(phoneNumberId, token, payload) {
  const res = await fetch(`${GRAPH}/${phoneNumberId}/messages`, {
    method: 'POST',
    headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
    body: JSON.stringify(payload),
  });
  const json = await res.json();
  if (res.ok) return { ok: true, id: json.messages?.[0]?.id };
  return { ok: false, code: json.error?.code };
}

export async function procesarCola(cola, phoneNumberId, token) {
  const intervalo = 1000 / MPS;
  while (cola.length) {
    const item = cola.shift();
    if (item.noAntesDe && item.noAntesDe > Date.now()) {
      cola.push(item); // todavía no es el turno de este contacto
      await esperar(intervalo);
      continue;
    }

    const r = await enviar(phoneNumberId, token, item.payload);
    if (r.ok) {
      item.onExito?.(r.id);
    } else if (REINTENTO_GLOBAL.has(r.code) && (item.intentos ?? 0) < 6) {
      item.intentos = (item.intentos || 0) + 1;
      const espera = Math.min(2 ** item.intentos * 1000, 60000) + Math.random() * 500;
      await esperar(espera); // frena todo el número
      cola.unshift(item);
    } else if (r.code === 131056) {
      item.noAntesDe = Date.now() + 30000; // aplaza solo a este destinatario
      cola.push(item);
    } else {
      item.onFallo?.(r.code); // 131048 y otros: no reintentar
    }
    await esperar(intervalo);
  }
}

El retraso de 30 segundos para el 131056 es un punto de partida, no una cifra de Meta: ajústalo según tus propios logs. En producción, cambia el arreglo por una cola persistente (Redis, SQS, RabbitMQ) para no perder envíos si el proceso se cae.

Ejemplo en Python

import asyncio
import random

import httpx

GRAPH = "https://graph.facebook.com/v26.0"
REINTENTO_GLOBAL = {130429, 4, 80007}
MPS = 60


async def enviar(client, phone_number_id, payload, intentos=0):
    r = await client.post(f"{GRAPH}/{phone_number_id}/messages", json=payload)
    if r.status_code == 200:
        return r.json()["messages"][0]["id"]

    code = r.json().get("error", {}).get("code")
    if code in REINTENTO_GLOBAL and intentos < 6:
        await asyncio.sleep(min(2 ** intentos, 60) + random.random() / 2)
        return await enviar(client, phone_number_id, payload, intentos + 1)
    if code == 131056:
        await asyncio.sleep(30)  # aplaza solo a este destinatario
        return await enviar(client, phone_number_id, payload, intentos + 1)
    raise RuntimeError(f"fallo definitivo: {code}")


async def disparar(phone_number_id, token, payloads):
    headers = {"Authorization": f"Bearer {token}"}
    async with httpx.AsyncClient(headers=headers, timeout=30) as client:
        tareas = []
        for p in payloads:
            tareas.append(asyncio.create_task(enviar(client, phone_number_id, p)))
            await asyncio.sleep(1 / MPS)  # ritmo global
        return await asyncio.gather(*tareas, return_exceptions=True)

Una respuesta 200 solo indica que el mensaje fue aceptado. Los fallos posteriores llegan al webhook de estado con status: "failed" y el código en errors; maneja los mismos códigos en ambos lugares. Consulta estado de mensajes vía webhook para el formato y errores de la API de WhatsApp para el resto de la lista.

Checklist antes de un envío grande

  • Conoce el throughput del número (?fields=throughput) y configura el limitador por debajo.
  • Si el número usa coexistencia, cuenta con 20 mps.
  • Deduplica la lista para que ningún contacto reciba el mismo mensaje dos veces.
  • Verifica que el volumen quepa en tu límite de mensajes de 24 horas.
  • Dimensiona el webhook para cerca de 3 veces tu tráfico saliente.
  • Sube los archivos multimedia antes y envíalos por ID.
  • Registra los códigos de error para ajustar el ritmo con datos reales.

Cómo hacerlo con Vectalk

Vectalk es un proxy de la Cloud API oficial de Meta, así que los límites de este artículo son los de Meta: 80 mps por número por defecto, 20 mps en coexistencia y los mismos códigos de error, que llegan en el cuerpo de la respuesta y en los webhooks con el formato oficial. Los envíos usan POST https://apis.vectalk.com.br/api/messages y el nivel de throughput del número aparece en la respuesta de GET /phone-numbers de la API de Vectalk. La lógica de cola y backoff de este artículo funciona sin cambios. Crea tu cuenta en apps.vectalk.com.br/register o revisa la guía rápida.

Si todavía estás armando la base de la integración, mira cómo validar la firma del webhook y cómo registrar el número en la Cloud API. El panorama general está en nuestra guía de WhatsApp Cloud API.

Preguntas frecuentes

¿Cuántos mensajes por segundo envía la API de WhatsApp?

Hasta 80 por segundo por número registrado, por defecto, sumando entrada y salida. Los números elegibles suben automáticamente a hasta 1.000 mps. Los números en coexistencia con la app WhatsApp Business quedan fijos en 20 mps.

¿Cuál es la diferencia entre el error 130429 y el 131056?

El 130429 es de throughput: el número superó su ritmo total permitido, sin importar el destinatario. El 131056 es de pair rate limit: demasiados mensajes al mismo destinatario en poco tiempo. El primero pide bajar el ritmo global; el segundo, espaciar los envíos a ese contacto.

¿Tener varios números aumenta la velocidad?

El throughput es por número, así que varios números suman velocidad. Pero el límite de destinatarios únicos en 24 horas es del portafolio y lo comparten todos sus números, y la calidad de cada uno se sigue evaluando. Más números no resuelven un límite de alcance.

¿Se cobra un mensaje rechazado por rate limit?

Meta cobra los mensajes entregados. Un mensaje rechazado con 130429 o 131056 no llega al destinatario y no debería cobrarse; concilia siempre con los webhooks de estado.

¿Cómo sé si mi número ya tiene 1.000 mps?

Consulta GET /PHONE_NUMBER_ID?fields=throughput. Cuando ocurre la mejora, Meta también envía el webhook phone_number_quality_update con el evento THROUGHPUT_UPGRADE.


Fuentes oficiales consultadas el 28/10/2026: Throughput (Meta), Códigos de error de la Cloud API (Meta), Límites de mensajes (Meta), Números de teléfono en la API de Vectalk.

Pon a funcionar el WhatsApp oficial de tu empresa

Crea tu cuenta, conecta tu número a la API oficial (puedes mantener la app con coexistencia) y empieza a atender y enviar mensajes.