Webhooks

Recibir eventos firmados en tu servidor, con reintentos y verificación HMAC.

Antes de empezar

  • Un endpoint HTTPS público
  • Un webhook creado en Configuración, Desarrolladores

Tinkay envía un POST con Content-Type: application/json cada vez que ocurre un evento al que te suscribiste. Hay 126 eventos disponibles: mirá la referencia completa.

Tu endpoint tiene que responder un 2xx dentro de 10 segundos. Todo lo que tarde más se considera una falla y entra en la cola de reintentos.

Respondé 200 apenas recibís el evento y hacé el trabajo pesado en una cola. Es la diferencia entre una integración estable y una que se cae en los picos.

Crear el webhook

  1. Entrá a Configuración, Desarrolladores, Webhooks y tocá Nuevo webhook.
  2. Pegá la URL HTTPS de tu endpoint.
  3. Elegí los eventos. Podés seleccionar un grupo entero o suscribirte a todos con *.
  4. Guardá y copiá el signing secret (whsec_...). Se muestra una sola vez.
  5. Tocá Enviar prueba para confirmar que tu endpoint responde.

Formato de la entrega

Cada entrega trae los headers de identificación y firma, y el evento completo en el cuerpo.

Headers de la entrega

CampoTipoDescripción
X-Tinkay-EventstringNombre del evento.
X-Tinkay-DeliverystringIdentificador de la entrega. Cambia en cada reintento.
X-Tinkay-AttemptnumberNúmero de intento, empezando en 1.
X-Tinkay-TimestampnumberEpoch en segundos usado para firmar.
X-Tinkay-Signaturestringsha256= seguido del HMAC en hexadecimal.
POST /hooks/tinkay HTTP/1.1Content-Type: application/jsonUser-Agent: Tinkay-Webhooks/1.0X-Tinkay-Event: conversation.createdX-Tinkay-Delivery: dlv_7c1a93f0X-Tinkay-Attempt: 1X-Tinkay-Timestamp: 1772668800X-Tinkay-Signature: sha256=9f2ab7c41d0e83ba5c1904e6f8b2d7a3c5e1f0d9b8a7c6e5d4f3a2b1c0d9e8f7

Un endpoint mínimo

Este ejemplo valida la firma, responde rápido y encola el trabajo real.

webhooks.js
import express from "express";import crypto from "node:crypto";const app = express();const SECRET = process.env.TINKAY_WEBHOOK_SECRET;// El cuerpo crudo es obligatorio: JSON.stringify cambia bytes y rompe la firma.app.post("/hooks/tinkay", express.raw({ type: "application/json" }), (req, res) => {  if (!verify(req)) return res.status(400).send("invalid signature");  const event = JSON.parse(req.body.toString("utf8"));  res.sendStatus(200);          // responder primero  queue.push(event);            // procesar después});function verify(req) {  const timestamp = req.get("X-Tinkay-Timestamp");  const signature = (req.get("X-Tinkay-Signature") || "").replace("sha256=", "");  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;  const expected = crypto    .createHmac("sha256", SECRET)    .update(`${timestamp}.${req.body.toString("utf8")}`)    .digest("hex");  const a = Buffer.from(expected, "hex");  const b = Buffer.from(signature, "hex");  return a.length === b.length && crypto.timingSafeEqual(a, b);}

Qué eventos elegir

De los 126 eventos, 80 sirven además como disparadores de automatizaciones dentro de Tinkay. Si lo que querés hacer es asignar, etiquetar o responder, conviene una automatización antes que un webhook.

Suscribite solo a lo que vas a procesar: cada evento extra es tráfico y latencia en tu servidor.

  • Sincronizar un CRM: contact.created, contact.updated, contact.merged, contact.deleted.
  • Alertas internas: ai.handoff, conversation.sla_breached, channel.error, invoice.payment_failed.
  • Data warehouse: conversation.closed, conversation.rated, ai.replied, ticket.resolved.
  • Cumplimiento: login.failed, api_key.revoked, member.role_changed, team.permissions_changed.

Probar en desarrollo

Exponé tu servidor local con un túnel y usá Enviar prueba en Configuración, Desarrolladores. Podés elegir cualquier evento del catálogo y recibirlo con datos realistas.

Terminal
ngrok http 3000# usá la URL https que te da como destino del webhook

Cómo saber que quedó bien

  • El endpoint responde 200 al botón `Enviar prueba`.
  • La firma calculada coincide con el header `X-Tinkay-Signature`.
  • Un evento real, por ejemplo cerrar una conversación, llega en menos de un segundo.