API de WhatsApp para desarrolladores
WAIA Connect es una API REST sobre la API oficial de WhatsApp de Meta (Cloud API y Coexistence). Mandás un POST /v1/messages con tu clave, nosotros lo encolamos y lo entregamos a Meta a un ritmo seguro, y los mensajes que entran te llegan a un webhook firmado. Proveedor de tecnología verificado por Meta, con documentación pública, OpenAPI y ejemplos en cuatro lenguajes.
Qué resuelve la API por vos
- Cola de salida con reintentos: el envío se confirma con
202y se entrega a Meta respetando el ritmo por número. Un rechazo de Meta queda en el estado del mensaje con un código estable. - Idempotencia: el encabezado
Idempotency-Keyevita mandar dos veces el mismo mensaje si reintentás. - Webhooks firmados con HMAC sobre fecha y cuerpo (protección contra reenvíos), y un encabezado estático opcional para herramientas sin código como n8n.
- Plantillas: crearlas, sincronizarlas y validarlas antes de mandarlas a Meta, con el motivo y cómo arreglarlo si algo va a ser rechazado. También carruseles de 2 a 10 tarjetas con foto o video, y saber qué tarjeta y qué botón tocó cada contacto (Plantillas carrusel).
- Media: enviar imagen, documento, audio y video por enlace, y descargar la media que entra por un proxy.
- Leído y «escribiendo…»: marcar como leído un mensaje que recibiste (tildes azules) y mostrar «escribiendo…» mientras tu sistema arma la respuesta. No consume cuota.
- Webhooks por API (
/v1/webhooks): crearlos, probarlos y rotar su secreto con tu clave; y el enlace de alta puede traer el webhook del número, que nace firmado con el secreto que ya tenés. - El desenlace de cada alta:
onboarding.completedyonboarding.failed(con el motivo y el código de Meta) llegan a tu webhook, o lo preguntás conGET /v1/onboarding-links?externalId=; y la baja también va por API (DELETE /v1/connections/{id}, con tuexternalId): su webhook se apaga solo y te llegaconnection.disconnected. - El historial de convivencia: si lo elegís al conectar, recibís hasta 6 meses de chats por webhook (
history.batch) o lo pedís por la API (GET /v1/connections/{id}/history). No consume cuota. - Mensajes editados y borrados:
message.editedtrae la versión final con el id del original (en números sólo Cloud API, Meta avisa la edición sin el texto:textAvailable: false) ymessage.revoked, el borrado. - Errores de Meta traducidos a un catálogo de códigos estables, con qué hacer en cada caso.
- Estado de envío antes de una campaña:
GET /v1/connections/{id}/sending-statusdice si un número puede iniciar conversaciones y por qué no — el veredicto y los códigos originales de Meta (141006,141010,131042), la verificación del negocio, el pago (sin datos de tarjeta) y el techo diario, que comparte todo el portafolio; lo que Meta no deja leer vieneunknown. Cada cambio llega a tu webhook comoconnection.sending_status_changed(Estado de envío). - Avisos por correo y Novedades: cada aviso de tus números (desconectado, plantilla aprobada, webhook que falla…) queda en
GET /v1/noticescon el mismo texto del correo; elegís si además llega por correo, para toda la cuenta (PATCH /v1/account/settings) o número por número.
Cómo se ve
Un envío es un pedido HTTP con tu clave de API. El número sale del identificador de conexión (conn_…) que te devuelve GET /v1/connections.
Ejemplos listos para copiar en cURL, Node.js, PHP y Python: Enviar un mensaje. Todo el contrato: OpenAPI.
Todo lo que hace la API, endpoint por endpoint
| Endpoint | Qué hace |
|---|---|
POST /v1/messages | Enviar un mensaje: texto, plantilla, imagen, documento, audio o video. Se confirma con 202 y sale por la cola. Límite por número (Convivencia 20/s, Cloud API 80/s) y por cuenta. |
GET /v1/messages/{id} | El estado de un envío (en cola, enviado, entregado, leído, fallido) y el motivo si falló. Nunca el contenido. |
POST /v1/messages/read | Marcar como leído un mensaje que recibiste (tildes azules) y, si querés, mostrar «escribiendo…». No consume cuota. |
GET /v1/connections | Tus números conectados, con su identificador conn_…, su estado y su modo (Cloud API o convivencia). |
PATCH /v1/connections/{id} | Ponerle a un número tu nombre, tu identificador externo, notas, un límite mensual de envíos y si sus avisos te llegan por correo. |
DELETE /v1/connections/{id} | Dar de baja un número (por conn_… o tu identificador externo), como «Desconectar» del panel: libera el lugar en tu plan y no borra nada en Meta. |
GET /v1/connections/{id}/history | Leer, por páginas, el historial de convivencia que elegiste recibir al conectar. Leer no borra nada. |
POST /v1/connections/{id}/history/{batchId}/ack | Confirmar que recibiste una tanda del historial: WAIA Connect la borra en el acto. |
GET /v1/account/settings | Ver si los avisos de tus números y de tus altas te llegan por correo (emailNotices). |
PATCH /v1/account/settings | Prender o apagar esos avisos por correo para toda la cuenta. Facturación, seguridad y soporte llegan siempre. |
GET /v1/notices | Las Novedades: cada aviso de tus números, haya salido por correo o no, con el mismo texto, en tu idioma. Filtrás por número y por no leídos. |
POST /v1/notices/{id}/read | Marcar un aviso como leído (también en el panel). |
POST /v1/notices/read-all | Marcar todos los avisos como leídos de una vez (también en el panel). |
GET /v1/usage | Lo que consumiste en el período actual, tus números y el extra estimado del ciclo. |
GET /v1/connections/{id}/sending-status | ¿Puede iniciar conversaciones este número? canSend, los códigos de Meta por entidad, verificación, pago (sin tarjeta) y techo diario; lo que Meta no deja leer, unknown. |
POST /v1/connections/{id}/sending-status/refresh | Releer el estado de envío en Meta (sólo lectura), una vez por número cada 10 min. |
GET /v1/connections/{id}/usage | Las cifras de un número: totales, serie por día y salud. |
GET /v1/usage/by-connection | Los totales de todos tus números en un período, de un vistazo. |
GET /v1/accounts/oversubscription | Si estás vendiendo más números de los que incluye tu plan. |
GET /v1/branding | Tu marca (nombre, logo, color) para la página de alta que ven tus clientes. |
PUT /v1/branding | Cambiar tu marca. |
POST /v1/onboarding-links | Crear un enlace de alta para que tu cliente conecte su número sin darte sus credenciales de Meta. Con webhook, el número nace con su webhook. |
GET /v1/onboarding-links | Tus enlaces de alta y en qué quedó cada uno (outcome). Con ?externalId=, los de un cliente. |
GET /v1/onboarding-links/{id} | Un enlace de alta con su desenlace: pendiente, completado (con el conn_… y el webhook) o fallido, con el motivo y el código de Meta. |
PATCH /v1/onboarding-links/{id} | Cambiar la página previa de un enlace vivo: intro: "minimal" (un botón y una línea) o full; null = la de la cuenta. |
GET /v1/onboarding-cases | Los casos del alta de tus clientes (A-<n>): lo que escribieron, el código de Meta y el diagnóstico; ?status=open|acked|all. |
POST /v1/onboarding-cases/{id}/ack | Marcar un caso como atendido (idempotente). Una entrega del webhook no cuenta. |
DELETE /v1/onboarding-links/{id} | Anular un enlace de alta. |
POST /v1/webhooks | Crear un webhook de la cuenta o de un número (por conn_… o tu externalId). El secreto de firma sale una sola vez. |
GET /v1/webhooks | Tus webhooks, todos o los de un número (filtrá por conn_… o externalId). Nunca el secreto. |
GET /v1/webhooks/{id} | Un webhook y su estado: activo, fallos seguidos, última respuesta. |
PATCH /v1/webhooks/{id} | Cambiar la URL, los eventos, encenderlo o apagarlo, o pasarlo a otro número. |
DELETE /v1/webhooks/{id} | Borrar un webhook. |
POST /v1/webhooks/{id}/test | Mandarle ahora un evento de prueba firmado y ver qué respondió tu servidor. |
POST /v1/webhooks/{id}/rotate-secret | Cambiar el secreto de firma: el nuevo sale una vez y el viejo deja de valer en el acto. |
GET /v1/media/{mediaId} | Descargar la imagen, el audio o el documento que te mandaron, sin exponer el token de Meta. |
GET /v1/templates | Tus plantillas y su estado en Meta. |
POST /v1/templates | Crear una plantilla en Meta, validada antes de mandarla: con imagen, video, documento o ubicación arriba y botones, o un carrusel de 2 a 10 tarjetas. |
POST /v1/templates/media | Subir el archivo de muestra que Meta revisa para una plantilla con imagen, video o documento. Devuelve el handle para crearla. |
POST /v1/templates/validate | Validar una plantilla sin mandar nada a Meta: todos los errores juntos, cada uno con su campo, en tu idioma. |
POST /v1/templates/preview | La vista previa de una plantilla, en JSON o como una burbuja de WhatsApp en HTML para mostrarle a tu cliente. |
GET /v1/templates/{id} | Una plantilla. |
PATCH /v1/templates/{id} | Editar una plantilla donde Meta lo permite (aprobada, rechazada o pausada), con su límite de veces. |
DELETE /v1/templates/{id} | Borrar una plantilla. |
POST /v1/templates/sync | Traer de Meta las plantillas y su estado actual. |
POST /v1/templates/precheck | Validar un borrador antes de mandarlo: si Meta lo va a rechazar, el motivo y cómo arreglarlo. |
POST /v1/templates/generate-examples | Proponer ejemplos para las variables de una plantilla (Meta los pide). |
GET /v1/templates/catalog | El catálogo de plantillas por rubro, armadas para que Meta las apruebe. |
POST /v1/templates/seed | Cargar plantillas del catálogo en un número. |
GET /v1/templates/bulk-targets | A qué números se le puede aplicar una plantilla de una vez. |
POST /v1/templates/bulk | Crear la misma plantilla en varios números de una vez. |
GET /v1/templates/drafts | Las plantillas que te propusieron tus clientes, para revisar. |
GET /v1/templates/drafts/count | Cuántas propuestas esperan revisión. |
POST /v1/templates/drafts/{id}/approve | Aprobar una propuesta: se valida y se crea en Meta. |
PUT /v1/templates/drafts/{id} | Corregir una propuesta antes de aprobarla (se guarda la original). |
POST /v1/templates/drafts/{id}/reject | Rechazar una propuesta. |
POST /v1/templates/drafts/bulk-approve | Aprobar varias propuestas juntas; si una falla, las otras siguen. |
POST /v1/template-links | Crear un enlace para que tu cliente te proponga plantillas para su número. |
GET /v1/template-links | Tus enlaces para proponer plantillas. |
DELETE /v1/template-links/{id} | Anular un enlace para proponer plantillas. |
El detalle de cada uno, con sus errores: OpenAPI.
Lo que no hace
- No es una bandeja de chats para atender con un equipo: para eso está WAIA, nuestro producto llave en mano.
- No guarda archivos: para mandar un archivo propio lo hospedás vos y mandás el enlace.
- No te saca de las reglas de Meta: la ventana de 24 horas, las plantillas aprobadas y los límites de envío siguen valiendo. Te los explicamos en Antes de conectar.
Cuánto cuesta
Tarifa plana por número conectado, sin tope de mensajes. Empezás con 14 días de prueba; el plan más chico es Starter (US$ 12 por mes).
- Starter — US$ 12 por mes, 1 número
- Studio — US$ 25 por mes, 5 números
- Agencia — US$ 45 por mes, 12 números
- Escala — US$ 99 por mes, 30 números, y US$ 3 por cada número extra
Meta cobra aparte sus mensajes, a tu tarjeta; no les agregamos recargo. Comparación con quien sí lo hace: WAIA Connect vs Twilio.
Preguntas frecuentes
¿Usa la API oficial de Meta?
Sí. WAIA Connect es un proveedor de tecnología verificado por Meta y opera la Cloud API y la convivencia (Coexistence). No usa librerías no oficiales que simulan WhatsApp Web.
¿Cómo recibo los mensajes que entran?
Registrás una URL https y te llegan por POST, firmados con HMAC. La guía de verificación de la firma tiene ejemplos en cuatro lenguajes.
¿Qué pasa si mando dos veces el mismo pedido?
Con el mismo Idempotency-Key el mensaje se manda una sola vez y la segunda respuesta devuelve el mismo identificador.
¿Hay límite de mensajes por mes?
En WAIA Connect no: el plan se paga por número conectado. Meta sí tiene límites propios para iniciar conversaciones con plantillas, que dependen de tu cuenta de Meta.
¿La documentación está pensada para leerla con una IA?
Sí: cada módulo está también en Markdown, hay un llms.txt en la raíz del sitio y el contrato completo está en OpenAPI.
Para seguir leyendo
Conectá tu primer número hoy
Verificado por Meta como proveedor de tecnología. Coexistence en un click.
Empezar