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

# Subir archivos

> Importa datos de transacciones a Matcher desde CSV, JSON, XML o formatos bancarios como camt.053. Previsualiza la detección de columnas y luego sube los archivos a una fuente.

Esta guía cubre cómo importar datos de transacciones de fuentes externas a Matcher para la conciliación.

## Formatos admitidos

***

Matcher acepta archivos de transacciones en tres formatos de propósito general:

* **CSV**: valores separados por comas con encabezados. El más común para exportaciones bancarias.
* **JSON**: arreglo de objetos de transacción. El mejor para integraciones de API.
* **XML**: elementos estructurados. Común para sistemas empresariales.

Más allá de estos, el endpoint de carga también acepta formatos bancarios especializados como `camt053` y las claves de descriptor con namespace del catálogo de formatos (CNAB, layouts de adquirentes). Consulta [Formatos de importación](/es/products/matcher/imports/matcher-import-formats) para el catálogo completo.

## Requisitos de estructura del archivo

***

Cada archivo debe contener registros de transacciones con campos que puedas mapear al esquema interno de Matcher.

### Campos obligatorios

Cada transacción debe tener estos campos (o equivalentes mapeables):

| Campo            | Tipo          | Descripción                                   |
| ---------------- | ------------- | --------------------------------------------- |
| `transaction_id` | String        | Identificador único dentro de la fuente       |
| `amount`         | Decimal       | Monto de la transacción (positivo o negativo) |
| `currency`       | String        | Código de moneda ISO 4217                     |
| `date`           | Date/DateTime | Fecha de la transacción                       |

### Campos opcionales

| Campo          | Tipo   | Descripción                                 |
| -------------- | ------ | ------------------------------------------- |
| `reference`    | String | Referencia externa o descripción            |
| `counterparty` | String | La otra parte de la transacción             |
| `type`         | String | Tipo de transacción (crédito, débito, etc.) |
| `metadata`     | Object | Campos personalizados adicionales           |

## Ejemplos de formato

***

### CSV

**Requisitos de CSV:**

* La primera fila debe ser de encabezados de columna
* Codificación UTF-8
* Delimitador de coma (configurable)
* Entrecomilla los campos que contienen comas o saltos de línea

**Ejemplo de código**

```csv theme={null}
 transaction_id,amount,currency,date,reference,type
 BANK-2024-001,1500.00,USD,2024-01-15,Invoice #1234,credit
 BANK-2024-002,-250.00,USD,2024-01-15,Service fee,debit
 BANK-2024-003,3200.50,USD,2024-01-16,Customer payment,credit
 BANK-2024-004,-89.99,USD,2024-01-16,Subscription,debit
```

### JSON

**Requisitos de JSON:**

* El elemento raíz debe ser un arreglo
* Nombres de campo consistentes entre objetos
* Codificación UTF-8

**Ejemplo de código**

```json theme={null}
[
  {
    "transaction_id": "BANK-2024-001",
    "amount": 1500.0,
    "currency": "USD",
    "date": "2024-01-15",
    "reference": "Invoice #1234",
    "type": "credit"
  },
  {
    "transaction_id": "BANK-2024-002",
    "amount": -250.0,
    "currency": "USD",
    "date": "2024-01-15",
    "reference": "Service fee",
    "type": "debit"
  }
]
```

### XML

**Requisitos de XML:**

* XML válido con declaración
* Elemento raíz que contiene elementos de transacción
* Codificación UTF-8

**Ejemplo de código**

```xml theme={null}
  <?xml version="1.0" encoding="UTF-8"?>
  <transactions>
    <transaction>
      <transaction_id>BANK-2024-001</transaction_id>
      <amount>1500.00</amount>
      <currency>USD</currency>
      <date>2024-01-15</date>
     <reference>Invoice #1234</reference>
      <type>credit</type>
    </transaction>
    <transaction>
      <transaction_id>BANK-2024-002</transaction_id>
      <amount>-250.00</amount>
      <currency>USD</currency>
      <date>2024-01-15</date>
      <reference>Service fee</reference>
      <type>debit</type>
      </transaction>
  </transactions>
```

## Carga mediante la API

***

Usa el endpoint de importación para subir archivos de transacciones.

### Previsualiza antes de subir

Antes de confirmar un archivo para la ingesta, puedes previsualizarlo para verificar la detección de columnas y los datos de muestra. Esto ayuda a detectar problemas de mapeo de campos a tiempo.

```bash cURL theme={null}
curl -X POST "https://api.matcher.example.com/v1/imports/contexts/{contextId}/sources/{sourceId}/preview" \
 -H "Authorization: Bearer $TOKEN" \
 -F "file=@bank_statement_january.csv" \
 -F "max_rows=5"
```

#### Respuesta

```json theme={null}
{
  "columns": ["transaction_id", "amount", "currency", "date", "reference"],
  "sampleRows": [
    ["BANK-2024-001", "1500.00", "USD", "2024-01-15", "Invoice #1234"],
    ["BANK-2024-002", "-250.00", "USD", "2024-01-15", "Service fee"]
  ],
  "rowCount": 2,
  "format": "csv"
}
```

<Tip>
  Referencia de API: [Previsualizar archivo](/es/reference/products/matcher/preview-upload)
</Tip>

### Carga de un solo archivo

```bash cURL theme={null}
curl -X POST "https://api.matcher.example.com/v1/imports/contexts/{contextId}/sources/{sourceId}/upload" \
 -H "Authorization: Bearer $TOKEN" \
 -F "format=csv" \
 -F "file=@bank_statement_january.csv"
```

<Info>
  Envía el campo `format` **antes** de la parte `file`. Si `file` llega primero, Matcher infiere el formato a partir de la extensión del nombre de archivo solo para `.csv` y `.json`. Matcher nunca infiere `.xml`, porque es una familia de formatos que cubre XML simple y camt.053. Envía el campo `format` explícito para XML. Matcher rechaza la carga sin él. La carga devuelve **202 Accepted** con el job creado.
</Info>

<Note>
  El límite de carga es **1 GiB** de forma predeterminada y aplica a toda la solicitud multipart, con cada parte, header y boundary, no solo al archivo. Puedes configurar `ingestion.max_upload_bytes` desde **1 MiB** hasta **8 GiB**.
</Note>

<Tip>Referencia de API: [Subir archivo](/es/reference/products/matcher/upload-transaction-file)</Tip>

#### Respuesta

```json theme={null}
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "contextId": "969a11cd-6b7d-4e71-b82b-0828e0603149",
  "sourceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "QUEUED",
  "fileName": "bank_statement_january.csv",
  "totalRows": 0,
  "persistedRows": 0,
  "droppedDuplicateRows": 0,
  "failedRows": 0,
  "failureRatePercent": 0,
  "completedWithErrors": false,
  "createdAt": "2024-01-20T10:30:00Z"
}
```

### Consultar el estado de la importación

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

<Tip>
  Referencia de API: [Obtener el estado de la importación](/es/reference/products/matcher/retrieve-ingestion-job)
</Tip>

#### Respuesta (en proceso)

```json theme={null}
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "contextId": "969a11cd-6b7d-4e71-b82b-0828e0603149",
  "sourceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "PROCESSING",
  "fileName": "bank_statement_january.csv",
  "totalRows": 1250,
  "startedAt": "2024-01-20T10:30:05Z"
}
```

#### Respuesta (completada)

```json theme={null}
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "contextId": "969a11cd-6b7d-4e71-b82b-0828e0603149",
  "sourceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "COMPLETED",
  "completedWithErrors": true,
  "fileName": "bank_statement_january.csv",
  "totalRows": 1250,
  "persistedRows": 1233,
  "droppedDuplicateRows": 12,
  "failedRows": 5,
  "failureRatePercent": 1,
  "reviewRows": 0,
  "diagnosis": "",
  "startedAt": "2024-01-20T10:30:05Z",
  "completedAt": "2024-01-20T10:30:45Z"
}
```

<Note>
  Los errores de análisis/normalización por fila **no** están incrustados en el job. Cuando `completedWithErrors` es `true` (o el job está en `FAILED`), obtén los detalles desde `GET /v1/imports/contexts/{contextId}/jobs/{jobId}/errors` (con un tope de 100 filas guardadas, con la contabilidad de `totalErrors`/`truncated`). Para un job `FAILED` por completo, `diagnosis` lleva un motivo seguro de una línea.
</Note>

### Valores de estado del job de importación

| Estado       | Descripción                                                                     |
| ------------ | ------------------------------------------------------------------------------- |
| `QUEUED`     | Job recibido, en espera de un worker                                            |
| `PROCESSING` | El archivo se está analizando y normalizando                                    |
| `COMPLETED`  | La importación terminó (revisa `completedWithErrors` para los fallos parciales) |
| `FAILED`     | La importación se abortó por completo (consulta `diagnosis`)                    |

## Validación y manejo de errores

***

Matcher valida los archivos subidos en varias etapas.

### Etapas de validación

<Steps>
  <Step title="Validación de formato">
    Verifica que el archivo sea CSV, JSON o XML válido con la estructura correcta.
  </Step>

  <Step title="Validación de esquema">
    Comprueba que los campos obligatorios estén presentes y coincidan con el mapa de campos configurado.
  </Step>

  <Step title="Validación de tipo de dato">
    Valida que los montos sean decimales válidos, que las fechas se puedan analizar y que las monedas sean códigos ISO válidos.
  </Step>

  <Step title="Validación de reglas de negocio">
    Aplica reglas específicas del contexto como rangos de fechas, límites de monto, etc.
  </Step>
</Steps>

### Errores de validación comunes

| Error                    | Causa                                   | Solución                                           |
| ------------------------ | --------------------------------------- | -------------------------------------------------- |
| `INVALID_FORMAT`         | El archivo no se puede analizar         | Revisa la codificación y la estructura del archivo |
| `MISSING_REQUIRED_FIELD` | No se encontró un campo obligatorio     | Verifica la configuración del mapeo de campos      |
| `INVALID_AMOUNT`         | El monto no es un número válido         | Busca símbolos de moneda o comas en los números    |
| `INVALID_DATE`           | La fecha no se puede analizar           | Usa el formato ISO 8601 (YYYY-MM-DD)               |
| `UNKNOWN_CURRENCY`       | El código de moneda no se reconoce      | Usa códigos ISO 4217 (USD, EUR, BRL)               |
| `DATE_OUT_OF_RANGE`      | Fecha antes/después del rango permitido | Revisa los límites de fecha del contexto           |

### Manejo de errores

De forma predeterminada, Matcher importa las filas válidas aunque algunas filas tengan errores. Configura el comportamiento del manejo de errores mediante los ajustes del contexto o maneja los errores al terminar la importación revisando la respuesta de estado del job.

## Detección de duplicados

***

Matcher detecta y maneja automáticamente las transacciones duplicadas para evitar el doble conteo.

### Cómo se detectan los duplicados

Una clave de deduplicación con alcance de fuente identifica los duplicados. De forma predeterminada es el `external_id` de la fuente. Define `duplicate_key` en el `config` de la fuente como una lista ordenada de campos mapeados (`external_id`, `amount`, `currency`, `date`, `description`, `fee_amount` o `fee_currency`) cuando necesitas una identidad compuesta. Debes mapear cada campo seleccionado. Las fuentes ligadas a un agregador no pueden declarar una clave personalizada porque sus retractaciones apuntan a `external_id`.

Si una fila repite esa clave (dentro de la misma carga o contra datos ya persistidos), Matcher la trata como duplicada. Un cambio en `duplicate_key` afecta solo a las importaciones posteriores. Las filas importadas antes conservan sus claves existentes.

### Opciones de manejo de duplicados

Define la clave `duplicate_policy` en el `config` de la fuente para controlar el manejo:

| Política                             | Comportamiento                                                                                                                                                   |
| ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `FLAG_AS_EXCEPTION` (predeterminada) | Descarta la repetición y genera una excepción `DUPLICATE_TRANSACTION` sobre la transacción que sobrevive (el subconjunto se informa como `flaggedDuplicateRows`) |
| `KEEP_FIRST`                         | Conserva la primera aparición y descarta las repeticiones en silencio, contadas en `droppedDuplicateRows`                                                        |
| `REJECT`                             | Convierte cada fila repetida en un error de fila de ingesta, contado en `failedRows`                                                                             |

Cuando `duplicate_policy` está ausente, aplica `FLAG_AS_EXCEPTION`.

### Ver los detalles de los duplicados

El resumen de la importación muestra el número de duplicados:

```json theme={null}
{
  "totalRows": 1000,
  "persistedRows": 950,
  "flaggedDuplicateRows": 50,
  "failedRows": 0,
  "failureRatePercent": 0
}
```

## Cargas por lote

***

Para jobs de conciliación grandes, puedes subir varios archivos en secuencia.

### Subir varios archivos

```bash theme={null}
# Upload bank statement
curl -X POST "https://api.matcher.example.com/v1/imports/contexts/{contextId}/sources/{bankSourceId}/upload" \
 -H "Authorization: Bearer $TOKEN" \
 -F "file=@bank_january.csv" \
 -F "format=csv"

# Upload ledger export
curl -X POST "https://api.matcher.example.com/v1/imports/contexts/{contextId}/sources/{ledgerSourceId}/upload" \
 -H "Authorization: Bearer $TOKEN" \
 -F "file=@ledger_january.csv" \
 -F "format=csv"
```

### Espera a que terminen todas las importaciones

Antes de ejecutar la coincidencia, confirma que todas las importaciones estén completas:

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

## Buscar transacciones subidas

***

Después de importar archivos, puedes buscar en todas las transacciones de un contexto para verificar la calidad de los datos o investigar registros específicos.

```bash cURL theme={null}
curl -X GET "https://api.matcher.example.com/v1/imports/contexts/{contextId}/transactions/search?q=Invoice&amount_min=1000&status=UNMATCHED" \
 -H "Authorization: Bearer $TOKEN"
```

#### Respuesta

```json theme={null}
{
  "items": [
    {
      "id": "019c96a0-2a10-7dfe-b5c1-8a1b2c3d4e5f",
      "sourceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "amount": "1500.00",
      "currency": "USD",
      "date": "2024-01-15T00:00:00Z",
      "description": "Invoice #1234",
      "status": "UNMATCHED"
    }
  ],
  "total": 1,
  "limit": 20,
  "offset": 0
}
```

<Tip>
  Referencia de API: [Buscar transacciones](/es/reference/products/matcher/search-transactions)
</Tip>

Entre los filtros admitidos están `amount_min`, `amount_max`, `date_from`, `date_to`, `currency`, `source_id`, `status` y la búsqueda de texto libre mediante el parámetro `q`.

## Mejores prácticas

***

<AccordionGroup>
  <Accordion title="Valida los archivos antes de subirlos">
    Revisa el formato y la codificación del archivo en local antes de subirlo. Esto detecta los errores obvios más rápido.

    ```bash theme={null}
    # Check CSV is valid
    head -5 transactions.csv

    # Check encoding
    file transactions.csv
    ```
  </Accordion>

  <Accordion title="Usa formatos de fecha consistentes">
    Estandariza el formato ISO 8601 (`YYYY-MM-DD` o `YYYY-MM-DDTHH:MM:SSZ`) en todas las fuentes para evitar problemas de análisis.
  </Accordion>

  <Accordion title="Incluye los IDs de transacción">
    Incluye siempre IDs de transacción únicos del sistema de origen. Esto habilita una detección de duplicados y unos registros de auditoría correctos.
  </Accordion>

  <Accordion title="Maneja los montos negativos de forma consistente">
    Decide una convención (negativo para débitos, positivo para créditos) y aplícala de forma consistente. Documéntala en tu mapeo de campos.
  </Accordion>

  <Accordion title="Sube de forma incremental los archivos grandes">
    Para archivos de más de 50 MB, considera dividirlos en trozos más pequeños por rango de fechas. Esta es una recomendación de confiabilidad, no el límite de carga, y permite reintentos parciales.
  </Accordion>

  <Accordion title="Configura cargas automatizadas">
    Para la conciliación recurrente, automatiza las cargas de archivos con jobs programados o webhooks de los sistemas de origen.

    ```bash theme={null}
    # Example: Daily upload via cron
    0 6 * * * /scripts/upload_bank_statement.sh
    ```
  </Accordion>
</AccordionGroup>

## Próximos pasos

***

<Card title="Revisar coincidencias" icon="magnifying-glass-chart" href="/es/products/matcher/daily-reconciliation/matcher-reviewing-matches" horizontal>
  Conoce cómo interpretar los resultados de coincidencia y las puntuaciones de confianza.
</Card>

<Card title="Mapeo de campos" icon="arrows-left-right" href="/es/products/matcher/configuration/matcher-field-mapping" horizontal>
  Configura cómo los campos de la fuente se mapean al esquema de Matcher.
</Card>
