Ringhum.

Desenvolvedores

Webhooks

Receba notificações HTTPS assinadas quando chamadas terminam, mensagens são anotadas, compromissos, pedidos e reservas mudam, ou uma campanha termina, e verifique que cada uma realmente veio da Ringhum.

6 min de leitura Atualizado em 24 setembro 2026

Nesta página

Um webhook envia uma requisição HTTPS ao seu servidor no momento em que algo acontece no seu workspace. Use webhooks em vez de fazer polling na API: quando uma chamada termina, você recebe o resumo, o resultado, os detalhes coletados e a transcrição imediatamente. Cada entrega é assinada com um segredo que só você e a Ringhum conhecem, para que seu servidor possa rejeitar qualquer coisa que não veio da Ringhum.

Adicione um endpoint

Somente o Proprietário e os Admins do workspace podem adicionar, testar e remover endpoints.

  1. Abra Desenvolvedores na barra lateral.
  2. No card Webhooks, clique em Adicionar endpoint.
  3. Digite a URL do endpoint. Deve começar com https://.
  4. Em Eventos, marque os eventos que você quer. call.ended já vem marcado.
  5. Clique em Adicionar endpoint.
  6. Copie o segredo de assinatura da caixa verde (começa com whsec_) e armazene-o no seu servidor. Clique em Concluído.

Importante: O segredo de assinatura é exibido apenas uma vez. Se você o perder, remova o endpoint e adicione-o novamente para obter um novo segredo.

Você pode adicionar quantos endpoints precisar. Os webhooks cobrem todo assistente no workspace. Você também pode gerenciar endpoints pela API, com POST /webhooks e uma chave que tenha o escopo de gravação.

Eventos

Evento Quando é enviado
call.started Uma chamada foi atendida por um assistente
call.ended Uma chamada terminou e foi resumida (inclui transcrição e resumo)
call.transferred Uma chamada foi transferida para uma pessoa
message.taken O assistente anotou uma mensagem
appointment.booked O assistente agendou um compromisso
appointment.rescheduled Um compromisso foi movido para um novo horário
appointment.cancelled Um compromisso foi cancelado
order.created Um pedido foi feito (por um assistente, manualmente ou pela API)
order.updated Um pedido mudou de status
order.cancelled Um pedido foi cancelado
reservation.created Um quarto foi reservado (por um assistente, manualmente ou pela API)
reservation.updated Uma reserva mudou de status (confirmada, com check-in, com check-out, não compareceu)
reservation.cancelled Uma reserva foi cancelada
campaign.completed Uma campanha ativa terminou de ligar para sua lista
test.ping Você clicou em Enviar teste

Como é uma entrega

Toda entrega é um POST com um corpo JSON e estes cabeçalhos:

POST https://example.com/hooks/ringhum
Content-Type: application/json
User-Agent: Ringhum-Webhooks/1.0
X-Ringhum-Event: call.ended
X-Ringhum-Timestamp: 1789250000
X-Ringhum-Signature: v1=5f1a…

{
  "id": "evt_8f2k…",
  "type": "call.ended",
  "created_at": "2026-09-24T14:03:11+00:00",
  "data": {
    "call_id": 4812,
    "direction": "inbound",
    "from": "+14155550132",
    "to": "+14155550100",
    "assistant_id": 3,
    "status": "completed",
    "outcome": "message_taken",
    "sentiment": "neutral",
    "duration_seconds": 94,
    "summary": "Caller asked for a quote for a kitchen repair…",
    "extracted": { "name": "Dana Lee", "reason": "Quote" },
    "transcript": [
      { "role": "assistant", "content": "Hello, you've reached…" },
      { "role": "user", "content": "Hi, I'd like a quote…" }
    ]
  }
}

O objeto data depende do evento:

  • call.ended e message.taken: os campos de chamada acima.
  • call.started e call.transferred: call_id, direction, from, to, assistant_id, status e started_at.
  • appointment.*: appointment_id, title, status, starts_at, ends_at, timezone, customer (nome, telefone, e-mail), contact_id, service, staff, call_id e notes.
  • order.*: order_id, number, status, fulfillment, customer, address, items com opções e preços, currency, subtotal, fee, total, source, call_id e, para cancelamentos, cancel_reason.
  • reservation.*: reservation_id, number, status, room, check_in, check_out, nights, adults, children, guest, currency, nightly, total e source.
  • campaign.completed: campaign_id, name e os números de progresso da campanha.

Nota: Quando o assistente agenda um compromisso durante uma chamada, você pode receber appointment.booked duas vezes. Uma é enviada assim que o agendamento é feito, com os campos do compromisso. A outra é enviada depois que a chamada é resumida, com os campos da chamada. Verifique se data tem appointment_id ou call_id e use o campo id para evitar processar uma entrega duas vezes.

Verifique a assinatura

A assinatura é um HMAC-SHA256 do timestamp, um ponto, e o corpo bruto da requisição, usando o segredo de assinatura do seu endpoint como chave. Ela é enviada como v1= seguido do resumo em hexadecimal.

  1. Leia o corpo bruto exatamente como recebido, antes de qualquer parsing de JSON.
  2. Construa a string {X-Ringhum-Timestamp}.{corpo bruto}.
  3. Calcule o HMAC-SHA256 com seu segredo e prefixe-o com v1=.
  4. Compare-o com X-Ringhum-Signature usando uma comparação de tempo constante.
  5. Rejeite a requisição se o timestamp tiver mais de cinco minutos, para bloquear requisições reenviadas.

Node.js:

const crypto = require('crypto');

function isValid(req, rawBody, secret) {
  const ts = req.header('X-Ringhum-Timestamp');
  const sig = req.header('X-Ringhum-Signature') || '';
  const expected = 'v1=' + crypto.createHmac('sha256', secret).update(`${ts}.${rawBody}`).digest('hex');
  const fresh = Math.abs(Date.now() / 1000 - Number(ts)) < 300;
  return fresh && sig.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
}

PHP:

$ts = $_SERVER['HTTP_X_RINGHUM_TIMESTAMP'] ?? '';
$sig = $_SERVER['HTTP_X_RINGHUM_SIGNATURE'] ?? '';
$expected = 'v1=' . hash_hmac('sha256', $ts . '.' . file_get_contents('php://input'), $secret);
if (! hash_equals($expected, $sig) || abs(time() - (int) $ts) > 300) {
    http_response_code(400);
    exit;
}

Respostas, tempos limite e novas tentativas

  • Responda com qualquer status 2xx para confirmar a entrega. Faça trabalho demorado depois de responder.
  • A Ringhum espera até 10 segundos pela sua resposta.
  • Se seu endpoint não responder com 2xx, a entrega é tentada até 3 vezes no total: imediatamente, novamente depois de cerca de 10 segundos, e uma última vez cerca de 60 segundos depois. Depois disso é descartada.
  • As entregas podem chegar fora de ordem. Use created_at e os ids em data para colocá-las em ordem.

A tabela Webhooks mostra o último status HTTP de cada endpoint e quando foi enviado. Um endpoint com falha continua ativo; a Ringhum não o desativa por você.

Teste, pause e remova

  • Enviar teste envia um evento test.ping imediatamente, e uma mensagem mostra o status HTTP que seu endpoint retornou.
  • O botão Ativo pausa um endpoint. Eventos que acontecem enquanto ele está desativado não são enviados depois.
  • Remover exclui o endpoint e seu segredo.

Perguntas comuns

Qual é a diferença em relação aos apps Zapier, Make e n8n em Integrações? Essas conexões usam a página Integrações e seus seis tipos de evento. O corpo delas é {"event", "workspace", "sent_at", "data"}, e quando você define um segredo, o cabeçalho de assinatura é X-Ringhum-Signature: sha256=…, um HMAC-SHA256 apenas do corpo. Os webhooks de desenvolvedor, descritos aqui, cobrem mais eventos e usam a assinatura v1= com um timestamp. Veja Escolhendo o que é enviado.

Meu endpoint retorna 2xx, mas meu código não vê nada. Verifique se o evento está marcado para esse endpoint, se o endpoint está ativo, e se seu firewall permite requisições da internet.

Por que a verificação de assinatura falha? Na maioria das vezes o corpo foi analisado e recodificado antes do hash. Faça o hash dos bytes brutos exatamente como recebidos.

Ainda com dúvidas?

Envie um e-mail para [email protected] ou mande uma mensagem. Os planos Team e Scale têm suporte prioritário.

Contatar suporte