Contato
Português

Webhooks

Receba callbacks HTTP assinados quando os tickets mudam, a partir de gatilhos e automações, com novas tentativas e registro de entregas.

Traduzido para sua conveniência. Código, nomes de campos e a referência da API continuam em inglês. Versão em inglês

Os webhooks enviam uma requisição HTTP ao seu endpoint quando um gatilho ou uma automação é acionado. Você os cria em Admin Center, Integrations, Webhooks e depois os usa como ação em qualquer gatilho ou automação. Os corpos das requisições aceitam placeholders e seguem payloads no formato do Zendesk, então receptores feitos para webhooks do Zendesk costumam funcionar sem mudanças.

Verificar a assinatura

Toda requisição traz dois cabeçalhos:

CabeçalhoValor
X-Desk-TimestampHora Unix em segundos em que a requisição foi assinada
X-Desk-Signaturebase64(HMAC-SHA256(signing secret, timestamp + "." + raw body))

Calcule a assinatura sobre o corpo bruto da requisição, compare em tempo constante e rejeite requisições cujo timestamp tenha mais de 5 minutos.

import crypto from 'node:crypto';

export function verify(rawBody, headers, secret) {
  const ts = headers['x-desk-timestamp'];
  const sig = headers['x-desk-signature'];
  if (!ts || !sig || Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
  const expected = crypto.createHmac('sha256', secret).update(`${ts}.${rawBody}`).digest('base64');
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig));
}
function verify(string $rawBody, string $ts, string $sig, string $secret): bool
{
    if (abs(time() - (int) $ts) > 300) {
        return false;
    }
    $expected = base64_encode(hash_hmac('sha256', $ts.'.'.$rawBody, $secret, true));

    return hash_equals($expected, $sig);
}
import base64, hashlib, hmac, time

def verify(raw_body: bytes, ts: str, sig: str, secret: str) -> bool:
    if not ts or not sig or abs(time.time() - int(ts)) > 300:
        return False
    mac = hmac.new(secret.encode(), ts.encode() + b"." + raw_body, hashlib.sha256)
    expected = base64.b64encode(mac.digest()).decode()
    return hmac.compare_digest(expected, sig)

Novas tentativas

Responda com qualquer status 2xx em poucos segundos. Outras respostas e timeouts são repetidos após 1 minuto, 5 minutos, 30 minutos, 2 horas, 6 horas e 12 horas; depois disso a entrega é marcada como falha. Cada tentativa, com status e resposta, fica no registro de entregas do webhook.

Torne o seu receptor idempotente: uma entrega pode chegar mais de uma vez.

Registro de entregas e nova tentativa manual

Admin Center, Integrations, Webhooks mostra cada entrega com requisição, resposta, status e tentativas. Filtre por webhook, evento (ticket.created, trigger, automation, test etc.) e status. Replay em qualquer entrega, mesmo uma que falhou de vez, coloca na fila uma nova cópia do mesmo payload, assinada com o secret atual; a cópia fica ligada à original. O mesmo registro está na API: GET /api/webhook_deliveries?event_type=ticket.created&status=failed e POST /api/webhook_deliveries/{id}/replay.

Versão do payload

Cada entrega e cada ping trazem um inteiro version no envelope, hoje 1. Ele faz parte do contrato público: um envelope incompatível recebe um novo inteiro, fixado por webhook, e as duas versões são entregues enquanto a antiga é retirada. Leia version no seu receptor em vez de deduzir pela forma do corpo, e ignore campos que não conhece. As regras, incluindo os 12 meses de aviso antes de qualquer remoção, estão em versionamento e descontinuação.

Endereços de saída

As requisições de webhook vêm dos nossos endereços IP de saída publicados, para que você possa liberá-los no seu firewall.