Integra WA Manager con n8n, Zapier, Make o tu propio código Integrate WA Manager with n8n, Zapier, Make or your own code
https://tudominio.com/wa-api/api/v1
En la barra lateral de WA Manager, pulsa el icono de llave 🔑 (junto al icono de campana y de cierre de sesión).
In the WA Manager sidebar, click the key icon 🔑 (next to the bell and logout icons).
En la pestaña API Keys, escribe un nombre identificativo (ej: «n8n producción») y opcionalmente selecciona una cuenta de WhatsApp concreta si quieres restringir el acceso. Pulsa Crear API Key.
In the API Keys tab, enter a descriptive name (e.g. «n8n production») and optionally select a specific WhatsApp account to restrict access. Click Create API Key.
La clave completa aparece justo después de crearla. Cópiala y guárdala en un lugar seguro. No se puede recuperar después.
The full key appears right after creation. Copy and save it somewhere safe. It cannot be retrieved later.
Incluye la API key en todas las peticiones con el header Authorization:
Include the API key in every request using the Authorization header:
Authorization: Bearer wam_a1b2c3d4...
Prueba que funciona obteniendo tus cuentas de WhatsApp:
Test it by fetching your WhatsApp accounts:
curl -H "Authorization: Bearer wam_TU_API_KEY" \ "https://tudominio.com/wa-api/api/v1/accounts"
[
{
"id": 1,
"account_name": "Mi número personal",
"type": "qr",
"phone_number": "+34612345678",
"status": "connected"
}
]
type: "qr"Número vinculado por QR (personal o Business). Soporta envío de texto, imágenes y documentos.
Number linked via QR (personal or Business). Supports sending text, images and documents.
type: "meta"WhatsApp Business API oficial de Meta. Solo permite envío de texto vía API (imágenes requieren ID de Meta).
Official Meta WhatsApp Business API. Only text sending via API (images require a Meta media ID).
Devuelve todas las cuentas accesibles con la API key. Si la clave está restringida a una cuenta, devuelve solo esa.
Returns all accounts accessible with the API key. If the key is restricted to one account, returns only that one.
[{
"id": 1,
"account_name": "Soporte",
"type": "qr", // "qr" | "meta"
"phone_number": "+34612345678",
"status": "connected" // "connected" | "disconnected"
}]
| Parámetro | Parameter | Tipo | Type | Descripción | Description | |
|---|---|---|---|---|---|---|
| limit | integer | opcional / optional | Máximo de resultados (defecto: 30) | Maximum results (default: 30) | ||
| offset | integer | opcional / optional | Paginación desde el resultado N | Pagination from result N | ||
| search | string | opcional / optional | Buscar por nombre o número | Search by name or number |
[{
"id": 42,
"account_id": 1,
"jid": "34612345678@s.whatsapp.net",
"name": "Juan García",
"last_message": "Hola, ¿cuándo llegará mi pedido?",
"last_message_at": 1724177400,
"unread_count": 2,
"is_group": false
}]
| Parámetro | Parameter | Tipo | Type | Descripción | Description | |
|---|---|---|---|---|---|---|
| account_id * | integer | requerido / required | ID de la cuenta de WhatsApp | WhatsApp account ID | ||
| jid * | string | requerido / required | JID de la conversación (ej: 34612345678@s.whatsapp.net) |
Conversation JID (e.g. 34612345678@s.whatsapp.net) |
||
| limit | integer | opcional / optional | Máximo de mensajes (defecto: 50) | Maximum messages (default: 50) | ||
| before | integer | opcional / optional | Paginar: ID interno del último mensaje recibido | Paginate: internal ID of the last received message |
[{
"id": 1234,
"wa_id": "3EB0...", // ID interno de WhatsApp
"direction": "in", // "in" | "out"
"body": "Hola, ¿me podéis ayudar?",
"type": "text", // text | image | document | audio | video
"status": "read", // sent | delivered | read | failed
"timestamp": "2026-08-20T18:30:00.000Z",
"sender_jid": null, // solo en grupos
"sender_name": null // solo en grupos
}]
Envía un mensaje de texto a un número. Funciona tanto con cuentas QR como Meta.
Sends a text message to a number. Works with both QR and Meta accounts.
| Campo | Field | Tipo | Type | Descripción | Description | |
|---|---|---|---|---|---|---|
| account_id * | integer | requerido / required | ID de la cuenta desde la que enviar | Account ID to send from | ||
| to * | string | requerido / required | Número destino. Ej: 34612345678 o 34612345678@s.whatsapp.net |
Destination number. E.g. 34612345678 or 34612345678@s.whatsapp.net |
||
| body * | string | requerido / required | Texto del mensaje | Message text |
curl -X POST \ -H "Authorization: Bearer wam_TU_API_KEY" \ -H "Content-Type: application/json" \ -d '{"account_id": 1, "to": "34612345678", "body": "Hola desde la API"}' \ "https://tudominio.com/wa-api/api/v1/send"
{
"ok": true,
"to": "34612345678@s.whatsapp.net",
"body": "Hola desde la API",
"wa_id": "3EB0C234D1..." // ID del mensaje en WhatsApp
}
| Parámetro | Parameter | Descripción | Description | |
|---|---|---|---|---|
| q | opcional / optional | Búsqueda por nombre o número | Search by name or number | |
| account_id | opcional / optional | Filtrar por cuenta | Filter by account | |
| limit | opcional / optional | Máximo de resultados (defecto: 20) | Maximum results (default: 20) |
[{
"account_id": 1,
"jid": "34612345678@s.whatsapp.net",
"name": "Juan García",
"conversation_name": "Juan García"
}]
En WA Manager, icono de llave 🔑 → pestaña Webhooks → rellena el formulario.
In WA Manager, key icon 🔑 → Webhooks tab → fill in the form.
La URL a la que WA Manager enviará los eventos. Debe ser HTTPS y estar accesible desde internet. En n8n será tu URL de webhook de nodo; en Zapier o Make, la URL que te proporcionen al crear el trigger.
The URL WA Manager will send events to. Must be HTTPS and publicly accessible. In n8n it's your node webhook URL; in Zapier or Make, the trigger URL they provide.
Introduce una cadena aleatoria como secreto. WA Manager firmará cada petición con HMAC-SHA256 y lo incluirá en el header X-WA-Signature. Así puedes verificar que el mensaje viene realmente de WA Manager.
Enter a random string as the secret. WA Manager will sign each request with HMAC-SHA256 and include it in the X-WA-Signature header. This lets you verify the message is genuinely from WA Manager.
Cada evento se envía como un POST JSON con esta estructura:
Each event is sent as a JSON POST with this structure:
{
"event": "message.inbound", // o "message.outbound"
"account_id": 1,
"timestamp": "2026-08-20T18:30:00.000Z",
"message": {
"id": 1234,
"wa_id": "3EB0C234D1...",
"jid": "34612345678@s.whatsapp.net",
"conversation_name": "Juan García",
"direction": "in",
"body": "Hola, necesito ayuda",
"type": "text",
"status": "received",
"timestamp_unix": 1724177400,
"sender_jid": null, // solo en grupos
"sender_name": null // solo en grupos
}
}
Si configuraste un secreto, el header X-WA-Signature contiene el HMAC-SHA256 del body en hexadecimal. Verifica así:
If you configured a secret, the X-WA-Signature header contains the HMAC-SHA256 of the body in hex. Verify like this:
const crypto = require('crypto'); function verifySignature(body, signature, secret) { const expected = crypto .createHmac('sha256', secret) .update(body) // body como string o Buffer .digest('hex'); return crypto.timingSafeEqual( Buffer.from(expected), Buffer.from(signature) ); } // En tu endpoint: const sig = req.headers['x-wa-signature']; if (!verifySignature(req.rawBody, sig, 'TU_SECRET')) { res.status(401).send('Firma inválida'); }
import hmac, hashlib def verify_signature(body: bytes, signature: str, secret: str) -> bool: expected = hmac.new( secret.encode(), body, hashlib.sha256 ).hexdigest() return hmac.compare_digest(expected, signature)
Mensaje entrante
Inbound message
Un contacto te ha enviado un mensaje (texto, imagen, audio, documento, etc.)
A contact has sent you a message (text, image, audio, document, etc.)
Mensaje saliente
Outbound message
Has enviado un mensaje (desde la app o desde la API).
You sent a message (from the app or via the API).
Nodo HTTP Request con header de autorización. Webhook Trigger para recibir mensajes.
HTTP Request node with auth header. Webhook Trigger to receive messages.
Acción Webhooks by Zapier (POST) para enviar. Trigger Catch Hook para recibir.
Webhooks by Zapier action (POST) to send. Catch Hook trigger to receive.
Módulo HTTP → Make a request. Custom Webhook para recibir eventos.
HTTP → Make a request module. Custom Webhook to receive events.
Cualquier lenguaje con soporte HTTP. Ejemplos abajo en Node.js y Python.
Any language with HTTP support. Examples below in Node.js and Python.
Para enviar un mensaje desde n8n, usa el nodo HTTP Request:
To send a message from n8n, use the HTTP Request node:
{
"method": "POST",
"url": "https://tudominio.com/wa-api/api/v1/send",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
// Credencial: Name = "Authorization", Value = "Bearer wam_..."
"bodyParametersJson": {
"account_id": 1,
"to": "{{ $json.phone }}",
"body": "{{ $json.message }}"
}
}
Para recibir mensajes en n8n, crea un nodo Webhook y usa la URL generada como destino del webhook en WA Manager:
To receive messages in n8n, create a Webhook node and use the generated URL as the webhook destination in WA Manager:
{{ $json.message.body }}
n8n Webhook → POST → Respond 200 immediately → Process body {{ $json.message.body }}
const WA_API_KEY = process.env.WA_API_KEY; const BASE_URL = 'https://tudominio.com/wa-api/api/v1'; async function sendWhatsApp(accountId, phone, message) { const res = await fetch(`${BASE_URL}/send`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${WA_API_KEY}`, }, body: JSON.stringify({ account_id: accountId, to: phone, body: message }), }); if (!res.ok) throw new Error(await res.text()); return res.json(); } // Uso: sendWhatsApp(1, '34612345678', 'Hola desde Node.js!') .then(r => console.log('Enviado:', r.wa_id));
from flask import Flask, request, abort import hmac, hashlib, json app = Flask(__name__) WA_SECRET = "mi_secreto_hmac" @app.route('/webhook/whatsapp', methods=['POST']) def wa_webhook(): sig = request.headers.get('X-WA-Signature', '') expected = hmac.new( WA_SECRET.encode(), request.data, hashlib.sha256 ).hexdigest() if not hmac.compare_digest(sig, expected): abort(401) data = request.get_json() msg = data['message'] print(f"Mensaje de {msg['jid']}: {msg['body']}") # Procesa aquí: guarda en BD, notifica al agente, etc. return '', 200 # ← responder siempre 200 rápido
<?php $apiKey = 'wam_TU_API_KEY'; $baseUrl = 'https://tudominio.com/wa-api/api/v1'; function sendWhatsApp($accountId, $phone, $message): array { global $apiKey, $baseUrl; $ch = curl_init("$baseUrl/send"); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer $apiKey", 'Content-Type: application/json', ], CURLOPT_POSTFIELDS => json_encode([ 'account_id' => $accountId, 'to' => $phone, 'body' => $message, ]), ]); $body = curl_exec($ch); curl_close($ch); return json_decode($body, true); } $result = sendWhatsApp(1, '34612345678', '¡Hola desde PHP!'); echo 'wa_id: ' . $result['wa_id'];
Todos los errores devuelven un objeto JSON con el campo error descriptivo. El código HTTP indica la categoría del problema.
All errors return a JSON object with a descriptive error field. The HTTP code indicates the problem category.
API key ausente, con formato incorrecto (debe empezar por wam_) o revocada.
API key missing, wrongly formatted (must start with wam_) or revoked.
Falta un campo obligatorio en el body o un parámetro de query. El mensaje de error indica cuál.
A required body field or query parameter is missing. The error message indicates which one.
La API key está restringida a una cuenta concreta y has intentado acceder a otra.
The API key is restricted to a specific account and you tried to access a different one.
La cuenta, conversación o recurso solicitado no existe o no te pertenece.
The account, conversation or requested resource does not exist or does not belong to you.
Error inesperado del servidor. Comprueba que la cuenta esté conectada y el mensaje de error del campo error.
Unexpected server error. Check that the account is connected and read the error field message.
Error al comunicarse con Meta Cloud API (solo cuentas tipo Meta). Revisa el token o el estado de tu app en Meta for Developers.
Error communicating with Meta Cloud API (Meta account type only). Check your token or app status in Meta for Developers.
{
"error": "API key no encontrada o revocada"
}
wam_?wam_?Authorization: Bearer wam_... (no olvides «Bearer »)?Authorization: Bearer wam_... header (don't forget «Bearer »)?34612345678)34612345678)/wa-api/api/v1/wa-api/api/v1
¿Necesitas ayuda con la integración?
Need help with the integration?