# Conexiones

> El vínculo con un sistema para un contribuyente o titular concreto: la unidad con la que Connect autoriza, sincroniza y factura.



Una **conexión** (id `conn_…`) une tu organización con un sistema para un contribuyente o titular concreto: el SII de Comercial Aurora SpA, la cuenta bancaria de esa misma empresa o el acceso personal de alguien al Poder Judicial. Es la unidad de autorización (sus tools autorizan contra ella), de sincronización (los datos persistidos cuelgan de ella) y de facturación. Una organización puede tener varias conexiones del mismo sistema, por ejemplo al SII de dos contribuyentes distintos. Cada una conserva su propia credencial, sus datos y su historial.

Los conectores de referencia (`core`, `indicadores`) y el de plataforma (`conexiones`) no tienen conexión: sus datos son globales o son el plano de control de Connect sobre sí mismo, y por eso sus tools no piden `connectionId`. Todo lo demás (SII, bancos) existe únicamente a través de una conexión.

## Reconocer una conexión en el panel [#reconocer-una-conexión-en-el-panel]

El menú lateral y la lista de Conexiones muestran el nombre de cada conexión y, cuando está disponible, su RUT como dato complementario. Ese RUT identifica al contribuyente o al titular del acceso, según el sistema. Así puedes distinguir conexiones con nombres como `SII` y `SII 2`. En el menú lateral, si todavía no hay un RUT guardado, aparece solo el nombre.

Puedes cambiar el nombre desde los **Ajustes** de la conexión para reconocerla con una etiqueta propia. El RUT se muestra por separado: al confirmar una eliminación, escribe el nombre exacto de la conexión.

## El ciclo de vida [#el-ciclo-de-vida]

`conexiones.estado.consultar` (y la pantalla [Conexiones](https://connect.emisso.ai/connections) del dashboard) muestra tres ejes por conexión: el estado de la conexión, el de su credencial y la cadencia de sincronización.

**Estado de la conexión:**

| Estado     | Qué significa                                                                                                                                                                      | Cómo se sale                                                                                                  |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| `active`   | Operativa: sus tools autorizan y la sincronización programada corre. Una conexión creada desde el dashboard o el flujo hosted nace en este estado.                                 | Deshabilitándola o eliminándola.                                                                              |
| `disabled` | Apagada a mano. Toda tool de la conexión responde `403 connection_disabled`, y la conexión deja de devengar facturación desde ese momento. Los datos ya sincronizados no se tocan. | Reactivándola en el dashboard. Ambos cambios quedan auditados (`connection.enabled` / `connection.disabled`). |
| `pending`  | Creada pero todavía no operativa. En la práctica es raro verla: los flujos de alta dejan la conexión activa de inmediato.                                                          | Completando el alta (entregar la credencial) o eliminándola.                                                  |

**Estado de la credencial:**

| Credencial | Qué significa                                                                                                                             | Cómo se sale                                                                          |
| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| `linked`   | Vinculada y utilizable. `verificadaEn` registra la última verificación exitosa contra el sistema.                                         | Es el estado normal.                                                                  |
| `invalid`  | El sistema rechazó el último login: la clave cambió o venció. A la tercera falla consecutiva, la sincronización programada se pausa sola. | Reconectando (abajo). Un login posterior que funciona también la devuelve a `linked`. |
| `revoked`  | Anulada de forma explícita: el vault se niega a entregarla aunque siga cifrada en la base.                                                | Entregando la credencial de nuevo.                                                    |
| `ausente`  | La conexión no tiene credencial guardada.                                                                                                 | Entregándola: por enlace de conexión o en los ajustes del dashboard.                  |

**Cadencia:** `off`, `daily`, `12h`, `6h` o `4h`. No se configura en ninguna parte, ni por API ni desde el dashboard: la decide Connect por conector y toda conexión activa la tiene. Hoy es `4h` en todos los conectores que sincronizan, sin importar el plan (la excepción es [Previred](/docs/sistemas/previred), que no sincroniza solo entre el 10 y el 13 de cada mes). Si necesitas una frecuencia de actualización mayor, escríbenos a [contacto@tryemisso.com](mailto:contacto@tryemisso.com) y te preparamos una propuesta. El único camino a `off` es el auto-pause por credencial inválida, que recuerda la cadencia anterior: arreglar la clave la restaura sola, sin que nadie reconfigure nada.

## `connectionId` es obligatorio, incluso con una sola conexión [#connectionid-es-obligatorio-incluso-con-una-sola-conexión]

Toda tool de un conector con conexión exige decir cuál: header `X-Connect-Connection` en REST, campo `connectionId` de `execute` en MCP, `opts.connectionId` en el SDK. No hay resolución implícita ni cuando existe exactamente una, y es deliberado: la conexión ES la empresa, y una elección implícita que hoy acierta porque hay una sola, mañana acierta distinto sin que nadie haya cambiado nada. Con dos conexiones de un banco, «la conexión» es ambigua entre dos RUT; con una, es una afirmación silenciosa que nadie escribió.

Omitirlo no cuesta una adivinanza, porque el error lo explica:

```bash
curl -X POST https://connect.emisso.ai/api/v1/tools/sii.rcv.consultar/execute \
  -H "Authorization: Bearer connect_sk_..." \
  -H "Content-Type: application/json" \
  -d '{"input": {"periodo": "2026-07"}}'
```

Respuesta (`400`):

```json
{
  "error": {
    "code": "validation_error",
    "message": "'sii.rcv.consultar' requiere una conexión concreta.",
    "suggested_fix": "Pasa el connectionId de la conexión de 'sii' (MCP: campo 'connectionId' de execute; REST: header 'X-Connect-Connection'). Lístalos con la tool 'conexiones.estado.consultar'.",
    "request_id": "req_..."
  },
  "meta": {
    "request_id": "req_...",
    "tool_id": "sii.rcv.consultar",
    "plane": "action",
    "latency_ms": 2,
    "audit_status": "recorded"
  }
}
```

El id sale de `conexiones.estado.consultar` (o de `GET /v1/connections`). Para la historia que cuentan estas páginas, `conn_9tKfR2mQx4Vb` es la conexión SII de Comercial Aurora SpA (RUT 77.123.456-9).

## Reconectar [#reconectar]

Cuando la clave del sistema cambia o vence, la credencial queda `invalid` y el camino es **rotarla sobre la misma conexión**, nunca crear una segunda. Tres vías:

* **Por agente:** `conexiones.enlace.crear` con `{"sistema": "sii", "modo": "reconectar", "conexionId": "conn_9tKfR2mQx4Vb"}` devuelve un enlace de un solo uso para que la persona entregue la clave nueva. El enlace de reconexión vence en 1 hora: se emite con la persona presente.
* **Por API:** `POST /v1/connect_sessions` con `mode: "reauth"` y `connection_id` ([flujo hosted](/docs/operar/enlace-hosted)).
* **En el dashboard:** los ajustes de la conexión piden la credencial completa de nuevo. No hay prefill: el secreto se guarda como un solo blob cifrado y el dashboard no tiene camino de descifrado.

La rotación reemplaza el cifrado sobre la misma conexión y dispara la verificación contra el sistema (`conexion.verificar`); si el auto-pause había apagado la cadencia, arreglar la clave la restaura. El historial, los datos sincronizados y el `conn_…` no cambian.

## Deshabilitar y eliminar [#deshabilitar-y-eliminar]

**Deshabilitar** es el interruptor reversible: la conexión queda en `disabled`, sus tools responden `403 connection_disabled`, deja de devengar facturación y nada se borra. Sirve para pausar un sistema sin perder nada de lo sincronizado.

Se pausa y se reanuda desde la fila de la conexión en el dashboard, o por agente o API:

* [`conexiones.conexion.deshabilitar`](/docs/referencia/conexiones/conexion-deshabilitar) con `{"conexionId": "conn_9tKfR2mQx4Vb"}` la pausa. Exige el permiso `conexiones:disable`.
* [`conexiones.conexion.habilitar`](/docs/referencia/conexiones/conexion-habilitar) con el mismo input la reanuda. Exige `conexiones:enable`. La conexión vuelve a sumarse al cobro: si la organización ya usa las conexiones que incluye su plan, la respuesta trae `costoAdicional` con lo que suma. Durante la prueba respeta el máximo de conexiones activas, y con la cobranza pendiente se rechaza como cualquier alta.

Las dos van por `execute_write` en MCP y por `POST /v1/tools/<tool>/execute` en REST. Pedir el estado que la conexión ya tiene no cambia nada y responde `cambiada: false`. Una conexión `pending`, que todavía no tiene credencial, no se habilita: se completa con [`conexiones.enlace.crear`](/docs/referencia/conexiones/enlace-crear) en modo `reconectar`.

**Eliminar** destruye la credencial cifrada, los datos sincronizados de esa conexión, sus programaciones y trabajos de sincronización y sus webhooks. La [bitácora](/docs/conceptos/bitacora) y el registro de cambios de configuración se conservan como registros inmutables de auditoría y facturación; sus filas mantienen el `connection_id` de la conexión eliminada.

Se elimina por dos vías, con las mismas reglas:

* **En el dashboard:** los ajustes de la conexión, escribiendo su nombre exacto para confirmar. Solo un owner o admin puede hacerlo.
* **Por agente o API:** [`conexiones.conexion.eliminar`](/docs/referencia/conexiones/conexion-eliminar) con `{"conexionId": "conn_9tKfR2mQx4Vb", "confirmarNombre": "Comercial Aurora SpA"}`. Por MCP va por `execute_write`; por REST, `POST /v1/tools/conexiones.conexion.eliminar/execute`. Exige el permiso `conexiones:delete`, que es aparte de `conexiones:write`: una clave que crea enlaces no puede borrar conexiones. Con un token OAuth, la persona que lo autorizó tiene que seguir siendo owner o admin. La respuesta dice cuántos registros, sincronizaciones y webhooks se borraron.

<Callout type="warn" title="Eliminar no tiene vuelta atrás">
  Recrear la conexión, incluso con el mismo nombre y la misma credencial, produce un `conn_` nuevo al que no se le puede re-adosar nada de lo anterior: el cifrado de los datos ata cada fila a la conexión original. Por eso la confirmación exige el nombre exacto de la conexión: si `confirmarNombre` no coincide carácter por carácter, no se borra nada y el error trae el nombre correcto. Si hay una sincronización en vuelo, la operación responde `connection_busy` (reintentable) en vez de borrar debajo de un trabajo corriendo.
</Callout>

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

* [Conectar un sistema](/docs/empezar/conectar): crear tu primera conexión de punta a punta.
* [Sincronizar y consultar](/docs/conceptos/sincronizar-consultar): qué hacer con la conexión ya activa.
* [El flujo hosted](/docs/operar/enlace-hosted): pedirle la credencial a quien de verdad la tiene.
