Sincronizar conexión Santander
Sincroniza los alcances solicitados (saldos, movimientos) para un período en una sola sesión de portal.
| Tool ID | santander_empresas.conexion.sincronizar |
| Nombre MCP | santander_empresas__conexion__sincronizar |
| Conector | santander_empresas |
| Plano | read |
| Alcances | saldos, movimientos |
| Scope (permiso) | santander_empresas:read |
| Auth | connection_credentials |
| Versión | 2 |
| Sensible | sí |
| Deprecado | no |
| Comportamiento | readOnly=false, destructive=false, idempotent=true, openWorld=true |
Requiere conexión. Indica cuál en cada llamada: header
X-Connect-Connectionen REST y campoconnectionIden elexecute_writede MCP. No hay resolución implícita, ni siquiera con una sola conexión activa: la conexión es la empresa. El id sale deconexiones.estado.consultar.
Qué hace
'saldos' es una foto del momento, no del período: solo se sincroniza cuando se pide el período corriente.
Entrada
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
periodo | string ^\d{4}-\d{2}$ | sí | El mes que se va a sincronizar, en formato AAAA-MM y en calendario chileno (por ejemplo '2026-07'). Traer varios meses son varias llamadas, una por mes. |
alcances | lista de "saldos" · "movimientos" | sí | Qué módulos de datos traer en esta corrida, al menos uno. Todos se sincronizan sobre UNA sola sesión (un login, un logout), así que pedir varios en una llamada cuesta menos que llamar una vez por cada uno. Un alcance debe estar habilitado en la conexión; si no lo está, la llamada responde 'alcance_not_enabled'. |
JSON Schema de entrada
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"periodo": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}$",
"description": "El mes que se va a sincronizar, en formato AAAA-MM y en calendario chileno (por ejemplo '2026-07'). Traer varios meses son varias llamadas, una por mes."
},
"alcances": {
"minItems": 1,
"type": "array",
"items": {
"type": "string",
"enum": [
"saldos",
"movimientos"
]
},
"description": "Qué módulos de datos traer en esta corrida, al menos uno. Todos se sincronizan sobre UNA sola sesión (un login, un logout), así que pedir varios en una llamada cuesta menos que llamar una vez por cada uno. Un alcance debe estar habilitado en la conexión; si no lo está, la llamada responde 'alcance_not_enabled'."
}
},
"required": [
"periodo",
"alcances"
]
}Ejemplo
curl -X POST https://connect.emisso.ai/api/v1/tools/santander_empresas.conexion.sincronizar/execute \
-H "Authorization: Bearer connect_sk_…" \
-H "X-Connect-Connection: conn_9tKfR2mQx4Vb" \
-H "Content-Type: application/json" \
-d '{"input":{"periodo":"2026-08","alcances":["saldos","movimientos"]}}'{
"tool": "santander_empresas.conexion.sincronizar",
"params": {
"periodo": "2026-08",
"alcances": [
"saldos",
"movimientos"
]
},
"connectionId": "conn_9tKfR2mQx4Vb"
}Salida esperada (200):
{
"data": {
"periodo": "2026-08",
"estado": "encolado",
"jobId": "sjb_5g7h9j1k3l6z8x0c2v4b6",
"yaEnCurso": false
},
"meta": {
"request_id": "req_…",
"tool_id": "santander_empresas.conexion.sincronizar",
"plane": "read",
"latency_ms": 58240,
"audit_status": "recorded"
}
}Cada sincronización abre una sesión de Office Banking por HTTP. Los saldos y movimientos comparten el mismo login; los movimientos se paginan hasta agotar el cursor del banco.
Salida
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
periodo | string | sí | Eco del período que se pidió, para poder correlacionar la respuesta sin guardarlo tú. |
estado | "encolado" · "completado" | sí | 'encolado' = la sincronización quedó en cola y va a empezar enseguida; esta respuesta NO trae datos todavía, y el trabajo se sigue por 'jobId'. 'completado' = la sincronización ya corrió y su resumen por alcance viene en 'results'. Un cliente recibe siempre 'encolado': un sync abre una sesión real contra el sistema externo y puede tardar minutos, así que no se te hace esperar por él. |
jobId | string | null | no |
yaEnCurso | booleano | no | 'true' significa que ya había una sincronización viva para esa conexión y ese período, así que no se creó otra. No es un error ni un rechazo. Si esa sincronización sigue en cola, 'jobId' es el suyo; si ya está corriendo, 'jobId' llega null y su avance se ve en 'trabajos' de 'conexiones.estado.consultar'. Cubre el período, no necesariamente los alcances que pediste: si pediste otros, vuelve a pedirlos cuando termine. Ojo con el otro lado: 'false' NO garantiza que la hayas creado tú: dos llamadas a la vez pueden recibir las dos 'false' y el MISMO 'jobId'. Lo que sí vale siempre es que hay una sola sincronización activa por conexión y período. |
results | lista de objeto | no | El resumen por alcance, una fila por alcance sincronizado. AUSENTE cuando 'estado' es 'encolado': el trabajo todavía no corrió. Ausente no es lo mismo que vacío: un arreglo vacío significaría que se miró y no había nada. |
results[].alcance | string | sí | Cuál de los alcances pedidos describe esta fila. Hay una fila por alcance solicitado, en el orden canónico del conector, no en el orden en que los pediste. |
results[].marcador | string | no | Detalle técnico, cuando el conector pudo componer uno. En una fila que falló dice en qué paso ocurrió y qué se encontró (conteos, status HTTP, content-type); en una que terminó incompleta, qué no se pudo cubrir. Sirve para diagnosticar sin volver a reproducirlo, y nunca contiene datos del contribuyente. |
results[].status | "ok" · "failed" | sí | 'ok' = el alcance terminó bien; que 'recordsSynced' sea 0 no lo vuelve un fallo. 'failed' = no terminó bien, y la causa va en 'error'. Ojo con un 'failed': NO garantiza que no se haya escrito nada. Cuando el sistema externo trunca un listado, el alcance queda 'failed' con las filas que alcanzó en 'recordsSynced'. Mira siempre las dos cosas juntas. Y revisa fila por fila: un alcance puede fallar mientras los otros de la misma corrida terminan bien. |
results[].recordsSynced | entero | sí | Cuántos registros de este alcance escribió ESTA corrida. Es el trabajo de esta llamada, no el total acumulado que tienes guardado: para saber cuánto hay, consulta. Un 0 no significa por sí solo «no hay datos»; cuando el cero tiene una explicación, viene en 'detalle'. |
results[].error | string | no | Por qué este alcance no terminó bien. Presente solo cuando 'status' es 'failed'. Normalmente es un código del catálogo de errores; cuando el sistema externo truncó el listado es una etiqueta de resultado ('movimientos_truncated', 'cartolas_truncated') que no está en ese catálogo y que significa «se escribió lo que alcanzó a venir». Decide por el valor, nunca por el texto libre. |
results[].cuentasConsultadas | entero | no | Cuántas cuentas se alcanzaron a consultar. Un 'recordsSynced: 0' con cero cuentas no dice nada sobre el período. Con cuentas consultadas, revisa también status y cuentasSinDatosConcluyentes antes de concluir ausencia de movimientos: una respuesta web ambigua no acredita un mes sin actividad. |
results[].cuentasNoConsultadas | entero | no | Cuentas web omitidas porque el inventario de la misma sesión no acreditó su moneda. El alcance es parcial; no significa que esas cuentas carezcan de saldo o movimientos. |
results[].cuentasSinDatosConcluyentes | entero | no | Cuentas web cuya respuesta vacía fue ambigua (Status 0). El alcance es parcial y no permite concluir ausencia de movimientos; no se repite el login por esa respuesta. |
results[].detalle | string | no | Explicación en lenguaje llano, presente solo cuando el resultado necesita una. Existe para que un cero se pueda transmitir tal cual en vez de concluir «no hay datos»: transmítelo a quien pregunte en lugar de resumir el número solo. |
JSON Schema de salida
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"periodo": {
"type": "string",
"description": "Eco del período que se pidió, para poder correlacionar la respuesta sin guardarlo tú."
},
"estado": {
"type": "string",
"enum": [
"encolado",
"completado"
],
"description": "'encolado' = la sincronización quedó en cola y va a empezar enseguida; esta respuesta NO trae datos todavía, y el trabajo se sigue por 'jobId'. 'completado' = la sincronización ya corrió y su resumen por alcance viene en 'results'. Un cliente recibe siempre 'encolado': un sync abre una sesión real contra el sistema externo y puede tardar minutos, así que no se te hace esperar por él."
},
"jobId": {
"description": "El identificador de la sincronización encolada. Por la API REST, el avance se consulta en 'GET /v1/syncs/{jobId}'; por MCP, búscalo en 'trabajos' de 'conexiones.estado.consultar' y revisa 'datosListos' ahí mismo. Es el mismo id que viaja en el webhook 'sync.succeeded' o 'sync.failed' si tu plan los incluye. Es null cuando 'estado' es 'completado', porque ahí el resultado ya está en la respuesta, y cuando 'yaEnCurso' es true y esa sincronización ya está corriendo.",
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"yaEnCurso": {
"description": "'true' significa que ya había una sincronización viva para esa conexión y ese período, así que no se creó otra. No es un error ni un rechazo. Si esa sincronización sigue en cola, 'jobId' es el suyo; si ya está corriendo, 'jobId' llega null y su avance se ve en 'trabajos' de 'conexiones.estado.consultar'. Cubre el período, no necesariamente los alcances que pediste: si pediste otros, vuelve a pedirlos cuando termine. Ojo con el otro lado: 'false' NO garantiza que la hayas creado tú: dos llamadas a la vez pueden recibir las dos 'false' y el MISMO 'jobId'. Lo que sí vale siempre es que hay una sola sincronización activa por conexión y período.",
"type": "boolean"
},
"results": {
"description": "El resumen por alcance, una fila por alcance sincronizado. AUSENTE cuando 'estado' es 'encolado': el trabajo todavía no corrió. Ausente no es lo mismo que vacío: un arreglo vacío significaría que se miró y no había nada.",
"type": "array",
"items": {
"type": "object",
"properties": {
"alcance": {
"type": "string",
"description": "Cuál de los alcances pedidos describe esta fila. Hay una fila por alcance solicitado, en el orden canónico del conector, no en el orden en que los pediste."
},
"marcador": {
"description": "Detalle técnico, cuando el conector pudo componer uno. En una fila que falló dice en qué paso ocurrió y qué se encontró (conteos, status HTTP, content-type); en una que terminó incompleta, qué no se pudo cubrir. Sirve para diagnosticar sin volver a reproducirlo, y nunca contiene datos del contribuyente.",
"type": "string"
},
"status": {
"type": "string",
"enum": [
"ok",
"failed"
],
"description": "'ok' = el alcance terminó bien; que 'recordsSynced' sea 0 no lo vuelve un fallo. 'failed' = no terminó bien, y la causa va en 'error'. Ojo con un 'failed': NO garantiza que no se haya escrito nada. Cuando el sistema externo trunca un listado, el alcance queda 'failed' con las filas que alcanzó en 'recordsSynced'. Mira siempre las dos cosas juntas. Y revisa fila por fila: un alcance puede fallar mientras los otros de la misma corrida terminan bien."
},
"recordsSynced": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991,
"description": "Cuántos registros de este alcance escribió ESTA corrida. Es el trabajo de esta llamada, no el total acumulado que tienes guardado: para saber cuánto hay, consulta. Un 0 no significa por sí solo «no hay datos»; cuando el cero tiene una explicación, viene en 'detalle'."
},
"error": {
"description": "Por qué este alcance no terminó bien. Presente solo cuando 'status' es 'failed'. Normalmente es un código del catálogo de errores; cuando el sistema externo truncó el listado es una etiqueta de resultado ('movimientos_truncated', 'cartolas_truncated') que no está en ese catálogo y que significa «se escribió lo que alcanzó a venir». Decide por el valor, nunca por el texto libre.",
"type": "string"
},
"cuentasConsultadas": {
"description": "Cuántas cuentas se alcanzaron a consultar. Un 'recordsSynced: 0' con cero cuentas no dice nada sobre el período. Con cuentas consultadas, revisa también status y cuentasSinDatosConcluyentes antes de concluir ausencia de movimientos: una respuesta web ambigua no acredita un mes sin actividad.",
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"cuentasNoConsultadas": {
"description": "Cuentas web omitidas porque el inventario de la misma sesión no acreditó su moneda. El alcance es parcial; no significa que esas cuentas carezcan de saldo o movimientos.",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"cuentasSinDatosConcluyentes": {
"description": "Cuentas web cuya respuesta vacía fue ambigua (Status 0). El alcance es parcial y no permite concluir ausencia de movimientos; no se repite el login por esa respuesta.",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"detalle": {
"description": "Explicación en lenguaje llano, presente solo cuando el resultado necesita una. Existe para que un cero se pueda transmitir tal cual en vez de concluir «no hay datos»: transmítelo a quien pregunte en lugar de resumir el número solo.",
"type": "string"
}
},
"required": [
"alcance",
"status",
"recordsSynced"
],
"additionalProperties": false
}
}
},
"required": [
"periodo",
"estado"
],
"additionalProperties": false
}Errores de esta tool
| Código | HTTP | Reintentable | Qué hacer |
|---|---|---|---|
connection_disabled | 403 | no | Reactívala en /connections o usa otra conexión del mismo sistema. |
connection_not_found | 404 | no | Usa uno de los connectionId que lista el error, o revisa la conexión en /connections. No hace falta reactivar nada. |
alcance_not_enabled | 403 | no | Habilita el alcance en /connections o quítalo del input de la sincronización. |
too_many_pending | 429 | sí | Deja terminar los trabajos en curso antes de encolar más. |
La llamada solo encola: las fallas del sistema externo (credencial, sesión, caída del portal) no llegan en esta respuesta, sino en el trabajo: en outcomes y last_error de GET /v1/syncs/{jobId}, o en los webhooks sync.succeeded (un alcance que falló junto a otros que terminaron) y sync.failed.
Toda llamada puede devolver además los códigos transversales (validation_error, unauthorized, scope_not_granted, rate_limited, entre otros): el detalle vive en el catálogo de errores.
Próximos pasos
santander_empresas.movimientos.consultar: lee el alcancemovimientosque esta sincronización escribe.santander_empresas.saldos.consultar: lee el alcancesaldosque esta sincronización escribe.