Emisso Connect
Operar

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; 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

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.

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

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; el endpoint, en la API de 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

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

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

TopeValor
Trabajos de sincronización encolados más corriendo, por organización50 (429 too_many_pending)
Períodos por petición de backfill24
Ritmo de drenaje de la colahasta 10 trabajos cada 5 minutos
Trabajos simultáneos por conexión1, y uno solo activo por período
Enlaces de conexión por hora, por organización60

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). 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 y lo ampliamos para tu organización.

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

  • El enlace hosted: el contrato completo del alta embebida.
  • API de control: sesiones, sincronizaciones y webhooks, endpoint por endpoint.
  • Webhooks: enterarte de cada alta y cada sync sin polling.

On this page