# BCI PyME

> Conecta el portal de empresas de BCI y obtén saldos y movimientos en una caché que se consulta al instante, sin tocar al banco.



El conector `bci_pyme` entra al portal Banco en Línea de BCI con la clave de la empresa, guarda saldos y movimientos en el plano persistido de Connect, y los sirve con dos tools de consulta que responden al instante. La conexión es la empresa: toda llamada lleva su `conn_…` (en REST, el header `X-Connect-Connection`).

## Qué necesitas para conectar [#qué-necesitas-para-conectar]

El [enlace de conexión](/docs/empezar/conectar) pide la **Clave de internet** del portal, en tres campos:

| Campo             | Qué es                                                |
| ----------------- | ----------------------------------------------------- |
| RUT de acceso     | El RUT de la persona que inicia sesión en el portal.  |
| Clave             | Su clave de internet de BCI.                          |
| RUT de la empresa | La empresa (el convenio) que esta conexión va a leer. |

El RUT de acceso y el RUT de la empresa son datos distintos a propósito: un mismo acceso puede administrar varias empresas. Cuando el portal ofrece más de un convenio, el conector elige el que coincide con el RUT de la empresa; y cuando ofrece uno solo, verifica igual que sea el configurado. Si no coinciden, la verificación falla pidiendo revisar ese campo, nunca sincroniza una empresa distinta en silencio.

El acceso es de solo lectura y se revoca al instante desde el dashboard. La clave la entrega quien la tiene, por el enlace de un solo uso: no pasa por tu código ni por el chat de un agente.

## Los alcances [#los-alcances]

| Alcance       | Qué trae                                                                                                       | Tool que lo lee                  |
| ------------- | -------------------------------------------------------------------------------------------------------------- | -------------------------------- |
| `saldos`      | Los cuatro saldos de cada cuenta (contable, disponible, contable a las 9AM y retención), como una foto por día | `bci_pyme.saldos.consultar`      |
| `movimientos` | Los movimientos del período, con contraparte, categoría, mnemónico y saldo arrastrado                          | `bci_pyme.movimientos.consultar` |

Los alcances se habilitan por conexión, desde el dashboard. Consultar un alcance apagado responde `403 alcance_not_enabled`.

## Sincronizar [#sincronizar]

Pide los alcances que necesites en la misma llamada: es un solo login contra el banco, y ese login toma cerca de 90 segundos.

```bash
curl -X POST https://connect.emisso.ai/api/v1/tools/bci_pyme.conexion.sincronizar/execute \
  -H "Authorization: Bearer connect_sk_..." \
  -H "X-Connect-Connection: conn_9tKfR2mQx4Vb" \
  -H "Content-Type: application/json" \
  -d '{"input":{"periodo":"2026-07","alcances":["saldos","movimientos"]}}'
```

Respuesta (recortada):

```json
{
  "data": {
    "periodo": "2026-07",
    "results": [
      {
        "alcance": "saldos",
        "status": "ok",
        "recordsSynced": 0,
        "detalle": "Los saldos son una foto del momento, no del período, así que solo se sincronizan en el período corriente. Este cero NO significa que la cuenta no tenga saldo: pediste 2026-07; pide 2026-08 para obtenerlo."
      },
      { "alcance": "movimientos", "status": "ok", "recordsSynced": 2 }
    ]
  },
  "meta": { "request_id": "req_...", "tool_id": "bci_pyme.conexion.sincronizar", "plane": "read" }
}
```

Aquí se pidió julio siendo agosto el período corriente: `movimientos` sincroniza ese mes, y `saldos` devuelve cero con la explicación en `detalle`, porque los saldos son una foto del momento y solo se sincronizan pidiendo el período corriente. En el período corriente ambos alcances traen datos.

Si no quieres bloquear tu proceso durante el login, encola el trabajo por la [API de control](/docs/api-control) y entérate del resultado por [webhook](/docs/operar/webhooks).

## Verdades operativas [#verdades-operativas]

### El banco admite una sola sesión activa por usuario [#el-banco-admite-una-sola-sesión-activa-por-usuario]

Entrar al portal corta la sesión de quien esté adentro, en ambas direcciones: una sincronización puede expulsar a la persona que está mirando la cartola en el navegador, y esa persona, al entrar, puede botar una sincronización en curso. Cuando le pasa al conector, el fallo se clasifica como `upstream_error` (reintentable), con la instrucción de reintentar en unos minutos sin nadie más usando ese acceso: las credenciales siguen buenas y no hay que reconectar nada.

Dos prácticas evitan el choque: una credencial dedicada para Connect (que ninguna persona use para navegar el portal) y una cadencia programada en un horario sin actividad. La cadencia (diaria, cada 12 o cada 6 horas) queda anclada a la hora en que la activas, así que activarla de noche la deja corriendo de noche.

### El corte de 1000 movimientos por consulta [#el-corte-de-1000-movimientos-por-consulta]

El endpoint del banco entrega a lo más los 1000 movimientos más recientes de una cuenta para el mes pedido: es el mismo tope de su propia interfaz, que sobre esa cifra ofrece exportar por Excel. Cuando una cuenta lo alcanza, el conector persiste igual todo lo que trajo y marca ese alcance con `error: "movimientos_truncated"` en el resultado del sync. Al consultar, el campo `completo` traduce ese estado: `true` significa que el último sync de ese período trajo todo, `false` que faltan filas del mes, y `null` (cuando consultas sin filtro de período) significa que no se sabe.

### Débito y crédito van por el libro del banco [#débito-y-crédito-van-por-el-libro-del-banco]

`type` clasifica cada movimiento al revés de como se lee una cartola: un abono (letra `A` del banco) es plata que entra y sale como `debit`; un cargo (letra `C`) es plata que sale y va como `credit`. `monto` es la magnitud sin signo y `display` trae ese monto formateado a la chilena con el signo ya aplicado, listo para mostrar. Los saldos no llevan `type`: son balances y conservan su propio signo, así que un sobregiro es negativo.

### Las correcciones del banco entran como fila nueva [#las-correcciones-del-banco-entran-como-fila-nueva]

La identidad de un movimiento es una huella de su contenido, así que cuando el banco corrige un movimiento ya sincronizado, la corrección entra como una fila nueva en vez de reemplazar la anterior. Ante dos filas del mismo hecho, vale la de `ultimaLecturaEn` mayor: ese campo viaja en cada fila justamente para eso.

## Errores que vas a ver [#errores-que-vas-a-ver]

| Código                               | Qué significa                                                                           | Qué hacer                                                                                         |
| ------------------------------------ | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| `428 connection_credential_required` | La conexión no tiene una credencial viva: nunca se vinculó, venció o fue revocada.      | Emite un enlace de reconexión y pide la clave de nuevo. No reintentes con la credencial anterior. |
| `409 connection_busy`                | Otra operación tiene tomado el candado de esta conexión (por ejemplo un sync en curso). | Espera unos segundos y reintenta: el candado se suelta solo.                                      |
| `409 connection_sync_in_progress`    | Ya corre una sincronización de esa conexión para ese período.                           | Espera a que termine, o consulta directamente: puede que ya haya datos.                           |
| `502 upstream_error`                 | El banco falló o cerró la sesión a mitad del login (típico de la sesión única).         | Reintenta más tarde, idealmente sin nadie más usando ese acceso.                                  |

El detalle de cada código, con su envelope, está en el [catálogo de errores](/docs/operar/errores).

## Próximos pasos [#próximos-pasos]

* El contrato completo de las cuatro tools: [referencia de `bci_pyme`](/docs/referencia/bci_pyme).
* Por qué leer son dos pasos y qué implica: [Sincronizar y consultar](/docs/conceptos/sincronizar-consultar).
* Enterarte de cada sync sin sondear: [Webhooks](/docs/operar/webhooks).
