> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks e callbacks

> Emita eventos de ciclo de vida do Matcher para ferramentas externas por webhooks de saída e receba callbacks de resolução para que JIRA ou ServiceNow mantenham as exceções em sincronia.

Webhooks permitem comunicação em tempo real entre o Matcher e sistemas externos. Este guia cobre notificações de eventos de saída e callbacks de resolução de entrada.

## Visão geral

***

O Matcher oferece suporte a comunicação bidirecional por webhook e mantém suas ferramentas operacionais em sincronia com cada evento de conciliação em tempo real.

* **Webhooks de saída**: o roteamento de exceções despacha exceções para destinos externos: JIRA, ServiceNow ou um endpoint de webhook HTTP que você configura
* **Callbacks de entrada**: sistemas externos avisam o Matcher quando executam uma ação

Quando o roteamento de exceções envia uma exceção para um destino de webhook, o Matcher entrega uma requisição HTTP assinada ao seu endpoint. Sistemas externos como JIRA ou ServiceNow podem então enviar callbacks para atualizar o status da exceção ou fechar itens automaticamente. Esse fluxo de mão dupla mantém suas ferramentas em sincronia sem intervenção manual.

Além do despacho de exceções, o Matcher publica o catálogo completo de eventos de ciclo de vida no backbone de streaming da plataforma. Esses eventos chegam até você como stream, não como webhooks HTTP.

<Frame caption="Fluxo de mão dupla entre o Matcher e sistemas externos.">
  <img src="https://mintcdn.com/lerian-49cb71fc/vdBt8wfgjsNRO1rf/images/pt/d2/matcher-webhooks-callbacks.svg?fit=max&auto=format&n=vdBt8wfgjsNRO1rf&q=85&s=6e36549e16f16074a9d948b092da08a9" alt="Webhooks e callbacks do Matcher" width="724" height="520" data-path="images/pt/d2/matcher-webhooks-callbacks.svg" />
</Frame>

## Eventos de saída

***

O Matcher emite eventos quando ações relevantes acontecem no processo de conciliação. O Matcher publica o catálogo abaixo no backbone de streaming. Os eventos de exceção também chegam a endpoints de webhook HTTP pelo [roteamento de exceções](/pt/products/matcher/configuration/matcher-exception-routing).

### Eventos disponíveis

O Matcher define seu catálogo de eventos de forma centralizada. As tabelas abaixo agrupam por domínio os eventos mais consumidos.

**Configuração**

| Evento                           | Gatilho                                 | Uso típico                           |
| -------------------------------- | --------------------------------------- | ------------------------------------ |
| `reconciliation_context.created` | Contexto de conciliação criado          | Sincronização de provisionamento     |
| `reconciliation_context.updated` | Metadados ou status do contexto mudaram | Rastreio de mudanças de configuração |
| `reconciliation_context.deleted` | Contexto excluído                       | Desmontagem downstream               |
| `reconciliation_source.created`  | Fonte criada dentro de um contexto      | Entrada de nova fonte                |
| `match_rule.created`             | Regra de correspondência criada         | Auditoria de mudanças de regra       |
| `match_rule.reordered`           | Prioridades de regras reordenadas       | Auditoria de mudanças de regra       |

**Discovery**

| Evento                             | Gatilho                                    | Uso típico                  |
| ---------------------------------- | ------------------------------------------ | --------------------------- |
| `fetcher_connection.synced`        | Conexão e snapshot do schema sincronizados | Monitoramento da descoberta |
| `fetcher_connection.unreachable`   | Conexão marcada como inalcançável          | Alerta de conectividade     |
| `extraction_request.created`       | Pedido de extração criado                  | Monitoramento de extração   |
| `extraction_request.submitted`     | Extração aceita pelo motor de extração     | Monitoramento de extração   |
| `extraction_request.completed`     | Extração concluída com artefato            | Prontidão dos dados         |
| `extraction_request.failed`        | Extração falhou                            | Alerta de erro              |
| `extraction_request.cancelled`     | Extração cancelada                         | Monitoramento do pipeline   |
| `extraction_request.bridged`       | Extração ligada a um job de ingestão       | Monitoramento do pipeline   |
| `extraction_request.bridge_failed` | Ligação com a ingestão falhou              | Alerta de erro              |

**Ingestão**

| Evento                | Gatilho                                        | Uso típico                         |
| --------------------- | ---------------------------------------------- | ---------------------------------- |
| `ingestion.completed` | Importação de arquivo terminou                 | Monitoramento do pipeline de dados |
| `ingestion.failed`    | Importação de arquivo falhou                   | Alerta de erro                     |
| `transaction.ignored` | Transação não conciliada marcada como ignorada | Trilha de auditoria                |

**Correspondência**

| Evento                       | Gatilho                                     | Uso típico                        |
| ---------------------------- | ------------------------------------------- | --------------------------------- |
| `match_run.completed`        | Job de correspondência terminou             | Monitoramento de jobs, relatórios |
| `match_run.failed`           | Job de correspondência falhou               | Alerta de erro                    |
| `match_group.confirmed`      | Grupo de correspondência confirmado         | Atualizações downstream           |
| `match_group.unmatched`      | Correspondência confirmada revertida        | Rastreio de correções             |
| `transaction.matched`        | Transação marcada como conciliada           | Registro de auditoria             |
| `transaction.pending_review` | Candidato não automático precisa de revisão | Gatilhos da fila de revisão       |
| `fee_variance.created`       | Variação de tarifa detectada                | Investigação de tarifas           |

**Exceções e disputas**

| Evento                            | Gatilho                                       | Uso típico                   |
| --------------------------------- | --------------------------------------------- | ---------------------------- |
| `exception.assigned`              | Exceção atribuída a um responsável            | Notificação de usuário       |
| `exception.resolved`              | Exceção resolvida                             | Sincronização de status      |
| `exception.dispatched`            | Exceção enviada a um destino externo          | Criação de chamado           |
| `exception.callback_processed`    | Callback externo processado                   | Sincronização de status      |
| `exception.force_match_resolved`  | Exceção resolvida por correspondência forçada | Workflows de aprovação       |
| `exception.adjust_entry_resolved` | Exceção resolvida por lançamento de ajuste    | Trilha de auditoria          |
| `exception_comment.added`         | Comentário adicionado a uma exceção           | Sincronização de colaboração |
| `exception_comment.deleted`       | Comentário de exceção excluído                | Sincronização de colaboração |
| `dispute.opened`                  | Disputa aberta para uma exceção               | Acompanhamento de disputas   |
| `dispute.won`                     | Disputa encerrada como ganha                  | Sincronização de status      |
| `dispute.lost`                    | Disputa encerrada como perdida                | Sincronização de status      |
| `evidence.submitted`              | Evidência enviada a uma disputa               | Acompanhamento de disputas   |

**Governança e relatórios**

| Evento                     | Gatilho                                | Uso típico                    |
| -------------------------- | -------------------------------------- | ----------------------------- |
| `audit_log.created`        | Entrada de log de auditoria adicionada | Monitoramento de conformidade |
| `archive_metadata.created` | Ciclo de vida de arquivamento começou  | Monitoramento de arquivamento |
| `archive.uploaded`         | Objeto de arquivo enviado              | Monitoramento de arquivamento |
| `archive.completed`        | Arquivo verificado e concluído         | Monitoramento de arquivamento |
| `actor.pseudonymized`      | Mapeamento de ator pseudonimizado      | Monitoramento de conformidade |
| `export_job.created`       | Job de exportação na fila              | Monitoramento de exportações  |
| `export_job.succeeded`     | Job de exportação concluído            | Download disponível           |
| `export_job.failed`        | Job de exportação falhou               | Alerta de erro                |
| `export_job.expired`       | Artefato de exportação expirou         | Ciclo de vida da exportação   |

### Payload de entrega do webhook

Os despachos de exceção para um destino de webhook carregam um payload consistente com `eventId`, `eventType`, `timestamp`, o snapshot da exceção em `data` e informações de roteamento e tracing em `metadata`:

```json theme={null}
{
  "eventId": "0e8f1c2a-5b6d-4f3e-9a7b-1c2d3e4f5a6b",
  "eventType": "exception.dispatched",
  "timestamp": "2026-01-20T10:30:00Z",
  "data": {
    "exceptionId": "9b2f4e6a-1c3d-4e5f-8a9b-0c1d2e3f4a5b",
    "transactionId": "7a1b3c5d-9e8f-4a2b-b6c7-d8e9f0a1b2c3",
    "severity": "HIGH",
    "status": "PENDING",
    "amount": "15000.00",
    "currency": "USD",
    "reason": "No matching ledger entry found",
    "sourceType": "LEFT",
    "createdAt": "2026-01-20T10:29:15Z",
    "dueAt": "2026-01-23T10:29:15Z"
  },
  "metadata": {
    "traceId": "4bf92f3577b34da6a3ce929d0e0e4736",
    "target": "WEBHOOK",
    "queue": "ops-review",
    "ruleName": "high-value-unmatched",
    "assignee": "ops-team"
  }
}
```

O Matcher omite `data.dueAt` e os campos `traceId`, `queue`, `ruleName` e `assignee` de `metadata` quando eles não têm valor. Os eventos do catálogo de streaming (as tabelas acima) seguem seus próprios schemas por evento no stream de eventos. O Matcher não os entrega neste formato HTTP.

## Callbacks de entrada

***

Sistemas externos enviam callbacks ao Matcher para atualizar o status da exceção depois do processamento. O endpoint de callback aceita atualizações de status, notas de resolução e mudanças de responsável de qualquer sistema externo.

### Processar um callback

O header `X-Callback-Token` autentica o endpoint de callback. Um JWT de operador não o autentica. O header carrega um token opaco da superfície de [credenciais de callback](#callback-credentials). Cada campo abaixo é obrigatório. `dueAt` e `updatedAt` aceitam `null`, e `payload` pode ser um objeto vazio:

```bash cURL theme={null}
curl -X POST "https://api.matcher.example.com/v1/exceptions/{exceptionId}/callback" \
 -H "X-Callback-Token: ***" \
 -H "X-Idempotency-Key: callback-jira-1234" \
 -H "Content-Type: application/json" \
 -d '{
   "callbackType": "status_update",
   "externalSystem": "JIRA",
   "externalIssueId": "RECON-1234",
   "status": "RESOLVED",
   "resolutionNotes": "Verified: amount difference is expected bank wire fee",
   "assignee": "john.doe@company.com",
   "dueAt": null,
   "updatedAt": "2026-01-20T14:30:00Z",
   "payload": {}
 }'
```

O campo `externalSystem` identifica o sistema externo que processou a exceção. Valores comuns incluem `"JIRA"`, `"SERVICENOW"` ou `"WEBHOOK"`, mas os callbacks podem informar qualquer identificador de sistema. Omitir qualquer um dos nove campos obrigatórios retorna `422`.

#### Resposta

```json theme={null}
{
  "status": "accepted"
}
```

<Tip>
  Referência da API: [Processar callback](/pt/reference/products/matcher/process-exception-callback)
</Tip>

Quando o Matcher processa um callback, ele atualiza o status da exceção e registra a resolução na trilha de auditoria. Use o header `X-Idempotency-Key` para evitar processamento duplicado.

<h3 id="automatic-retry-for-failed-callbacks">
  Nova tentativa automática para callbacks que falharam
</h3>

Se um callback anterior com a mesma chave de idempotência falhou durante o processamento, o Matcher tenta automaticamente readquirir o lock de idempotência e reprocessar o callback. Isso significa que você não precisa gerar uma nova chave de idempotência ao repetir um callback que falhou. Reenvie a mesma requisição e o Matcher cuida da recuperação.

Esse comportamento de nova tentativa vale apenas para callbacks com estado interno `failed`. O Matcher continua deduplicando callbacks que terminaram com sucesso.

<h2 id="callback-credentials">
  Credenciais de callback
</h2>

***

Um token bearer opaco autentica os callbacks de entrada. O sistema externo envia esse token no header `X-Callback-Token`. Você emite, lista, rotaciona e revoga essas **credenciais de callback** por uma superfície CRUD dedicada em `/v1/exceptions/callbacks/credentials`. Cada credencial pertence ao tenant de quem chama. O Matcher guarda apenas o hash SHA-256 do token no servidor. As respostas de emissão e de rotação retornam o token bruto **exatamente uma vez**.

| Ação                  | Método e caminho                                                  | Observações                                                                                                                                                          |
| --------------------- | ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Emitir credencial     | `POST /v1/exceptions/callbacks/credentials`                       | Cria uma credencial e retorna o token bruto uma vez (`201`).                                                                                                         |
| Listar credenciais    | `GET /v1/exceptions/callbacks/credentials`                        | Lista os metadados das credenciais do tenant (nunca os tokens brutos).                                                                                               |
| Rotacionar credencial | `POST /v1/exceptions/callbacks/credentials/{credentialId}/rotate` | Substitui de forma atômica uma credencial ativa por outra recém-emitida (mesmo rótulo) e retorna o novo token bruto uma vez; a antiga é revogada na mesma transação. |
| Revogar credencial    | `DELETE /v1/exceptions/callbacks/credentials/{credentialId}`      | Revoga a credencial em definitivo (`204`); auditado em modo append-only.                                                                                             |

<Tip>
  Referência da API:

  * [Emitir credencial de callback](/pt/reference/products/matcher/mint-callback-credential)
  * [Listar credenciais de callback](/pt/reference/products/matcher/list-callback-credentials)
  * [Rotacionar credencial de callback](/pt/reference/products/matcher/rotate-callback-credential)
  * [Revogar credencial de callback](/pt/reference/products/matcher/revoke-callback-credential)
</Tip>

### Emitir uma credencial

O corpo da requisição é opcional. Informe `externalSystem` como um rótulo legível pelo operador para o sistema que este token autentica.

```bash cURL theme={null}
curl -X POST "https://api.matcher.example.com/v1/exceptions/callbacks/credentials" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{ "externalSystem": "stripe" }'
```

A resposta `201` (`CredentialSecretResponse`) retorna:

| Campo            | Descrição                                                                                                                                   |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `token`          | Token bearer bruto, mostrado **uma vez**. Configure-o como valor do header `X-Callback-Token` no sistema externo.                           |
| `credentialId`   | Id substituto da credencial emitida (usado para rotacionar e revogar).                                                                      |
| `createdAt`      | Momento da emissão (RFC 3339, UTC).                                                                                                         |
| `externalSystem` | O rótulo devolvido para confirmação.                                                                                                        |
| `webhookUrlHint` | Formato informativo da URL de callback de entrada para configurar fora do Matcher; o marcador `{exceptionId}` é preenchido a cada callback. |

<Warning>
  Apenas as respostas de emissão e de rotação mostram o `token` bruto. Guarde-o com segurança ao recebê-lo. Você não pode recuperá-lo de novo. Se perder ou vazar o token, rotacione ou revogue a credencial.
</Warning>

### Rotacionar uma credencial

```bash cURL theme={null}
curl -X POST "https://api.matcher.example.com/v1/exceptions/callbacks/credentials/{credentialId}/rotate" \
 -H "Authorization: Bearer $TOKEN"
```

A rotação retorna um novo `CredentialSecretResponse` (novo token bruto) e revoga a credencial anterior de forma atômica, assim quem chama de fora não fica sem acesso quando você troca o token.

### Revogar uma credencial

```bash cURL theme={null}
curl -X DELETE "https://api.matcher.example.com/v1/exceptions/callbacks/credentials/{credentialId}" \
 -H "Authorization: Bearer $TOKEN"
```

A revogação é definitiva: a credencial não pode mais autenticar callbacks de entrada.

## Segurança de webhooks

***

### Verificação de assinatura

Quando você configura um segredo compartilhado de webhook, o Matcher assina cada entrega com um HMAC-SHA256 sobre o **corpo bruto da requisição**. O Matcher envia a assinatura no header `X-Signature-256`, no formato `sha256=<hex-digest>`:

```
X-Signature-256: sha256=abc123...
```

Cada entrega também carrega um header `X-Idempotency-Key` para que os receptores possam deduplicar novas tentativas.

**Processo de verificação:**

1. Calcule o HMAC-SHA256 do corpo bruto da requisição usando o segredo compartilhado do webhook
2. Prefixe o digest hexadecimal com `sha256=`
3. Compare (em tempo constante) com o header `X-Signature-256`

**Exemplo (Node.js):**

```javascript theme={null}
const crypto = require('crypto');

function verifyWebhook(payload, signature, secret) {
 const expectedSignature = crypto
 .createHmac('sha256', secret)
 .update(payload)
 .digest('hex');

 return `sha256=${expectedSignature}` === signature;
}
```

**Exemplo (Python):**

```python theme={null}
import hmac
import hashlib

def verify_webhook(payload, signature, secret):
 expected = hmac.new(
 secret.encode(),
 payload,
 hashlib.sha256
 ).hexdigest()
 return f"sha256={expected}" == signature
```

### Postura de rede

O deploy do Matcher acontece na sua própria infraestrutura, então as entregas de webhook saem pelo egress do seu deploy. Não existe faixa de IP fixa da Lerian para colocar em allowlist. Sirva os endpoints de webhook por HTTPS com um certificado válido. Como proteção contra SSRF, o Matcher recusa entregar para endereços IP privados ou de loopback, a menos que o deploy os permita explicitamente (apenas em desenvolvimento).

## Lógica de novas tentativas

***

O Matcher repete as entregas de webhook que falharam com backoff exponencial.

### Política padrão de novas tentativas

Por padrão, o Matcher repete uma entrega que falhou até **3 vezes**. Os atrasos seguem backoff exponencial a partir de uma base de **1 segundo**, com jitter para espalhar as tentativas. O espaçamento exato varia de tentativa para tentativa em vez de seguir uma escada fixa.

### Condições de nova tentativa

As novas tentativas acontecem para:

* Respostas HTTP 429
* Respostas HTTP 5xx
* Erros de transporte (falhas de conexão, timeouts)

Sem nova tentativa para:

* Outras respostas HTTP 4xx

## Boas práticas

***

<AccordionGroup>
  <Accordion title="Verifique as assinaturas de webhook">
    Sempre verifique a assinatura HMAC antes de processar payloads de webhook. Isso evita requisições forjadas.
  </Accordion>

  <Accordion title="Responda rápido">
    Retorne uma resposta 2xx em até 5 segundos. Processe o evento de forma assíncrona se precisar.
  </Accordion>

  <Accordion title="Trate duplicatas de forma idempotente">
    As entregas podem chegar mais de uma vez. Deduplique pelo header `X-Idempotency-Key` ou pelo `eventId` do payload.
  </Accordion>

  <Accordion title="Monitore a saúde das entregas">
    Configure alertas para as taxas de falha de webhook. Investigue falhas persistentes sem demora.
  </Accordion>
</AccordionGroup>

## Próximos passos

***

<Card title="Roteamento de exceções" icon="route" href="/pt/products/matcher/configuration/matcher-exception-routing" horizontal>
  Configure como as exceções disparam eventos de webhook.
</Card>

<Card title="Fontes externas" icon="building-columns" href="/pt/products/matcher/integrations/matcher-external-sources" horizontal>
  Configure fontes de dados que podem enviar por webhooks.
</Card>
