Autenticación por API Key, envío de mensajes y webhooks entrantes.
Todas las rutas públicas de cliente usan el prefijo /api/v1.
http://localhost:3000/api/v1
Usa tu API Key (visible en el panel) en cada request:
X-API-Key: wht_tu_api_key_aqui
También se acepta Authorization: Bearer wht_....
GET/sessions — Lista tus números conectados.
curl -X GET http://localhost:3000/api/v1/sessions \ -H "X-API-Key: wht_..."
{
"sessions": [
{
"session_key": "sess_abc123",
"name": "Ventas",
"phone_number": "51999999999",
"status": "connected",
"webhook_url": "https://tu.app/webhook",
"connected_at": "2026-07-28T15:00:00.000Z"
}
]
}
GET/sessions/:session_key — Detalle / estado de una sesión.
PUT/sessions/:session_key/webhook — Configura el webhook.
curl -X PUT http://localhost:3000/api/v1/sessions/sess_abc123/webhook \
-H "X-API-Key: wht_..." \
-H "Content-Type: application/json" \
-d '{"webhook_url":"https://tu-servidor.com/whatsapp/webhook"}'
POST/messages/send
Body JSON:
session_key — ID de la sesión (del panel)to — número destino con código de país, sin + (ej. 51987654321)message — texto a enviarcurl -X POST http://localhost:3000/api/v1/messages/send \
-H "X-API-Key: wht_..." \
-H "Content-Type: application/json" \
-d '{
"session_key": "sess_abc123",
"to": "51987654321",
"message": "Hola, tu pedido está listo"
}'
{
"success": true,
"message": {
"id": 42,
"wa_message_id": "3EB0XXXX",
"to": "51987654321",
"body": "Hola, tu pedido está listo",
"status": "sent"
}
}
La sesión debe estar en estado connected. Si no, recibirás HTTP 409.
Equivalente a Ultramsg /contacts/check: comprueba si un número tiene WhatsApp
antes de enviar.
GET / POST/contacts/check
session_key — sesión conectadachatId o phone — número con código de país (ej. 51987654321)curl "http://localhost:3000/api/v1/contacts/check?session_key=sess_abc123&chatId=51987654321" \ -H "X-API-Key: wht_..."
curl -X POST http://localhost:3000/api/v1/contacts/check \
-H "X-API-Key: wht_..." \
-H "Content-Type: application/json" \
-d '{
"session_key": "sess_abc123",
"chatId": "51987654321"
}'
{
"status": "valid",
"exists": true,
"phone": "51987654321",
"jid": "51987654321@s.whatsapp.net",
"session_key": "sess_abc123"
}
Si no tiene WhatsApp: "status": "invalid", "exists": false.
Úsalo con moderación: no está pensado para validar listas masivas.
Cuando alguien escribe a tu número conectado, WHT hace un
POST a tu webhook_url con este JSON:
{
"event": "message.received",
"session_key": "sess_abc123",
"session_name": "Ventas",
"phone_number": "51999999999",
"message": {
"id": 100,
"wa_message_id": "3EB0YYYY",
"from": "51987654321",
"to": "51999999999",
"type": "text",
"body": "Hola, quiero info",
"push_name": "Cliente",
"timestamp": 1722170000
}
}
Headers que enviamos:
Content-Type: application/jsonX-WHT-Event: message.receivedX-WHT-Session: sess_abc123Responde con HTTP 2xx para marcar la entrega como exitosa. Timeout: 10s.
Ejemplo mínimo en Node/Express:
app.post('/whatsapp/webhook', (req, res) => {
const { event, message, session_key } = req.body;
if (event === 'message.received') {
console.log(session_key, message.from, message.body);
// Aquí tu lógica de chatbot / notificaciones
}
res.sendStatus(200);
});
401 — API Key inválida o ausente404 — Sesión no encontrada (o no te pertenece)409 — Sesión no conectada400 — Body inválido{ "error": "Session is not connected" }
POST /messages/send.Chatbot eco (pseudo):
// Al recibir webhook message.received:
await fetch('http://localhost:3000/api/v1/messages/send', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': process.env.WHT_API_KEY
},
body: JSON.stringify({
session_key: payload.session_key,
to: payload.message.from,
message: 'Recibí: ' + payload.message.body
})
});