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

# Revisiones de extracción

> Revisa, aprueba o rechaza candidatos de transacción extraídos por IA antes de que entren a la ingesta, y usa las propuestas de mapeo y las acciones sobre trabajos para preparar los datos de origen.

Matcher puede extraer candidatos de transacción de documentos y proponer mapeos de campos con IA, pero **la salida de la IA nunca es autoritativa**. Nada llega a la conciliación hasta que una persona lo aprueba. Esta guía cubre la cola de revisión de extracciones con intervención humana (HITL), las propuestas de mapeo por IA y las acciones sobre trabajos relacionadas.

<Note>Cuando Lerian habilita la extracción de documentos en tu entorno y en tu tenant, puedes enviar documentos. Un tenant sin extracción de documentos recibe `403`. Esa respuesta llega antes de cualquier almacenamiento o salida de los bytes del documento.</Note>

## Encolar un documento para extracción

***

Sube un documento de origen (PDF) para ejecutar la extracción determinista + IA. Matcher envía un fragmento limitado de la capa de texto del documento al proveedor de modelos de lenguaje que Lerian configura para tu entorno. Cuando el PDF no tiene capa de texto, Matcher envía el propio PDF. Los candidatos de transacción resultantes van a una cola de revisión. Todavía nada llega a la conciliación.

```bash theme={null}
curl -X POST "https://api.matcher.example.com/v1/imports/contexts/{contextId}/sources/{sourceId}/extract-document" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/pdf" \
  --data-binary @statement.pdf
```

La respuesta (`202 Accepted`) devuelve el id de la revisión encolada, el conteo de candidatos y un estado que siempre es `PENDING_REVIEW` al encolar:

```json theme={null}
{
  "reviewId": "550e8400-e29b-41d4-a716-446655440000",
  "candidateCount": 12,
  "status": "PENDING_REVIEW"
}
```

## La cola de revisión

***

### Listar revisiones

Lista paginada por cursor de las revisiones de extracción de un contexto, con filtro opcional por estado del ciclo de vida.

```bash theme={null}
curl -X GET "https://api.matcher.example.com/v1/imports/contexts/{contextId}/extraction-reviews?status=PENDING_REVIEW&limit=50" \
  -H "Authorization: Bearer $TOKEN"
```

Parámetros de consulta: `status` (`PENDING_REVIEW`, `APPROVED`, `REJECTED`), `limit` (1–200) y `cursor`.

### Obtener una revisión

```bash theme={null}
curl -X GET "https://api.matcher.example.com/v1/imports/contexts/{contextId}/extraction-reviews/{reviewId}" \
  -H "Authorization: Bearer $TOKEN"
```

Una revisión lleva su ciclo de vida, los candidatos propuestos, la procedencia y el estado de vinculación:

```json theme={null}
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "contextId": "550e8400-e29b-41d4-a716-446655440000",
  "sourceId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "PENDING_REVIEW",
  "candidates": [
    {
      "source": "text_layer",
      "fields": [
        { "canonicalKey": "amount", "value": "100.50", "confidence": 0.95, "page": 1 },
        { "canonicalKey": "date", "value": "2025-06-01", "confidence": 0.9, "page": 1 }
      ]
    }
  ],
  "version": 1,
  "createdAt": "2025-01-15T10:30:00Z",
  "updatedAt": "2025-01-15T10:30:00Z"
}
```

Cada candidato declara el canal que lo produjo: `text_layer` (texto del PDF, mayor confianza) o `vision` (modelo de OCR o visión, menor confianza). En el canal `text_layer`, los valores de campo son tokens del texto del documento. En el canal `vision`, el modelo los lee de la imagen. El dinero se mantiene como cadena, nunca como un monto ya parseado.

## Aprobar o rechazar

***

### Aprobar

Aprobar una revisión en `PENDING_REVIEW` ejecuta el único traspaso determinista hacia el pipeline de ingesta normal (dedup + outbox + disparador de coincidencia) y vincula el trabajo resultante a la revisión. Este es el **único** camino de un candidato de IA a una transacción conciliada, y se ejecuta solo con aprobación humana explícita.

```bash theme={null}
curl -X POST "https://api.matcher.example.com/v1/imports/contexts/{contextId}/extraction-reviews/{reviewId}/approve" \
  -H "Authorization: Bearer $TOKEN"
```

```json theme={null}
{
  "reviewId": "550e8400-e29b-41d4-a716-446655440000",
  "ingestionJobId": "550e8400-e29b-41d4-a716-446655440000",
  "candidateCount": 12
}
```

### Rechazar

Rechazar cierra la revisión, y nada entra a la ingesta. El cuerpo es opcional. Un cuerpo vacío es un "rechazo sin motivo" válido.

```bash theme={null}
curl -X POST "https://api.matcher.example.com/v1/imports/contexts/{contextId}/extraction-reviews/{reviewId}/reject" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "reason": "poor scan quality, re-upload" }'
```

El principal que aprueba o rechaza queda registrado para auditoría.

## Propuestas de mapeo

***

Antes de declarar un mapa de campos a mano, pide al asesor que inspeccione una muestra representativa y proponga un mapeo **solo de configuración**. Cuando Lerian habilita el asesor de mapeo en tu entorno, Matcher envía un fragmento limitado de la muestra al proveedor de modelos de lenguaje que Lerian configura para tu entorno. Es consultivo y sin efectos secundarios: generar una propuesta **no persiste nada**. Confirmas el resultado por la ruta existente de declaración del mapa de campos.

```bash theme={null}
curl -X POST "https://api.matcher.example.com/v1/imports/contexts/{contextId}/sources/{sourceId}/mapping-proposal" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "sample": "id;value;ccy;posted_at\nA1;10,50;BRL;2025-06-01\n",
    "format": "csv",
    "hints": { "locale": "pt-BR", "has_header": "true" }
  }'
```

La respuesta lleva el mapa de campos propuesto, el dialecto de la fuente y un desglose por campo con confianza y justificación:

```json theme={null}
{
  "mapping": { "amount": "value", "external_id": "id" },
  "dialect": {
    "encoding": "utf-8",
    "delimiter": "semicolon",
    "decimalStyle": "comma",
    "dateStyle": "iso"
  },
  "fields": [
    { "canonicalKey": "amount", "sourceColumn": "value", "confidence": 0.92, "rationale": "numeric column with comma decimal" }
  ]
}
```

La respuesta nunca lleva valores parseados, montos ni transacciones.

## Traer datos de un transporte externo

***

Dispara una obtención e ingesta manual que lista cada objeto que coincide con las coordenadas de transporte entregadas y envía cada uno al pipeline de ingesta de contenido confiable. `kind` es `sftp` (el predeterminado), `https`, `s3` o `imap`. El cuerpo lleva las coordenadas de conexión y un `credentialRef` obligatorio. Una obtención SFTP necesita la clave de host del servidor en `connectOptions.known_hosts` y lee como máximo 256 objetos coincidentes.

```bash theme={null}
curl -X POST "https://api.matcher.example.com/v1/imports/contexts/{contextId}/sources/{sourceId}/fetch" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "sftp",
    "host": "sftp.bank.example",
    "port": 22,
    "path": "outbound/returns",
    "glob": "*.ret",
    "credentialRef": "<credential-ref>",
    "format": "br/cnab240/febraban-base",
    "connectOptions": { "known_hosts": "sftp.bank.example ssh-ed25519 AAAA..." }
  }'
```

La respuesta (`202 Accepted`) devuelve un resultado por archivo en el orden de obtención. Una falla de admisión en un archivo no detiene el lote. La respuesta informa cada una:

```json theme={null}
{
  "files": [
    { "name": "statement-2025-06.ret", "ingestionJobId": "550e8400-...", "transactionCount": 42 }
  ]
}
```

Una falla en el nivel del transporte (endpoint inalcanzable o credencial rechazada) devuelve `503`.

## Inspeccionar los errores de un trabajo

***

Después de una importación, lista los errores de parseo o normalización almacenados por fila de un trabajo (con tope de 100 por trabajo) para explicar importaciones fallidas o parcialmente fallidas.

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

```json theme={null}
{
  "items": [ ... ],
  "totalErrors": 137,
  "storedErrors": 100,
  "errorCap": 100,
  "truncated": true
}
```

`totalErrors` contiene el total de fallas sin tope. `truncated` es `true` cuando el total supera el conjunto almacenado (con tope).

## Códigos de respuesta

***

| Estado | Significado |
| - | - |
| `200` | Se devolvió la revisión, la lista, la propuesta de mapeo o los errores del trabajo |
| `202` | Documento encolado / obtención aceptada |
| `400` | Entrada inválida (cuerpo del documento vacío, paginación inválida) |
| `403` | La extracción de documentos no está habilitada para tu tenant |
| `404` | Revisión o trabajo no encontrado |
| `409` | Transición de estado de revisión inválida |
| `422` | No se pudo extraer ningún candidato, o solicitud inválida (filtro de estado incorrecto, falta la muestra de mapeo, cuerpo estructuralmente inválido) |
| `503` | Extracción, revisión, propuesta u obtención no habilitadas en tu entorno, extractor de documentos no disponible o falla de transporte |


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