# Conecta a tus clientes

> El caso plataforma, un producto que conecta a muchos clientes finales, con el modelo de datos, el alta embebida y los topes que importan a escala.



Si tu producto (un ERP, un software de gestión, una plataforma vertical) necesita leer el SII o los
bancos de muchos clientes finales, este es tu mapa. El mecanismo es el mismo de
[Conecta tu primera empresa](/docs/empezar/conectar); lo que cambia a escala es el modelo de datos,
cómo identificas a cada cliente y contra qué topes vas a operar.

## El modelo: dos niveles, no tres [#el-modelo-dos-niveles-no-tres]

```text
organización (org_…)        tu cuenta. Aquí viven tus API keys y tu facturación.
  └── conexión (conn_…)     un cliente tuyo en un sistema. La unidad de todo lo demás.
```

No existe una entidad «proyecto». Si vienes de un modelo cuenta → proyecto → enlace, el equivalente del
proyecto es la conexión, y el enlace de un solo uso es solo el permiso para entregar la credencial:
una vez consumido, lo que queda es la conexión. Una organización puede tener tantas conexiones del
mismo sistema como clientes tengas; con dos o más activas, toda llamada debe nombrar cuál con
`X-Connect-Connection` (omitirlo responde `validation_error` con la lista de candidatas en el
`suggested_fix`). El detalle del ciclo de vida está en [Conexiones](/docs/conceptos/conexiones).

## Identificar a tu cliente [#identificar-a-tu-cliente]

Las conexiones no tienen un campo `external_id` ni `metadata`, y su `display_name` lo autogenera el
servidor (`SII`, `SII 2`). **El mapeo cliente ↔ `conn_…` lo guardas tú**, y el momento de capturarlo
es el alta: el `connection_id` llega en el `postMessage` del iframe cuando la persona completa el
enlace, y en el webhook `connect_session.consumed` si tienes [webhooks](/docs/operar/webhooks)
configurados. Guarda ese par en tu base al recibirlo; después no hay endpoint para reconstruirlo
desde tu lado (solo `GET /v1/connections`, que lista ids y nombres autogenerados).

El aislamiento es por organización, no por conexión: una API key con `sii:read` puede leer cualquier
conexión del SII de tu organización, y no se puede acuñar una clave limitada a una sola conexión. Si
tu arquitectura exige muros entre clientes finales, el muro lo pones tú delante de Connect.

## El alta, dentro de tu producto [#el-alta-dentro-de-tu-producto]

`POST /v1/connect_sessions` con `allowed_origins` devuelve una URL de un solo uso que se monta en un
iframe de tu app: tu cliente escribe su clave en la pantalla de Connect sin salir de tu producto, la
credencial viaja directo al vault y el resultado te vuelve por `postMessage`, por `redirect_uri` y
por webhook. El contrato completo (orígenes, TTL, intentos, el modelo de amenaza) está en
[el enlace hosted](/docs/operar/enlace-hosted); el endpoint, en la
[API de control](/docs/api-control). Dos datos que importan a escala:

* La emisión de enlaces tiene tope por organización (60 por hora, `429` con `Retry-After`): un alta
  masiva de clientes se planifica por tandas.
* Por el carril del enlace, la primera sincronización queda encolada sola al conectar. Por el
  dashboard no: ahí el alta solo verifica la credencial.

## Cuando la credencial de un cliente se rompe [#cuando-la-credencial-de-un-cliente-se-rompe]

Te enteras por tres señales, en este orden si tienes webhooks: llega `sync.failed`, las llamadas de
esa conexión empiezan a responder `connection_credential_required` (428, con la sugerencia del SII o
del banco en el mensaje), y al tercer fallo de autenticación consecutivo la cadencia automática de esa
conexión se pausa sola y deja de encolar. La conexión sigue `active` y sus tools de consulta siguen
leyendo lo ya persistido; lo que se detiene es el reloj.

La reconexión es el mismo endpoint de enlaces con `"mode": "reauth"` y el `connection_id`: rota la
credencial sobre la misma conexión, sin duplicarla. Un detalle operativo: el enlace `reauth` no
reanuda la cadencia pausada; eso hoy se hace desde el dashboard (rotar la credencial o verificar la
conexión desde su pestaña de ajustes limpia la pausa y restaura la cadencia anterior).

## Operar la flota [#operar-la-flota]

Los topes que vas a tocar con decenas o cientos de conexiones, todos del código:

| Tope                                                                 | Valor                            |
| -------------------------------------------------------------------- | -------------------------------- |
| Trabajos de sincronización encolados más corriendo, por organización | 50 (`429 too_many_pending`)      |
| Períodos por petición de backfill                                    | 24                               |
| Ritmo de drenaje de la cola                                          | hasta 10 trabajos cada 5 minutos |
| Trabajos simultáneos por conexión                                    | 1, y uno solo activo por período |
| Enlaces de conexión por hora, por organización                       | 60                               |

El ritmo de drenaje define tu techo de sincronización: alrededor de 120 trabajos por hora. Un
backfill grande de muchos clientes se reparte en tandas y se supervisa con los webhooks `sync.*` o
con `GET /v1/syncs/{id}`, no reencolando a ciegas.

Sobre la cuota: **encolar no consume cuota**; lo que cuenta como llamada es cada sincronización
ejecutada y cada página de consulta (el detalle de categorías está en
[Límites y planes](/docs/operar/limites)). El cupo es **por conexión**, así que la aritmética de una
flota grande no se multiplica por el número de conexiones: cada una mide su propio período contra el
mismo techo, y agregar clientes no acerca a los demás al corte. Lo que hay que dimensionar por
conexión es sincronizaciones diarias × páginas leídas. Subir de plan no mueve ese techo; si tu
cadencia lo roza, escríbenos desde [connect.emisso.ai/billing](https://connect.emisso.ai/billing) y
lo ampliamos para tu organización.

## Lo que todavía se hace solo desde el dashboard [#lo-que-todavía-se-hace-solo-desde-el-dashboard]

Hoy no hay endpoint para crear organizaciones, acuñar o rotar API keys, renombrar, deshabilitar o
eliminar una conexión, ni configurar la cadencia de sincronización. Si tu integración necesita
alguna de esas operaciones por API, escríbenos: saber qué falta primero es lo que ordena el roadmap.

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

* [El enlace hosted](/docs/operar/enlace-hosted): el contrato completo del alta embebida.
* [API de control](/docs/api-control): sesiones, sincronizaciones y webhooks, endpoint por endpoint.
* [Webhooks](/docs/operar/webhooks): enterarte de cada alta y cada sync sin polling.
