Um webhook é um endpoint HTTPS, hospedado por você, que recebe notificações POST quando algo acontece nos recursos da sua aplicação: Items, transações e conectores. Eles substituem o polling — em vez de consultar a API repetidamente perguntando “já mudou?”, a Malvo te avisa. Os nomes de evento, o envelope, os campos e os enums seguem o contrato público da API. Como a Malvo faz apenas agregação de dados, os eventos de pagamento (ITP) nunca são disparados — veja a lista completa em Eventos.

Regras de transporte

São requisitos rígidos para qualquer endpoint registrado:
A regra do https:// vale também em desenvolvimento. Aponte o webhook para uma URL pública de túnel (ngrok, por exemplo) — endpoints localhost são recusados já no POST /webhooks.

Como registrar um webhook

Há duas formas de registrar webhooks, e elas se complementam.
1

Application-level (via API de Webhooks)

Registrado pelo CRUD de webhooks (POST /webhooks), no nível da aplicação. É a forma recomendada para um listener de event: "all" e a única maneira de definir headers de autenticação customizados. Consulte a Referência da API — grupo Webhooks.
2

Per-resource (via webhookUrl)

Informe o parâmetro webhookUrl ao criar um Item (POST /items) ou um Connect Token (POST /connect_token). Essa URL recebe apenas os eventos daquele recurso específico — o Item resultante e as transações dele.
Todos os endpoints do CRUD de webhooks exigem o header X-API-KEY: <apiKey>. A apiKey tem TTL de 2 horas e é regenerada via POST /auth com clientId/clientSecret. Os headers de um webhook são write-only: aceitos no POST/PATCH, nunca retornados em GET e nunca visíveis no Dashboard.

Limites e retenção

  • Máximo de 5 webhooks por tipo de evento por aplicação. Exceder retorna o erro Webhook limit reached. Quem precisa de mais fan-out deve assinar um endpoint em event: "all" e rotear internamente.
  • Webhooks apontando para ferramentas de teste conhecidas (ngrok, requestcatcher.com, URLs de túnel/local) são auto-removidos após 90 dias.
  • Apenas administradores ou owners do time podem editar webhooks pelo Dashboard. Os headers nunca são editáveis ou visíveis no Dashboard — somente via API.

O padrão canônico: webhook como gatilho, REST como fonte da verdade

Nunca confie apenas no payload do webhook. O padrão recomendado é “webhook como gatilho, REST como fonte da verdade”:
1

Registre um webhook no setup da aplicação

Um listener em event: "all" apontando para o seu receiver.
2

Em qualquer evento item/*, re-busque o recurso canônico

GET /items/{itemId} para status, erro e consentExpiresAt; depois GET /accounts?itemId=....
3

Em transactions/created e transactions/updated

Liste as contas do itemId, pagine GET /v2/transactions?accountId=... para cada uma e faça upsert por id da transação. O payload não inclui accountId nem link de transações.
4

Em transactions/deleted

Delete localmente pelos transactionIds recebidos.
5

Em item/error e item/waiting_user_input

Marque o Item como “precisa de ação” e direcione o usuário de volta ao widget em modo de atualização.
6

Responda 2XX antes do trabalho pesado

Empurre o evento para uma fila (BullMQ, SQS, etc.) e processe de forma assíncrona.
Worker de referência (Express + fila) — o webhook apenas confirma a recepção e enfileira; o worker faz o trabalho re-buscando a API:
Faça todo o trabalho pesado depois de responder 2XX. Trabalho síncrono antes do 200 causa timeout (>5s), e a Malvo passa a reentregar o mesmo evento até 9 vezes. Veja Entrega & Retry.

Próximos passos

Catálogo de Eventos

Todos os eventos disparados, com payload de exemplo e a ação recomendada para cada um.

Entrega & Retry

O que conta como entregue, o schedule de 9 tentativas, idempotência e a reconciliação noturna.

Segurança

Headers customizados, IP allowlisting e o checklist de validação do receiver.

Referência — Webhooks

O CRUD completo: POST, GET, PATCH e DELETE de webhooks.