Introdução

Como cadastrar endpoints e receber eventos.

Como funciona#

Você cadastra um endpoint HTTPS no painel, em Desenvolvedores → Webhooks, e escolhe quais eventos quer receber. A cada mudança de estado, enviamos um POST com o corpo ao lado e o header de assinatura.

  • Responda 2xx o mais rápido possível — de preferência antes de processar.
  • Processe de forma idempotente: o mesmo evento pode chegar duas vezes.
  • Confie no id e consulte a API se precisar do estado mais recente.
  • Nunca autorize a entrega sem validar a assinatura.

Sempre HTTPS

Endpoints em HTTP simples não são aceitos. A entrega precisa de canal cifrado.
POSTcorpo da entrega
{
  "event": "payment.paid",
  "sent_at": "2026-08-11T19:03:12Z",
  "data": {
    "id": "pay_3Kq8Zx91",
    "status": "paid",
    "amount_centavos": 12990,
    "net_centavos": 12945,
    "paid_at": "2026-08-11T19:03:11Z"
  }
}

Retentativas#

Se o seu endpoint não responder 2xx, repetimos a entrega em intervalos crescentes: 1 minuto, 5 minutos, 30 minutos, 2 horas e 6 horas. Cada tentativa fica registrada no painel, com o código de resposta que recebemos.

Você também pode reenviar manualmente uma entrega específica, tanto pelo painel quanto por POST /v1/developers/webhook-deliveries/{id}/retry.

Gerenciar endpoints pela API#

MétodoRotaO que faz
GET/v1/developers/webhook-endpointsLista os endpoints cadastrados.
POST/v1/developers/webhook-endpointsCadastra um endpoint e devolve o segredo.
PATCH/v1/developers/webhook-endpoints/{id}Altera URL ou eventos assinados.
POST/v1/developers/webhook-endpoints/{id}/rotate-secretGera um novo segredo.
GET/v1/developers/webhook-deliveriesHistórico de entregas e tentativas.
recebendo o evento
app.post("/webhooks/kyvo",
  express.raw({ type: "application/json" }),
  (req, res) => {
    const assinatura = req.header("Kyvo-Signature");
    if (!verify(req.body, assinatura, process.env.KYVO_WEBHOOK_SECRET)) {
      return res.sendStatus(401);
    }

    // responda antes de processar
    res.sendStatus(200);

    const evento = JSON.parse(req.body);
    fila.publicar(evento);
  });