> ## 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.

# Exportações e disputas

> Rode jobs de exportação assíncronos para gerar relatórios de conciliação para download, e abra, comprove com evidências e resolva disputas contra exceções.

Este guia cobre dois workflows de operador que terminam em um artefato baixável ou resolvido. Com **jobs de exportação** você põe um relatório na fila, consulta até ele ter sucesso e baixa o arquivo. Com **disputas** você abre uma disputa contra uma exceção, anexa evidências e depois a encerra como ganha ou perdida. O Matcher limita os jobs de exportação e as disputas ao seu tenant.

## Jobs de exportação

***

As exportações são assíncronas. Você cria um job com escopo em um contexto, consulta o status dele pelo ID e baixa o arquivo quando ele chega em `SUCCEEDED`. Os status são `QUEUED`, `RUNNING`, `SUCCEEDED`, `FAILED`, `EXPIRED` e `CANCELED`.

### Criar um job de exportação

Faça `POST` na coleção de jobs de exportação do contexto. Responde `202 Accepted` com o ID do job e uma URL de consulta.

```bash theme={null}
curl -X POST "https://api.matcher.example.com/v1/contexts/{contextId}/export-jobs" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "reportType": "MATCHED",
    "format": "CSV",
    "dateFrom": "2025-01-01",
    "dateTo": "2025-01-31",
    "sourceId": "550e8400-e29b-41d4-a716-446655440000"
  }'
```

```json theme={null}
{
  "jobId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "QUEUED",
  "statusUrl": "/v1/export-jobs/550e8400-e29b-41d4-a716-446655440000"
}
```

* `reportType`: um entre `MATCHED`, `UNMATCHED`, `VARIANCE`, `EXCEPTIONS` (os aliases `MATCHES` e `UNMATCHED_TRANSACTIONS` normalizam para esses valores).
* `format`: `CSV`, `JSON` ou `XML`, em maiúsculas.
* `dateFrom` / `dateTo`: `YYYY-MM-DD` opcional. `dateFrom` tem como padrão 30 dias antes de `dateTo`, e `dateTo` tem como padrão amanhã (UTC).
* `sourceId`: filtro de fonte opcional.

> [!NOTE]
>
> Os jobs de exportação assíncronos não aceitam `SUMMARY` (`400`) nem `PDF` (`422`). A janela de datas cobre no máximo 365 dias, e uma janela maior retorna `400`. A criação do job retorna `503` quando as exportações assíncronas não estão habilitadas para o seu ambiente.

### Consultar o status do job

Leia a rota de job de nível raiz (a `statusUrl` da criação).

```bash theme={null}
curl -X GET "https://api.matcher.example.com/v1/export-jobs/{jobId}" \
  -H "Authorization: Bearer $TOKEN"
```

```json theme={null}
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "contextId": "969a11cd-6b7d-4e71-b82b-0828e0603149",
  "reportType": "MATCHED",
  "format": "CSV",
  "status": "SUCCEEDED",
  "recordsWritten": 4250,
  "bytesWritten": 524288,
  "fileName": "MATCHED_550e8400_20250101-20250131.csv",
  "createdAt": "2025-01-15T10:30:00Z",
  "startedAt": "2025-01-15T10:30:05Z",
  "finishedAt": "2025-01-15T10:35:00Z",
  "expiresAt": "2025-01-22T10:30:00Z",
  "downloadUrl": "/v1/export-jobs/550e8400-e29b-41d4-a716-446655440000/download"
}
```

`contextId` indica o contexto que o job exporta. `error` traz o último motivo de falha do job, quando ele tem um. `downloadUrl` é a rota de download abaixo, e aparece apenas quando o job chegou a `SUCCEEDED` e o arquivo ainda está disponível. Você pode listar os jobs de um contexto com `GET /v1/contexts/{contextId}/export-jobs`, listar todos os jobs com `GET /v1/export-jobs` e cancelar um job na fila ou em execução com `POST /v1/export-jobs/{jobId}/cancel`.

### Baixar o arquivo

Retorna uma URL pré-assinada, o nome original do arquivo, um checksum SHA-256 e o tempo de vida restante da URL em segundos.

```bash theme={null}
curl -X GET "https://api.matcher.example.com/v1/export-jobs/{jobId}/download" \
  -H "Authorization: Bearer $TOKEN"
```

```json theme={null}
{
  "downloadUrl": "https://storage.example.com/exports/report.csv?token=abc",
  "fileName": "MATCHED_550e8400_20250101-20250131.csv",
  "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  "expiresIn": 3600
}
```

> [!WARNING]
>
> Os arquivos de exportação são apagados depois de `expiresAt`, 7 dias depois da criação do job. Depois disso, o arquivo não pode mais ser baixado. Rode a exportação de novo para gerá-lo outra vez.

## Disputas

***

Você abre uma disputa contra uma **exceção** específica quando precisa contestar uma divergência de conciliação. Uma disputa nova fica `OPEN`. Fechá-la define `WON` ou `LOST`, e os dois resultados são terminais.

### Abrir uma disputa

Faça `POST` na coleção de disputas da exceção. Responde `201 Created`.

```bash theme={null}
curl -X POST "https://api.matcher.example.com/v1/exceptions/{exceptionId}/disputes" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "category": "BANK_FEE_ERROR",
    "description": "Transaction amount differs from invoice"
  }'
```

```json theme={null}
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "exceptionId": "550e8400-e29b-41d4-a716-446655440001",
  "category": "BANK_FEE_ERROR",
  "state": "OPEN",
  "description": "Transaction amount differs from invoice",
  "openedBy": "user@example.com",
  "createdAt": "2025-01-15T10:30:00Z",
  "updatedAt": "2025-01-15T10:30:00Z"
}
```

`category` é um entre `BANK_FEE_ERROR`, `UNRECOGNIZED_CHARGE`, `DUPLICATE_TRANSACTION`, `AMOUNT_MISMATCH` ou `OTHER`. A resposta omite `evidence` até a disputa ter alguma. O campo `openedBy` registra o principal que abriu.

O Matcher recusa abrir uma disputa com `409` (`MTCH-0511`) quando a exceção está `RESOLVED` ou `PENDING_RESOLUTION`. Ele responde `409` (`MTCH-0510`) enquanto uma liquidação está em andamento na exceção. Repita essa requisição depois que a liquidação terminar.

### Enviar evidência por URL

Anexe uma referência a um arquivo de evidência já hospedado mais um comentário que o descreve. `fileUrl` precisa ser uma URL `https`.

```bash theme={null}
curl -X POST "https://api.matcher.example.com/v1/disputes/{disputeId}/evidence" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "comment": "Attached bank statement showing correct amount",
    "fileUrl": "https://storage.example.com/evidence/doc123.pdf"
  }'
```

### Fazer upload de um arquivo de evidência

Envie os bytes brutos do arquivo direto para o object storage com escopo de tenant. O comentário viaja como parâmetro de query e o arquivo como corpo da requisição. Responde `201 Created` com a disputa atualizada. Os content types permitidos são `application/pdf`, `image/png`, `image/jpeg` e `text/csv`. O corpo tem limite de 10 MiB.

```bash theme={null}
curl -X POST "https://api.matcher.example.com/v1/disputes/{disputeId}/evidence/upload?comment=Bank%20statement%20showing%20correct%20amount" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/pdf" \
  --data-binary @statement.pdf
```

O array `evidence` da disputa lista cada item de evidência guardado. Para um arquivo enviado, `fileUrl` guarda a chave do armazenamento de objetos, não uma URL de download:

```json theme={null}
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "disputeId": "550e8400-e29b-41d4-a716-446655440001",
  "comment": "Bank statement showing correct amount",
  "submittedBy": "user@example.com",
  "fileUrl": "<tenant-id>/dispute-evidence/550e8400-e29b-41d4-a716-446655440001/<object-id>.pdf",
  "submittedAt": "2025-01-15T10:30:00Z"
}
```

> [!NOTE]
>
> O endpoint de upload retorna `503` quando o armazenamento de evidências está indisponível. Ele rejeita corpos grandes demais com `413` e content types fora da allowlist com `415`.

### Fechar uma disputa

Registre o resultado. `won: true` define o estado como `WON` e `won: false` o define como `LOST`. Uma nota `resolution` é obrigatória.

```bash theme={null}
curl -X POST "https://api.matcher.example.com/v1/disputes/{disputeId}/close" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "won": true,
    "resolution": "Counterparty acknowledged the error and issued correction"
  }'
```

Você pode listar disputas com `GET /v1/disputes` e buscar uma com `GET /v1/disputes/{disputeId}`. O endpoint de lista filtra por `state`, `category` e intervalo de datas, e oferece suporte a ordenação e paginação por cursor.

## Códigos de resposta

***

| Status | Significado |
| - | - |
| `200` | Dados de exportação ou de disputa retornados |
| `201` | Disputa aberta ou arquivo de evidência enviado |
| `202` | Job de exportação aceito |
| `400` | Entrada inválida (tipo de relatório `SUMMARY`, intervalo de datas errado, categoria inválida) |
| `404` | Contexto, job de exportação, exceção ou disputa não encontrado |
| `409` | Job de exportação ainda não pronto para download, ou já em estado terminal ao ser cancelado. Exceção que não aceita uma nova disputa, ou com uma liquidação em andamento |
| `410` | Arquivo de exportação expirado |
| `413` | O arquivo de evidência ultrapassa o limite de 10 MiB |
| `415` | Content type da evidência fora da allowlist |
| `422` | Campo malformado (incluindo um `format` em minúsculas ou não aceito), ou transição de estado de disputa inválida |
| `429` | Limite de requisições excedido |
| `503` | Exportações assíncronas não habilitadas para o seu ambiente, ou armazenamento de exportação ou de evidência indisponível |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.