Webhooks
Você cadastra uma URL HTTPS e recebe um POST a cada evento. A entrega é assinada, tenta 9 vezes em cerca de 5 horas e é por conta: um endpoint lento seu não atrasa ninguém.
Cadastrar #
PUT /v2/ex/webhook
Escopo: ex.webhook.write.
PUT /v2/ex/webhook
{
"url": "https://loja.exemplo.com/webhooks/pix",
"tiposHabilitados": ["*"],
"urlsPorFamilia": {
"payout": "https://loja.exemplo.com/webhooks/saques"
}
}
→ 200
{
"url": "https://loja.exemplo.com/webhooks/pix",
"tiposHabilitados": ["*"],
"urlsPorFamilia": {
"payout": "https://loja.exemplo.com/webhooks/saques"
},
"ativo": true,
"atualizadoEm": "2026-09-18T12:00:00Z"
}
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
url |
string | sim | HTTPS público. Recebe tudo que não tem desvio. |
tiposHabilitados |
lista | sim | ["*"] para todos, ou os tipos que você quer. |
urlsPorFamilia |
objeto | não | Desvio por família. A família é o primeiro segmento do tipo, e GET /v2/ex/webhook/familias lista as aceitas. |
O PUT descreve o estado final: omitir urlsPorFamilia apaga os desvios. GET /v2/ex/webhook lê a configuração, DELETE /v2/ex/webhook desativa a entrega e GET /v2/ex/webhook/familias lista as famílias aceitas.
O envelope #
Todo evento chega com este corpo. Responda 2xx em até 10 segundos e processe depois.
{
"eventoId": "01J1ZK7M9QW3ERT5TY6UI8OP0A",
"tipo": "pix.creditado",
"criadoEm": "2026-09-18T12:00:07.412Z",
"sequencia": 3,
"correlationId": "01M2SX29NP95HKN0W06DDFPZFG",
"dados": {
"endToEndId": "E12345678202609181200000000000001",
"txid": "FIN02J1ZK7M9QW3ERT5TY6UI8O",
"valor": "150.00",
"situacaoFundos": "CREDITADO",
"pagador": { "cpf": "12345678909", "nome": "Fulano de Tal", "ispb": "60746948" },
"instrumento": "PIX",
"horario": { "liquidacao": "2026-09-18T12:00:07.001Z" }
}
}
| Campo | Tipo | Descrição |
|---|---|---|
eventoId |
string | Único. Descarte repetidos por ele: a entrega é ao menos uma vez. |
sequencia |
inteiro | Cresce por recurso (txid, idEnvio). A ordem entre recursos diferentes não é garantida. |
dados |
objeto | O conteúdo do evento. As chaves variam por tipo. |
A assinatura #
Cada entrega traz o cabeçalho x-jws-signature com uma JWS destacada ES256 sobre o corpo. A chave pública está em GET /.well-known/jwks.json. Verifique antes de confiar no corpo.
Eventos #
| Tipo | Quando |
|---|---|
pix.recebido |
O Pix liquidou. Ainda não é saldo. |
pix.creditado |
O dinheiro virou saldo. Credite o seu cliente aqui. |
pix.retido |
O Pix entrou e ficou bloqueado. |
cob.pagamento_rejeitado |
O pagamento foi recusado antes de entrar. |
cob.atualizada |
A cobrança foi alterada ou cancelada. |
devolucao.criada |
Uma devolução saiu, sua ou nossa. motivo diz qual. |
devolucao.concluida |
A devolução liquidou. |
devolucao.nao_realizada |
A devolução foi recusada pelo banco do pagador. |
payout.em_processamento |
O saque saiu do disponível. |
payout.realizado |
O saque liquidou. endToEndId é o definitivo. |
payout.nao_realizado |
O saque foi recusado. O valor voltou ao disponível. |
payout.devolucao_recebida |
O banco do favorecido devolveu um saque já realizado. |
payout.sla.em_risco |
Faltam 30 minutos para o prazo do saque. |
payout.sla.estourado |
O prazo do saque venceu com ele em curso. |
favorecido.criado |
Alguém cadastrou no painel um destino para saques. Ele só vale em 24 h. Se você não reconhece, remova. |
favorecido.removido |
O destino saiu da lista. |
saldo.bloqueado |
Parte do saldo foi retida. |
saldo.desbloqueado |
A retenção acabou. |
subconta.atualizada |
Uma sub-conta mudou de status. |
conta.status_alterado |
A sua conta mudou de status. |
conta.segmento_alterado |
A instituição reclassificou a sua conta. Releia GET /v2/ex/config. |
split.executado |
Um recebimento foi repartido. |
split.revertido |
Uma devolução ou contestação desfez a repartição. |
tarifa.cobrada |
A tarifa foi descontada do crédito. valor e referencia. |
webhook.teste |
Disparado por POST /v2/ex/webhook/teste. |
Saúde da fila #
GET /v2/ex/webhook/saude
Escopo: ex.webhook.read.
GET /v2/ex/webhook/saude
→ 200
{
"situacao": "OK",
"entregues": 0,
"emBackoff": 0,
"desistidas": 0,
"janelaHoras": 24
}
situacao é OK, ATENCAO ou FALHANDO. Em FALHANDO vêm motivo e ultimaFalha. Entregas desistidas não saem mais sozinhas: conserte o endpoint e peça o reenvio.
Reenvio #
POST /v2/ex/webhook/reenvios
POST /v2/ex/webhook/reenvios
{
"tipos": ["pix.creditado"],
"inicio": "2026-09-17T12:00:00Z",
"fim": "2026-09-18T12:00:00Z",
"dryRun": true
}
→ 202
{
"idReenvio": "01M2SX3Q56B91Y7HDH49X0QQH5",
"status": "CONCLUIDO",
"total": 0,
"enfileirados": 0,
"dryRun": true
}
dryRun: true só conta. GET /v2/ex/webhook/reenvios/{id} acompanha um reenvio, GET /v2/ex/webhook/entregas lista as tentativas com status HTTP e latência, e GET /v2/ex/eventos é o feed dos mesmos envelopes, com cursor, para reconciliar.
Erros #
| Status | title |
Quando |
|---|---|---|
| 400 | url_invalida |
A URL não é HTTPS válido. |
| 400 | url_privada |
A URL aponta para rede privada ou localhost. |
| 400 | familia_desconhecida |
urlsPorFamilia cita uma família que não existe. |
| 409 | reenvio_em_andamento |
Já há um reenvio em curso. |
| 422 | webhook_nao_configurado |
Teste ou reenvio sem configuração. |