15 de octubre de 2026 • 12 min de lectura
Si tu producto está por mandar su primer mensaje por la API de WhatsApp, el primer paso correcto casi siempre es Twilio. El segundo, el mismo día, es arrancar la verificación de negocio de Meta, para poder irte de Twilio más adelante.
Soy Twilio Champion, así que tomá la primera mitad con la sal que corresponde. La segunda mitad es la que te ahorra dinero. Y es la que se saltean la mayoría de los tutoriales, porque te muestran un solo camino y cortan cuando llega el primer mensaje.
Este post cubre los dos caminos. Muestra la configuración que uso desde la consola de Twilio y el código del webhook del repo de demo de mi video. Y cierra con lo que cuesta cada mensaje según la tabla de precios de Meta vigente desde el 01/10/2026.
En el papel, el camino directo es más corto. Tu código habla con Meta Cloud API y listo, dos cajas en el diagrama. En la práctica hay mucho en el medio:
El camino de Twilio tiene una caja más. Tu código habla con Twilio, y Twilio habla con Meta por las APIs que Meta ofrece a proveedores y partners. A cambio de esa caja extra tenés una sola API para WhatsApp, SMS y voz. Twilio se encarga de los tokens y del refresh, y usás un saldo prepago que Twilio va consumiendo a medida que mandás. No hay un mínimo grande para cargar, y el saldo también cubre el número de teléfono y el resto de la telefonía. Lo que pagás por eso es un fee en cada mensaje, que desgloso más abajo.
Acá el orden importa, porque una cuenta recién creada no te deja hacer mucho.
Recargá la página de senders de WhatsApp. El sender aparece offline unos minutos y después pasa a online, listo para mandar y recibir. Desde no tener número hasta el primer mensaje, todo lleva entre 10 y 15 minutos.
Dos cosas de esa página del sender merecen una segunda mirada. La primera es el throughput (mensajes procesados por segundo): dice 80 mensajes por segundo como salida base, y eso es media mentira. Lo que tenés en realidad depende de tu estado de compliance y de cuánta información del negocio compartiste con Twilio y Meta. Planificá con ese número como techo, no como promesa. La segunda es que todo lo demás también vive ahí: el webhook de mensajes entrantes y la configuración de llamadas de WhatsApp. También está el perfil que la gente ve en WhatsApp (nombre visible, sitio web, dirección, email, descripción). Nada de eso te obliga a pasar por la consola de Meta.
El repo de demo es una app chica de Node 20 con Express 5, el SDK de Twilio y un modelo gratis de OpenRouter (google/gemma-4-31b-it:free por defecto). El objetivo es una prueba funcional: mandás un mensaje de WhatsApp, la app genera la respuesta y te la devuelve. En local la expongo con ngrok y apunto el webhook de entrada del sender a PUBLIC_URL/whatsapp.
De ese webhook, hay tres decisiones que mantendría en cualquier versión de producción.
Validá la firma contra la URL pública. Twilio firma la URL exacta configurada en la consola, que es la de ngrok, no la que ve Express detrás del túnel. Si reconstruís la URL a partir del request, vas a tener un 403 en cada mensaje.
webhook.post('/whatsapp', express.urlencoded({ extended: false }), (req, res) => {
// Twilio signs the public URL (the ngrok one), not the one Express sees.
const url = PUBLIC_URL + req.originalUrl;
const signature = req.header('X-Twilio-Signature');
if (!signature) {
console.warn('[403] Request without X-Twilio-Signature header');
return res.status(403).send('Forbidden');
}
if (!twilio.validateRequest(TWILIO_AUTH_TOKEN, signature, url, req.body)) {
console.warn(`[403] Invalid signature for ${url} (stale PUBLIC_URL?)`);
return res.status(403).send('Forbidden');
}
// Answer right away: Twilio cuts the webhook at 15 seconds.
res.type('text/xml').send('<Response></Response>');
handleMessage(req.body).catch((err) => console.error('[ERR] Unexpected:', err.message));
});
Primero respondé, después pensá. Twilio corta el webhook a los 15 segundos, y un modelo gratis en un día cargado puede tardar más que eso. Por eso el handler devuelve un TwiML vacío al instante y la respuesta sale después por la API REST. La misma función maneja también las dos fallas que pasan en la vida real: falla el modelo o falla el envío. En los dos casos la persona recibe un mensaje de fallback en lugar de silencio.
async function handleMessage({ From, Body = '', ProfileName, NumMedia = '0' }) {
const text = Body.trim();
let reply;
if (Number(NumMedia) > 0 && !text) {
reply = ONLY_TEXT;
} else {
try {
addMessage(From, 'user', text);
reply = await generateReply(getHistory(From), ProfileName);
addMessage(From, 'assistant', reply);
} catch (err) {
reply = FALLBACK;
}
}
try {
await client.messages.create({ from: TWILIO_WHATSAPP_FROM, to: From, body: reply });
} catch (err) {
if (reply === FALLBACK) return;
await client.messages
.create({ from: TWILIO_WHATSAPP_FROM, to: From, body: FALLBACK })
.catch(() => {});
}
}
Mantené el historial corto y bien formado. En la demo la conversación vive en memoria, con un tope de los últimos 10 mensajes. Siempre arranca con un mensaje del usuario y con los roles alternados, que es lo que esperan las APIs de chat completion. Esto no sobrevive a un reinicio ni escala más allá de una instancia, y el archivo lo dice. En producción va a una base de datos.
const MAX_MESSAGES = 10;
const conversations = new Map(); // From -> [{ role, content }]
export function addMessage(from, role, content) {
const history = getHistory(from);
// If the previous message got no answer (the model failed), replace it
// to keep user/assistant alternating.
if (history.at(-1)?.role === role) history.pop();
history.push({ role, content });
while (history.length > MAX_MESSAGES || history[0]?.role === 'assistant') history.shift();
conversations.set(from, history);
}
El comportamiento del asistente vive en un archivo prompts/system.md, así que cambiás lo que dice sin tocar código. Un siguiente paso natural es cargar ese archivo con la información del negocio, los horarios por ejemplo. Así responde las primeras preguntas y deriva a una persona cuando el caso lo necesita.
Los modelos gratis de OpenRouter tienen límites, unos 20 requests por minuto más un tope diario, y a veces directamente están saturados. Si ves errores 429, cambiá OPENROUTER_MODEL o usá openrouter/free, que se encarga de elegir uno disponible.
Cuando una persona te escribe, tenés 24 horas para responder libremente, y tu agente puede contestar todo lo que quiera dentro de esa ventana. Fuera de ella, WhatsApp devuelve el error 63016 y necesitás una plantilla aprobada.
Si querés ser vos el que arranca la conversación, las plantillas son la única forma. En la consola de Twilio creás una con un nombre, un idioma y un tipo de contenido (quick reply, catálogo, carrusel, según el caso de uso). Le agregás el cuerpo y las variables, si las necesitás. La misma plantilla puede servir para WhatsApp y para otros canales como Messenger o Instagram.
Después pasa a revisión, por Twilio por un lado y por Meta por el otro. Revisan sobre todo el compliance y que el mensaje coincida con tu caso de uso y con lo que hace la empresa. Meta es mucho más estricta con los mensajes salientes que con las respuestas a mensajes entrantes, así que esperá algunas idas y vueltas. Lo bueno es que, una vez aprobada, una plantilla te sirve por meses, incluso años.
Esta es la parte que decide entre un camino nativo como Meta y un intermediario que te lleva al mercado antes a cambio de un recargo. Precios en USD, según la tabla de Meta vigente desde el 01/10/2026 y los precios publicados de Twilio:
| Tipo de mensaje | Argentina, Meta | Argentina, vía Twilio | México, Meta | México, vía Twilio |
|---|---|---|---|---|
| Marketing | 0.0618 | 0.0668 | 0.0397 | 0.0447 |
| Utilidad | 0.0260 | 0.0310 | 0.0085 | 0.0135 |
| Autenticación | 0.0260 | 0.0310 | 0.0085 | 0.0135 |
| Servicio (desde el mensaje 1.001) | 0.0260 | 0.0310 | 0.0085 | 0.0135 |
| Servicio (primeros 1.000 por mes) | 0 | 0.005 | 0 | 0.005 |
| Mensaje entrante | 0 | 0.005 | 0 | 0.005 |
Algunas cosas de esa tabla importan más de lo que parece.
Twilio suma USD 0.005 por mensaje, entrante o saliente, incluso cuando Meta no cobra nada. Entonces los primeros 1.000 mensajes de servicio del mes, que del lado de Meta son gratis, te cuestan USD 5 a través de Twilio. Y desde el mensaje 1.001 pagás las dos cosas. Con 10.000 mensajes por mes, el recargo ronda los USD 50.
El país lo cambia todo. Las plantillas de marketing en Argentina cuestan más de seis centavos cada una, y el mismo mensaje en México es mucho más barato. Cuando hacés campañas salientes, segmentar por país también es una decisión de costos.
Y la que agarra desprevenido a quien construye agentes: los mensajes de servicio se cuentan por mensaje, no por conversación. Si tu agente responde cada mensaje del usuario con tres, cuatro o cinco burbujas, cada burbuja cuenta. Los 1.000 mensajes gratis del mes se terminan en semanas o días, según tu volumen. Responder con un solo mensaje bien escrito es más barato que cualquier decisión de proveedor que tomes.
Esta es mi recomendación para cualquiera que integre WhatsApp por código o con modelos de IA, y es lo que hago con clientes.
Salí con Twilio. Comprá el número y mandá el primer mensaje el primer día, en 10 a 15 minutos como mostré arriba. Iterá con usuarios reales y ajustá las plantillas desde Twilio. Ayuda mucho con esa parte y con mejorar la entrega mientras el producto todavía está cambiando.
Arrancá la verificación de negocio de Meta el mismo día. Es un proceso largo, unas dos semanas si todo sale bien y la aprueban al primer intento. Si no, hay idas y vueltas, y ese es justo el momento en que no querés estar esperando para mandar tu primer mensaje de WhatsApp.
Migrá cuando el volumen lo justifique. Una vez verificado el negocio, pasá las plantillas aprobadas (las mismas que tenías en Twilio) a Meta y cambiá al camino directo para dejar de pagar el recargo por mensaje.
Para ser justo con el otro lado: quizás ya tenés un portfolio verificado y un equipo cómodo con la rotación de tokens y una app de Meta. En ese caso, ir directo desde el primer día es perfectamente razonable, y está bien. El camino híbrido es para cuando el tiempo de salida al mercado es la restricción.
Donde yo pondría la atención no es en los USD 0.005. Es en anotar, antes del lanzamiento, el volumen mensual a partir del cual te vas. Un recargo que nadie revisa es el que termina costando dinero de verdad. Y la arquitectura tiene que mantener la lógica del agente separada del proveedor, para que migrar sea cambiar una capa y no reescribir el sistema.
-Gonza
¿Quieres un agente de IA así en tu WhatsApp? Mira mis servicios de agentes de IA para WhatsApp.
¿Quieres algo así funcionando en tu negocio? Hablemos.
Agenda una llamada gratis de 30 minutos¿Ya sabes lo que necesitas? Empieza con una auditoría de comunicaciones.