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

# Resolver excepciones

> Revisa, prioriza y resuelve las transacciones que Matcher no pudo conciliar automáticamente con severidad, ciclo de vida y acciones aptas para auditoría.

Las excepciones son transacciones que Matcher no puede conciliar automáticamente. Esta guía muestra cómo revisar excepciones, priorizar el trabajo según la severidad y resolver elementos con el nivel de documentación adecuado.

## ¿Qué es una excepción?

***

Una excepción se crea cuando una transacción de una fuente no tiene contraparte válida en otra fuente. Entre las causas comunes están:

* **No se encontró candidato**: ninguna transacción de la otra fuente cumple los criterios de la regla activa.
* **Por debajo del umbral de confianza**: hay candidatos, pero puntúan por debajo de la confianza mínima (predeterminado: 60).
* **Rechazo por duplicado**: una coincidencia anterior fue rechazada y no queda ningún candidato alternativo.
* **Desbalance entre fuentes**: una fuente contiene transacciones que faltan en la otra.

## Ciclo de vida de la excepción

***

Las excepciones avanzan por un workflow simple:

* Cuando Matcher no puede conciliar una transacción, crea una excepción en estado `OPEN`.
* Asignar la excepción la mueve de `OPEN` a `ASSIGNED`. La API no expone una operación para desasignar. Debes enviar un `assignee` no vacío.
* Forzar coincidencia y ajustar asiento persisten `PENDING_RESOLUTION` solo mientras la operación está en curso. El éxito mueve la excepción a `RESOLVED`. El fallo la devuelve a su estado `OPEN` o `ASSIGNED` anterior.
* La resolución directa mueve una excepción `OPEN` o `ASSIGNED` a `RESOLVED`.
* El despacho envía la solicitud al conector, escribe un evento de auditoría `DISPATCH` y emite `exception.dispatched`. No cambia el estado de la excepción.

<Frame caption="El ciclo de vida de una excepción en Matcher">
  <img src="https://mintcdn.com/lerian-49cb71fc/RAVxFNT8MNA4GWjO/images/es/d2/matcher-exception-lifecycle.svg?fit=max&auto=format&n=RAVxFNT8MNA4GWjO&q=85&s=08328a511e8a64e5f68e01ceb9be4343" alt="Ciclo de vida de excepciones de Matcher" width="1068" height="1130" data-path="images/es/d2/matcher-exception-lifecycle.svg" />
</Frame>

### Definiciones de estado

| Estado               | Descripción                                    | Quién puede hacer la transición |
| -------------------- | ---------------------------------------------- | ------------------------------- |
| `OPEN`               | Excepción nueva en espera de asignación        | Sistema                         |
| `ASSIGNED`           | Asignada a un analista para investigación      | Sistema, analista               |
| `PENDING_RESOLUTION` | Forzar coincidencia o ajustar asiento en curso | Sistema                         |
| `RESOLVED`           | Cerrada con una resolución auditable           | Analista, sistema               |

### Endpoints de la máquina de estados

Los siguientes endpoints de una sola excepción cambian el ciclo de vida o registran acciones relacionadas. Cada uno se identifica con el `exceptionId` de la excepción en la ruta.

| Endpoint                     | Método y ruta                                    | Propósito                                                                                                                                                                                                                                                                 |
| ---------------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Asignar excepción            | `POST /v1/exceptions/{exceptionId}/assign`       | Asigna la excepción a un analista. Cuerpo: `assignee` (obligatorio). Devuelve la excepción actualizada. (`OPEN` → `ASSIGNED`)                                                                                                                                             |
| Despachar excepción          | `POST /v1/exceptions/{exceptionId}/dispatch`     | Envía la excepción por el conector configurado. Escribe un evento de auditoría `DISPATCH` y emite `exception.dispatched` sin cambiar el estado.                                                                                                                           |
| Resolver excepción           | `POST /v1/exceptions/{exceptionId}/resolve`      | Resuelve una sola excepción. Cuerpo: `resolution` (obligatorio), `reason` (opcional). Refleja la validación de la resolución masiva para una excepción. (`OPEN` o `ASSIGNED` → `RESOLVED`)                                                                                |
| Forzar coincidencia          | `POST /v1/exceptions/{exceptionId}/force-match`  | Resuelve una excepción con `overrideReason` y `notes`. Usa `PENDING_RESOLUTION` mientras la operación está en curso, luego resuelve o vuelve al estado anterior si falla.                                                                                                 |
| Ajustar asiento              | `POST /v1/exceptions/{exceptionId}/adjust-entry` | Resuelve una excepción creando un asiento contable de ajuste. Cuerpo: `amount`, `currency`, `effectiveAt`, `notes`, `reasonCode` (todos obligatorios). Usa `PENDING_RESOLUTION` mientras la operación está en curso, luego resuelve o vuelve al estado anterior si falla. |
| Historial de la excepción    | `GET /v1/exceptions/{exceptionId}/history`       | Devuelve el historial ordenado de transiciones de estado y acciones de la excepción (`HistoryResponse`). Admite paginación con `cursor`/`limit`. *(solo lectura)*                                                                                                         |
| Seleccionar IDs de excepción | `GET /v1/exceptions/ids`                         | Devuelve el conjunto completo de IDs de excepción que coinciden con los filtros actuales (`contextId`, `status`, `severity`, `reason`, …). Úsalo para preparar una selección masiva antes de llamar a los endpoints masivos. *(solo lectura)*                             |

<Note>
  Matcher admite el despacho `WEBHOOK`, `JIRA`, `SERVICENOW` y `MANUAL`. `WEBHOOK` requiere una URL provista por el despliegue y, cuando se requieren payloads firmados, un secreto compartido. JIRA y ServiceNow requieren su configuración de conector. `MANUAL` confirma el despacho localmente sin llamar a un sistema externo. Un conector ausente devuelve `MTCH-0509`. Un despacho no confirmado devuelve `MTCH-0514`, así que verifica el destino antes de reintentar porque puede que ya exista un registro de destino. Consulta [Enrutamiento de excepciones](/es/products/matcher/configuration/matcher-exception-routing) para el contrato de despacho completo.
</Note>

<Tip>
  Referencia de API:

  * [Asignar excepción](/es/reference/products/matcher/assign-exception)
  * [Despachar excepción](/es/reference/products/matcher/dispatch-exception)
  * [Resolver excepción](/es/reference/products/matcher/resolve-exception)
  * [Forzar coincidencia](/es/reference/products/matcher/force-match-exception)
  * [Ajustar asiento](/es/reference/products/matcher/adjust-entry-exception)
  * [Obtener historial de la excepción](/es/reference/products/matcher/retrieve-exception-history)
  * [Seleccionar IDs de excepción](/es/reference/products/matcher/select-exception-ids)
</Tip>

#### Ejemplo de asignación

```bash cURL theme={null}
curl -X POST "https://api.matcher.example.com/v1/exceptions/{exceptionId}/assign" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{ "assignee": "john.doe@company.com" }'
```

#### Ejemplo de resolución

```bash cURL theme={null}
curl -X POST "https://api.matcher.example.com/v1/exceptions/{exceptionId}/resolve" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{ "resolution": "ACCEPTED", "reason": "Variance within tolerance" }'
```

#### Ejemplo de ajuste de asiento

```bash cURL theme={null}
curl -X POST "https://api.matcher.example.com/v1/exceptions/{exceptionId}/adjust-entry" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "amount": "150.50",
   "currency": "BRL",
   "effectiveAt": "2026-02-02T16:40:00Z",
   "reasonCode": "AMOUNT_CORRECTION",
   "notes": "Correcting processing fee discrepancy"
 }'
```

#### Selección masiva con `selectExceptionIDs`

```bash cURL theme={null}
curl -X GET "https://api.matcher.example.com/v1/exceptions/ids?contextId={contextId}&status=OPEN&severity=CRITICAL" \
 -H "Authorization: Bearer $TOKEN"
```

Alimenta los IDs devueltos en las [operaciones masivas](#bulk-operations) de abajo.

## Severidad de la excepción

***

Matcher clasifica las excepciones por severidad para que puedas trabajar la cola en el orden correcto.

| Severidad   | Criterio                                   |
| ----------- | ------------------------------------------ |
| **Crítica** | Monto >= 100,000 O antigüedad >= 120 horas |
| **Alta**    | Monto >= 10,000 O antigüedad >= 72 horas   |
| **Media**   | Monto >= 1,000 O antigüedad >= 24 horas    |
| **Baja**    | Todas las demás                            |

Estos umbrales repriorizan la excepción. No crean un plazo de SLA. Un callback entrante puede proporcionar `dueAt`, y los agregados del dashboard miden el cumplimiento de esos plazos provistos externamente. Define la política de tiempo de respuesta en el sistema externo que envía el callback.

### Escalamiento de severidad

La severidad se reevalúa a medida que la excepción envejece. La clasificación usa lógica OR. El umbral de monto o el de antigüedad basta para disparar una severidad mayor:

* Una excepción por debajo de 1,000 empieza como **Baja**, pero escala a **Media** después de 24 horas.
* Una excepción por debajo de 10,000 escala a **Alta** después de 72 horas.
* Cualquier excepción sin resolver escala a **Crítica** después de 120 horas.

## Métodos de resolución

***

Matcher expone tres acciones de resolución de excepciones.

### 1. Resolver directamente

Cierra una excepción con un `resolution` obligatorio y un `reason` opcional cuando no hace falta una coincidencia forzada ni un ajuste.

### 2. Forzar coincidencia

Vincula transacciones manualmente cuando confirmaste que van juntas, pero el sistema no pudo hacerlas coincidir.

**Usa Forzar coincidencia cuando:**

* La contraparte correcta existe, pero las variaciones bloquearon la coincidencia automática.
* Puedes explicar y documentar con claridad la justificación.
* La variación es esperada (comisiones, tiempos, redondeo).

<Important>
  Forzar coincidencia omite la puntuación y la lógica de reglas. Úsalo solo cuando puedes justificar la decisión por escrito.
</Important>

### 3. Crear ajuste

Crea un asiento de ajuste para registrar una variación o para balancear un elemento no conciliado.

**Códigos de motivo del ajuste:**

| Código de motivo      | Caso de uso                           |
| --------------------- | ------------------------------------- |
| `AMOUNT_CORRECTION`   | Corregir el monto de la transacción   |
| `CURRENCY_CORRECTION` | Corregir la moneda de la transacción  |
| `DATE_CORRECTION`     | Corregir la fecha efectiva            |
| `OTHER`               | Registrar otra corrección documentada |

**Reglas de validación:**

* Los montos de ajuste deben ser positivos. Una solicitud con un monto cero o negativo devuelve un error `400 Bad Request`.
* `POST /v1/exceptions/{exceptionId}/adjust-entry` requiere un código de moneda ISO 4217 válido. `POST /v1/matching/adjustments` acepta cualquier cadena de moneda no vacía y no valida la pertenencia a ISO 4217.
* `reasonCode` debe usar `AMOUNT_CORRECTION`, `CURRENCY_CORRECTION`, `DATE_CORRECTION` u `OTHER`.

## Registros de resolución

***

Matcher registra las acciones de resolución admitidas en el historial de la excepción y en el stream de auditoría.

| Resolución          | Campos de la solicitud                                     |
| ------------------- | ---------------------------------------------------------- |
| Resolución directa  | `resolution` (obligatorio), `reason` (opcional)            |
| Forzar coincidencia | `overrideReason`, `notes`                                  |
| Ajustar asiento     | `reasonCode`, `amount`, `currency`, `effectiveAt`, `notes` |

Matcher no expone contratos de resolución de división de excepciones ni de baja contable independiente, y no aplica umbrales de aprobación basados en montos para estas acciones. Aplica cualquier requisito de aprobación adicional mediante los controles de tu organización.

<h2 id="bulk-operations">
  Operaciones masivas
</h2>

***

Cuando manejas grandes volúmenes de excepciones, los endpoints masivos permiten procesar hasta 100 excepciones en una sola solicitud.

### Asignación masiva

Asigna varias excepciones a un integrante del equipo de una vez:

```bash cURL theme={null}
curl -X POST "https://api.matcher.example.com/v1/exceptions/bulk/assign" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "exceptionIds": ["019c96a0-2a10-7dfe-b5c1-8a1b2c3d4e5f", "019c96a0-2b20-7123-9a1b-2c3d4e5f6a7b"],
   "assignee": "john.doe@company.com"
 }'
```

<Tip>
  Referencia de API:

  * [Asignación masiva](/es/reference/products/matcher/bulk-assign-exceptions)
  * [Resolución masiva](/es/reference/products/matcher/bulk-resolve-exceptions)
  * [Despacho masivo](/es/reference/products/matcher/bulk-dispatch-exceptions)
</Tip>

### Resolución masiva

Resuelve varias excepciones con una resolución compartida:

```bash cURL theme={null}
curl -X POST "https://api.matcher.example.com/v1/exceptions/bulk/resolve" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "exceptionIds": ["019c96a0-2a10-7dfe-b5c1-8a1b2c3d4e5f", "019c96a0-2b20-7123-9a1b-2c3d4e5f6a7b"],
   "resolution": "ACCEPTED",
   "reason": "Verified as valid bank fees"
 }'
```

La respuesta incluye los arreglos `succeeded` y `failed`, para que puedas manejar los fallos parciales de forma controlada.

### Despacho masivo

Despacha varias excepciones a un sistema externo:

```bash cURL theme={null}
curl -X POST "https://api.matcher.example.com/v1/exceptions/bulk/dispatch" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "exceptionIds": ["019c96a0-2a10-7dfe-b5c1-8a1b2c3d4e5f"],
   "targetSystem": "WEBHOOK",
   "queue": "RECON-TEAM"
 }'
```

## Comentarios de la excepción

***

Los comentarios dan a cada excepción un registro de auditoría de notas de investigación y discusión del equipo. Agrega un comentario mientras un analista trabaja un elemento:

```bash cURL theme={null}
curl -X POST "https://api.matcher.example.com/v1/exceptions/{exceptionId}/comments" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "content": "Contacted bank to verify wire transfer fee. Awaiting confirmation."
 }'
```

El listado (`GET`) devuelve el hilo completo ordenado del más antiguo al más reciente. No puedes agregar comentarios después de que una excepción se resuelve. Solo el autor del comentario puede eliminarlo, y el comentario debe pertenecer a la excepción identificada en la URL.

| Acción              | Método y ruta                                              | Campos clave                                                   |
| ------------------- | ---------------------------------------------------------- | -------------------------------------------------------------- |
| Agregar comentario  | `POST /v1/exceptions/{exceptionId}/comments`               | `content` (cuerpo del comentario)                              |
| Listar comentarios  | `GET /v1/exceptions/{exceptionId}/comments`                | — (devuelve el hilo completo, del más antiguo al más reciente) |
| Eliminar comentario | `DELETE /v1/exceptions/{exceptionId}/comments/{commentId}` | `commentId` en la ruta                                         |

<Tip>
  Referencia de API:

  * [Listar comentarios](/es/reference/products/matcher/list-exception-comments)
  * [Agregar comentario](/es/reference/products/matcher/add-exception-comment)
  * [Eliminar comentario](/es/reference/products/matcher/delete-exception-comment)
</Tip>

## Disputas

***

Cuando una excepción necesita investigación formal o involucra a un tercero (un chargeback, una consulta bancaria), escálala a una **disputa**. Las disputas registran la evidencia, los cambios de estado y el resultado final. Lista las disputas con `GET /v1/disputes` (filtra por `state`, p. ej. `OPEN`) o recupera una por su `disputeId`.

<Tip>
  Referencia de API:

  * [Listar disputas](/es/reference/products/matcher/list-disputes)
  * [Obtener disputa](/es/reference/products/matcher/retrieve-dispute)
  * [Abrir disputa](/es/reference/products/matcher/open-dispute)
  * [Cerrar disputa](/es/reference/products/matcher/close-dispute)
</Tip>

### Estados y transiciones de la disputa

Una disputa tiene cinco estados: `DRAFT`, `OPEN`, `PENDING_EVIDENCE`, `WON` y `LOST`. El flujo **no** es estrictamente lineal:

* `PENDING_EVIDENCE` es **opcional**. Una disputa `OPEN` puede pasar directamente a `WON` o `LOST` sin llegar a recolectar evidencia.
* Una disputa `LOST` se puede **reabrir** a `OPEN`.
* `WON` es terminal.

El conjunto completo de transiciones válidas:

| Estado de origen   | Estados siguientes permitidos     | Notas                                                       |
| ------------------ | --------------------------------- | ----------------------------------------------------------- |
| `DRAFT`            | `OPEN`                            | La disputa se abre para investigación                       |
| `OPEN`             | `PENDING_EVIDENCE`, `WON`, `LOST` | Puede resolverse directamente o pedir evidencia primero     |
| `PENDING_EVIDENCE` | `OPEN`, `WON`, `LOST`             | Vuelve a `OPEN` o se resuelve una vez revisada la evidencia |
| `WON`              | *(ninguno)*                       | Estado terminal                                             |
| `LOST`             | `OPEN`                            | Una disputa perdida se puede reabrir                        |

## Workflow de resolución de excepciones

***

Usa este flujo para mantener las revisiones consistentes y aptas para auditoría.

<Steps>
  <Step title="Triaje">
    Revisa la cola por severidad y SLA. Empieza con Crítica y Alta.
  </Step>

  <Step title="Investigar">
    Usa el payload de la excepción para entender qué falló y qué candidatos existen.

    * Lee `reason_details` para ver por qué falló la coincidencia.
    * Revisa `candidates` en busca de coincidencias cercanas por debajo del umbral.
    * Busca patrones (misma contraparte, formatos de referencia recurrentes).
  </Step>

  <Step title="Resolver">
    Elige la resolución que mejor refleje la realidad y la política.

    * **Resolver directamente**: puedes cerrar la excepción sin una coincidencia forzada ni un ajuste.
    * **Forzar coincidencia**: encontraste la contraparte correcta.
    * **Ajustar**: necesitas un asiento de ajuste para la variación.
  </Step>

  <Step title="Documentar">
    Captura suficiente detalle para que otra persona pueda reproducir tu decisión después:

    * Qué revisaste
    * Qué concluiste
    * Enlaces o IDs de la evidencia de soporte
  </Step>

  <Step title="Despachar si hace falta">
    Si la excepción requiere manejo externo, despáchala por un conector configurado. El despacho registra la acción pero no cambia el estado de la excepción. `WEBHOOK` requiere una URL provista por el despliegue. JIRA y ServiceNow requieren su configuración de conector. Si un conector devuelve `MTCH-0514`, verifica el destino antes de reintentar porque puede que ya exista un registro de destino.
  </Step>
</Steps>

## Mejores prácticas

***

<AccordionGroup>
  <Accordion title="Trabaja por severidad y SLA">
    Empieza con los elementos Crítica y Alta. Llevan el mayor riesgo y los plazos más ajustados.
  </Accordion>

  <Accordion title="Haz que las decisiones sean auditables">
    Las notas no son opcionales. Trátalas como parte de la resolución:

    * Qué revisaste
    * Por qué esta resolución es correcta
    * Cualquier ID de ticket, extracto o confirmación
  </Accordion>

  <Accordion title="Corrige los patrones en la fuente">
    Las excepciones repetidas suelen apuntar a problemas de configuración:

    * Misma contraparte → Normaliza nombres o mapeo
    * Misma ventana de fechas → Valida la integridad de la ingesta
    * Misma fuente → Revisa el mapeo de campos y las convenciones de signo
  </Accordion>

  <Accordion title="Trata las coincidencias forzadas como excepciones a la regla">
    Si fuerzas coincidencias con regularidad, tus reglas o tolerancias necesitan atención.
  </Accordion>

  <Accordion title="Asigna el trabajo de forma explícita">
    Asigna las excepciones mediante los endpoints de asignación. Matcher no aplica reglas de asignación automáticamente.
  </Accordion>
</AccordionGroup>

## Próximos pasos

***

<Card title="Generar informes" icon="chart-pie" href="/es/products/matcher/daily-reconciliation/matcher-generating-reports" horizontal>
  Crea informes de conciliación, exporta resultados y da soporte a las auditorías.
</Card>

<Card title="Enrutamiento de excepciones" icon="route" href="/es/products/matcher/configuration/matcher-exception-routing" horizontal>
  Revisa los conceptos de severidad, SLA y enrutamiento para las excepciones.
</Card>
