Webhooks v1

Recibe eventos de WhatsApp en tu sistema.

Cada vez que pasa algo en un canal (mensaje entrante, status de delivery, asignación, cierre de conversación) smarttalkapp dispara un POST firmado HMAC-SHA256 al endpoint que registres. At-least-once delivery con reintentos exponenciales.

01

Registrar un endpoint

Ve a Settings → Integraciones → Webhooks → Add endpoint y guarda:

  • URL: HTTPS pública (no localhost; usa ngrok o cloudflared en dev).
  • Events: selección granular (o * para todos).
  • Secret: string aleatorio que se usará para firmar los payloads.
02

Verificación de firma

Cada POST incluye X-Smarttalk-Signature: sha256=<base64> y X-Smarttalk-Delivery: <uuid>. Calcula HMAC-SHA256 del body raw con tu secret y compara constant-time:

javascript
import crypto from "node:crypto"; export function verifyWebhook(rawBody: string, signature: string, secret: string) { const expected = "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("base64"); return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature)); }

Idempotencia

smarttalkapp reintenta con backoff exponencial hasta 5 veces si tu endpoint devuelve 5xx o timeout. Usa X-Smarttalk-Delivery para deduplicar — guárdalo y rechaza duplicados (e.g. clave única en BD).
03

Eventos

message.incoming

Un contacto envía un mensaje a tu número.

Expandir

Un contacto envía un mensaje a tu número.

json
{ "event": "message.incoming", "delivery_id": "uuid", "occurred_at": "2026-05-19T05:13:19.570Z", "channel_id": "uuid", "organization_id": "uuid", "data": { "message_id": "uuid", "wa_message_id": "wamid.HBg...", "conversation_id": "uuid", "contact": { "id": "uuid", "wa_id": "573108760539", "name": "Diana" }, "content": { "type": "text", "text": "Hola" } } }
message.outgoing

Tu API / agente envía un mensaje (incluye reply manual o automatizado).

Expandir

Tu API / agente envía un mensaje (incluye reply manual o automatizado).

json
{ "event": "message.outgoing", "data": { ... mismo shape ... } }
message.status

Meta confirma sent / delivered / read / failed.

Expandir

Meta confirma sent / delivered / read / failed.

json
{ "event": "message.status", "data": { "wa_message_id": "wamid...", "status": "delivered", "timestamp": "..." } }
contact.created

Un número nunca antes visto contacta tu canal (o llega por auto-create de /messages/text).

Expandir

Un número nunca antes visto contacta tu canal (o llega por auto-create de /messages/text).

json
{ "event": "contact.created", "data": { "contact": { "id", "wa_id", "name" } } }
contact.updated

Cambia el lifecycle, tags o asignee de un contacto.

Expandir

Cambia el lifecycle, tags o asignee de un contacto.

json
{ "event": "contact.updated", "data": { "contact": {...}, "changes": ["lifecycle"] } }
conversation.opened

Se crea una nueva conversación.

Expandir

Se crea una nueva conversación.

json
{ "event": "conversation.opened", "data": { "conversation": {...} } }
conversation.closed

Una conversación pasa a status closed/resolved (manual o por auto-snooze).

Expandir

Una conversación pasa a status closed/resolved (manual o por auto-snooze).

json
{ "event": "conversation.closed", "data": { "conversation": {...}, "reason": "..." } }
conversation.assignee_updated

Un agente toma una conversación o se la reasignan.

Expandir

Un agente toma una conversación o se la reasignan.

json
{ "event": "conversation.assignee_updated", "data": { "conversation_id", "from", "to" } }
04

Confiabilidad

  • At-least-once delivery. Diseña tu handler como idempotent.
  • Retries: 30s, 5min, 30min, 2h, 6h. Después → dead-letter queue interna.
  • Timeouts: 10s por POST. Si esperas processing más largo, devuelve 202 inmediato y procesa async.
  • Replay: desde Settings → Integraciones → Webhooks puedes re-enviar cualquier evento del último mes.