Conceitos

Receber eventos por webhook

Um webhook envia eventos JSON por POST à URL que você configura na aplicação. Use os eventos para atualizar seu sistema e o histórico do painel para diagnosticar falhas no receptor.

Nesta página

Configure o receptor na aplicação

No painel, abra Aplicações → sua aplicação → Webhook e informe a URL e o token do seu receptor.

ConfiguraçãoRegra
URLHTTPS, sem usuário ou senha na URL, com destino público. Endereços locais ou privados são rejeitados; redirecionamentos não são seguidos.
TokenDe 16 a 200 caracteres ASCII visíveis, sem espaços. Guarde o mesmo valor no servidor receptor.
EventosEscolha ao menos um dos seis eventos abaixo. A aplicação começa com todos selecionados.
Incluir o códigoDesligado por padrão. Inclui code apenas em send.sent, enquanto o código estiver válido.

O token nunca aparece nas respostas ou no histórico. Ao editar, deixe o campo vazio para preservar o valor salvo. Na configuração JSON, omita token para preservá-lo; token_set informa se existe um token salvo.

Salvar outra configuração, remover o webhook ou revogar a aplicação interrompe as entregas pendentes da configuração anterior.

Eventos disponíveis

Você recebe somente os eventos selecionados para a aplicação:

EventoQuando ocorre
send.sentO canal aceitou a mensagem. SMS e e-mail podem encerrar a entrega e a cobrança nesse estado, sem recibo de entrega.
send.deliveredO canal confirmou a entrega, quando esse recibo está disponível.
send.readO canal confirmou a leitura, quando esse recibo está disponível.
send.failedO envio encerrou com falha após as alternativas de entrega.
send.verifiedO código foi verificado com sucesso.
send.expiredUm código pendente atingiu o prazo de validade.

Os estados de entrega e verificação são independentes. Nem todo canal fornece confirmação de entrega ou leitura.

Valide os cabeçalhos antes de processar

Cada POST leva estes cabeçalhos:

HTTP
Content-Type: application/json
Aut2fa-Token: seu_token_privado_do_webhook
Aut2fa-Event: send.delivered
Aut2fa-Delivery: whd_01m4prwckhd0kyjgv5vw8a5wjr

Compare Aut2fa-Token com o token guardado no seu servidor antes de confiar no corpo. A autenticação usa o próprio token, sem assinatura HMAC.

Aut2fa-Event corresponde a type no JSON. Aut2fa-Delivery identifica a entrega de evento e permanece igual nas retentativas.

No Node.js, esta função compara os bytes sem revelar o ponto da divergência:

JavaScript
import { timingSafeEqual } from "node:crypto";

export function validWebhookToken(received, expected) {
  if (typeof received !== "string" || !expected) return false;
  const receivedBytes = Buffer.from(received);
  const expectedBytes = Buffer.from(expected);
  return receivedBytes.length === expectedBytes.length
    && timingSafeEqual(receivedBytes, expectedBytes);
}

Passe o cabeçalho recebido e process.env.AUT2FA_WEBHOOK_TOKEN à função. Rejeite requisições sem token válido e evite registrar tokens e códigos em logs.

Corpo JSON do evento

O exemplo descreve uma confirmação de entrega com dados sintéticos:

JSON
{
  "type": "send.delivered",
  "created_at": "2026-10-12T14:02:13Z",
  "data": {
    "id": "snd_01m4prwckhd0kyjgv5vw8a5wjr",
    "application_id": "app_01m4prwckhd0kyjgv5vw8a5wjr",
    "to": "+5500000000000",
    "channel": "whatsapp",
    "from": null,
    "status": "delivered",
    "verification": "pending",
    "expires_at": "2026-10-12T14:12:13Z"
  }
}
CampoSignificado
typeUm dos seis eventos selecionáveis.
created_atData e hora do evento em RFC 3339.
data.idID do envio OTP. Use em status e verificação.
data.application_idAplicação que criou o envio.
data.toDestino completo normalizado. Trate esse dado pessoal no seu servidor.
data.channelCanal real ou planejado na simulação: whatsapp, sms ou email. null antes do roteamento.
data.fromRemetente usado, ou null enquanto não estiver definido.
data.statusEstado da entrega no momento do evento.
data.verificationEstado da verificação no momento do evento.
data.expires_atPrazo de validade do código em RFC 3339.
data.codeOpcional, apenas em send.sent com inclusão habilitada e código válido.
testtrue somente no teste manual com dados sintéticos.

O código não fica no JSON persistido do evento nem no histórico. Em uma retentativa depois da validade, code será omitido.

Confirme o recebimento e evite duplicatas

Responda com HTTP 2xx após guardar o evento de forma durável. Você pode processar a operação na sua própria fila depois desse aceite.

A requisição tem prazo total de 10 segundos. Falha de rede, timeout ou resposta fora de 2xx permite outra tentativa; respostas 3xx não redirecionam.

Guarde Aut2fa-Delivery com uma restrição de unicidade. Ao receber novamente um ID já aceito, confirme com 2xx sem repetir a operação.

Uma falha de conexão pode acontecer depois que seu servidor processou o evento. Os eventos também podem chegar fora de ordem; consulte o status atual do envio quando precisar reconciliar estados.

Prazos das retentativas

Uma entrega automática tem até seis tentativas: a original e cinco retentativas. Cada intervalo começa após a falha anterior:

TentativaIntervalo após a falha anterior
1Sem espera programada.
210 segundos.
31 minuto.
45 minutos.
530 minutos.
62 horas.

Depois de um 2xx, não há nova tentativa programada. Depois da sexta falha, a entrega encerra. Os prazos indicam o agendamento; a execução depende do processamento da fila.

Teste o receptor pelo painel

Salve a configuração e clique em Enviar evento de teste. O painel executa um POST real ao receptor e mostra o status HTTP recebido.

O teste usa o primeiro evento selecionado, test: true e um ID snd_test_…. O canal é o primeiro permitido na aplicação. Para e-mail, o destino sintético é [email protected]; para telefone, +5500000000000. O prazo sintético é de dez minutos.

O teste manual tem attempt: 1 e max_attempts: 1, sem retentativas automáticas. Ele não cria um envio OTP, não entrega uma mensagem ao destinatário e não cobra a conta.

Aplicações no modo test também podem enviar eventos ao webhook durante a simulação. No callback, data.channel informa o canal planejado: e-mail para esse destino ou o primeiro canal da rota para telefone. A API de envio e status continua retornando channel: sandbox. O campo test: true distingue o botão de teste manual.

Consulte o histórico de entregas

Abra Aplicações → sua aplicação → Entregas para consultar as últimas 50 entregas de eventos. Cada linha tem um ID único e mostra a tentativa mais recente:

CampoUso
idMesmo identificador de Aut2fa-Delivery, preservado nas retentativas.
eventTipo do evento entregue.
status_codeHTTP do receptor ou null se não houve resposta.
attempt / max_attemptsTentativa mais recente e limite da entrega.
duration_msDuração da tentativa em milissegundos, quando disponível.
errorFalha da tentativa ou null no sucesso.
next_attempt_atPróximo agendamento ou null quando não há outra tentativa prevista.
created_atQuando a entrega de evento foi criada.

As retentativas atualizam a mesma linha. O histórico contém metadados da entrega; nunca inclui o token, o código ou o corpo do evento.

Contrato de configuração do painel

Estas rotas exigem uma sessão autenticada no painel e acesso à aplicação. A chave ak_live_… ou ak_test_… da API de envios não autentica essas operações:

MétodoCaminhoResposta
PUT/v1/panel/applications/{id}/webhook200: aplicação completa com webhook aninhado.
DELETE/v1/panel/applications/{id}/webhook204: sem corpo.
POST/v1/panel/applications/{id}/webhook/test201: { delivery }, com o resultado da tentativa executada.
GET/v1/panel/applications/{id}/webhook/deliveries200: { data: Delivery[] }, limitado às 50 entregas mais recentes.

O corpo do PUT recebe url, events, include_code e token opcional após o primeiro cadastro. A resposta da aplicação sempre inclui webhook com url, events, include_code e token_set.

Antes da configuração, url é null, todos os eventos estão selecionados e os dois campos booleanos são false. Consulte o OpenAPI para o contrato do POST recebido pelo seu servidor.

Abrir painel da aut2fa

Buscar na documentação

Digite uma palavra para procurar nos guias e na API.

Use as setas para percorrer os resultados. Enter abre a página. Esc fecha a busca.