Matcher puede extraer candidatos de transacciones desde documentos y proponer mapeos de campos usando IA — pero la salida de la IA nunca es autoritativa. Nada se concilia hasta que un humano lo aprueba. Esta guía cubre la cola de revisión de extracción con supervisión humana (HITL), las propuestas de mapeo de IA y las acciones de trabajo relacionadas.
El carril de extracción de documentos está protegido por un kill-switch global y una activación explícita por tenant. Un tenant que no se ha activado recibe 403 antes de que se almacene o se transmita cualquier byte del documento.
Sube un documento de origen (PDF) para ejecutar la extracción determinista + IA. Los candidatos de transacciones resultantes se encolan en una revisión — todavía no se concilia nada.
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 número de candidatos y un estado que siempre es PENDING_REVIEW al encolar:
{
"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, opcionalmente filtrada por estado del ciclo de vida.
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
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:
{
"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 carril que lo produjo: text_layer (texto del PDF, mayor confianza) o vision (modelo de OCR/visión, menor confianza). Los valores de los campos son tokens textuales — el dinero se mantiene como cadena, nunca como un monto parseado.
Aprobar o rechazar
Aprobar
Aprobar una revisión en estado PENDING_REVIEW ejecuta el único traspaso determinista hacia el pipeline normal de ingesta (deduplicación + outbox + disparador de matching) y vincula el trabajo resultante con la revisión. Este es el único camino desde un candidato de IA hasta una transacción conciliada, y solo se ejecuta con la aprobación explícita de un humano.
curl -X POST "https://api.matcher.example.com/v1/imports/contexts/{contextId}/extraction-reviews/{reviewId}/approve" \
-H "Authorization: Bearer $TOKEN"
{
"reviewId": "550e8400-e29b-41d4-a716-446655440000",
"ingestionJobId": "550e8400-e29b-41d4-a716-446655440000",
"candidateCount": 12
}
Rechazar
Rechazar descarta los candidatos — no se ingesta nada. El cuerpo es opcional; un cuerpo vacío es un “rechazo sin motivo” válido.
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 se registra 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. Es consultivo y sin efectos secundarios: generar una propuesta no persiste nada. Confirmas el resultado mediante el camino existente de declaración del mapa de campos.
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 origen y un desglose por campo con confianza y justificación:
{
"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.
Obtener desde un transporte externo
Dispara un fetch-and-ingest manual que lista todos los objetos que coinciden con las coordenadas de transporte suministradas (hoy SFTP) y transmite cada uno al pipeline de ingesta de contenido confiable. El cuerpo lleva las coordenadas de conexión más una referencia de credencial opaca — nunca un secreto.
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": "cred-handle-123",
"format": "br/cnab240/febraban-base"
}'
La respuesta (202 Accepted) devuelve un resultado por archivo en el orden de obtención. Los fallos de ingesta por archivo se reportan sin hacer fallar el lote:
{
"files": [
{ "name": "statement-2025-06.ret", "ingestionJobId": "550e8400-...", "transactionCount": 42 }
]
}
Un fallo a nivel de transporte (endpoint inalcanzable o credencial rechazada) devuelve 503.
Inspeccionar errores de un trabajo
Después de una importación, lista los errores de parseo/normalización por fila almacenados para un trabajo (limitados a 100 por trabajo) para explicar importaciones fallidas o parcialmente fallidas.
curl -X GET "https://api.matcher.example.com/v1/imports/contexts/{contextId}/jobs/{jobId}/errors" \
-H "Authorization: Bearer $TOKEN"
{
"items": [ ... ],
"totalErrors": 137,
"storedErrors": 100,
"errorCap": 100,
"truncated": true
}
totalErrors es el total de fallos sin límite; truncated es true cuando supera el conjunto almacenado (limitado).
Códigos de respuesta
| Estado | Significado |
|---|
200 | Revisión, lista, propuesta de mapeo o errores de trabajo devueltos |
202 | Documento encolado / fetch aceptado |
400 | Entrada inválida (cuerpo vacío, filtro de estado incorrecto, paginación inválida) |
403 | Tenant no activado para extracción de documentos |
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 / muestra de mapeo rechazada aguas abajo |
503 | Extracción, revisión, propuesta o fetch no habilitados en este despliegue |