Webhooks: receber eventos em tempo real

Receba na sua URL, em tempo real, os eventos do WhatsApp e os comentários e DMs do Instagram, confira a assinatura e entenda as novas tentativas.

Atualizado em

Com o escopo Receber eventos (comentários e DMs) por webhook (webhooks:manage), você cadastra uma URL do seu sistema e a XBASE manda para ela, em tempo real, os comentários e as DMs que chegam às contas do Instagram do workspace.

Cadastrar o webhook

PUT https://api.xbase.app/api/external/v1/webhook
curl -X PUT https://api.xbase.app/api/external/v1/webhook \
  -H "Authorization: Bearer $XBASE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://meusistema.com/xbase/webhook", "events": ["instagram.comment", "instagram.message"] }'

Resposta 200:

{
  "url": "https://meusistema.com/xbase/webhook",
  "events": ["instagram.comment", "instagram.message"],
  "secretLast4": "Q2w9",
  "updatedAt": "2026-11-04T16:10:00.000Z",
  "secret": "whsec_…"
}

O secret aparece só nesta resposta: guarde-o para conferir a assinatura. Cada chave tem um webhook. Chamar o PUT de novo troca a URL e os eventos e gera um segredo novo.

A URL tem de ser https e pública.

Consultar e desligar

  • GET /webhook devolve a URL, os eventos, os 4 últimos caracteres do segredo (secretLast4) e updatedAt. Sem webhook cadastrado, responde 200 com o corpo vazio.
  • DELETE /webhook desliga o webhook e responde 204, sem corpo.
  • Revogar a chave também desliga o webhook dela.

Eventos

EventoQuando
instagram.commentAlguém comenta num post de uma conta do workspace
instagram.messageChega uma DM a uma conta do workspace

Cada entrega é um POST na sua URL:

POST https://meusistema.com/xbase/webhook
Content-Type: application/json
x-xbase-Signature: t=1793808600,v1=5d41402abc4b2a76b9719d911017c592…
x-xbase-Delivery: 0b9f7c1e-…
x-xbase-Event: instagram.comment
{
  "id": "0b9f7c1e-…",
  "type": "instagram.comment",
  "occurredAt": "2026-11-04T16:10:00Z",
  "workspaceId": "8f0c2d4e-…",
  "account": { "connectionId": "6d1f…", "instagramAccountId": "1784…", "username": "minhaempresa" },
  "comment": {
    "id": "17900000000000000",
    "text": "Quanto custa?",
    "mediaId": "18010000000000000",
    "parentId": null,
    "from": { "id": "…", "username": "fulano" }
  }
}

No evento instagram.message, no lugar de comment vem message: { "mid", "text", "isEcho", "from": { "id" }, "attachments": [{ "type", "url" }] }.

O webhook da chave manda os eventos do Instagram. Os do WhatsApp saem pelos webhooks do workspace.

Webhooks do workspace: WhatsApp e Instagram

Para receber os eventos do WhatsApp, cadastre o webhook em Integrações → Webhooks (ou pelas ferramentas create-webhook e update-webhook do MCP). Precisa da permissão de gerenciar integrações. São até 10 webhooks por workspace, e cada um escolhe:

  • Números: todos os números de WhatsApp do workspace ou só os escolhidos.
  • Eventos, da tabela abaixo.
  • Formato: XBASE (padrão) ou Gupshup (compatível), os dois assinados.
EventoQuando
whatsapp.message.receivedChega uma mensagem a um número do workspace
whatsapp.message.sent · .delivered · .read · .failedUma mensagem enviada muda de status
whatsapp.message.enqueuedO provedor aceitou a mensagem (só números Gupshup)
whatsapp.billingCobrança da conversa (só números Gupshup)
whatsapp.systemEventos de sistema e do usuário (só números Gupshup)
instagram.comment · instagram.messageOs mesmos desta página

No formato XBASE, a entrega usa os mesmos cabeçalhos, a mesma assinatura e as mesmas novas tentativas desta página. O corpo traz o número e, em payload, o evento como o provedor mandou:

{
  "id": "3c2a…",
  "type": "whatsapp.message.delivered",
  "occurredAt": "2026-11-04T16:10:00Z",
  "workspaceId": "8f0c2d4e-…",
  "connection": { "id": "6d1f…", "provider": "GUPSHUP", "appName": "minhaempresa", "number": "5511999990000" },
  "payload": { "…": "evento do provedor" }
}

O formato Gupshup serve a integrações que já recebiam os eventos da Gupshup: o corpo é { "data": <evento da Gupshup> } e vale só para números Gupshup, sem a cobrança e sem o Instagram.

O segredo de assinatura aparece uma vez, na tela, logo depois de criar. A mesma entrega pode chegar mais de uma vez: ignore as repetidas pelo id do evento (payload.id na Gupshup, id do item na Meta).

Conferir a assinatura

O cabeçalho x-xbase-Signature tem o horário (t, em segundos) e a assinatura (v1): o HMAC-SHA256, em hexadecimal, de "<t>.<corpo>" com o seu secret. Recuse a entrega se a assinatura não bater ou se t tiver mais de 5 minutos. Exemplo em Node.js:

import { createHmac, timingSafeEqual } from 'node:crypto';

// rawBody: o corpo exatamente como chegou, antes de qualquer JSON.parse.
function isValidSignature(rawBody, header, secret) {
  const { t, v1 } = Object.fromEntries(header.split(',').map((part) => part.split('=')));
  if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false; // até 5 minutos
  const expected = createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
  return v1.length === expected.length && timingSafeEqual(Buffer.from(v1), Buffer.from(expected));
}

Entrega e novas tentativas

  • A entrega conta como feita quando a sua URL responde 2xx em até 10 segundos. Responda rápido e processe depois.
  • Sem 2xx, a XBASE tenta de novo mais 5 vezes: depois de 1 minuto, 5 minutos, 30 minutos, 2 horas e 6 horas. Depois disso, desiste.
  • A mesma entrega pode chegar mais de uma vez. Ignore as repetidas pelo x-xbase-Delivery, ou pelo comment.id e pelo message.mid.

Perguntas frequentes

Veja também

Nesta página