Saltar al contenido principal
Página sin clasificar
Esta página está sin clasificar. Los motores de búsqueda no la indexaran, y solo los usuarios con el enlace directo podrán acceder a esta.

Boufin API v2

Referencia de la API v2 de Boufin: autenticación, inicio de tareas con composición de acciones y notificación vía webhook. Para detalles operativos (límites, catálogo de entidades, schemas completos), consulta la referencia OpenAPI.

Autenticación

El endpoint de autenticación se mantiene en /api/v1/auth/login y es el único endpoint de auth oficial, compatible tanto con clientes v1 como con clientes v2. Con tu API Key obtienes un token de sesión:

curl -X POST "https://${URL}/api/v1/auth/login" \
-H "X-API-Key: ${API_KEY}" \
-H "Content-Type: application/json" \
--data '{"expire": 60}'
CampoDescripción
X-API-KeyTu API Key entregada por Boufin
expire(Opcional) Minutos de validez del token. Por defecto 60. Ver límites y validaciones en la referencia de la API

Response:

{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Usa el token en el header Authorization: Bearer ${TOKEN} para todas las siguientes peticiones.


Iniciar proceso de extracción

Endpoint: POST /api/v2/tasks

La v2 mantiene el mismo concepto de tarea e incorpora cuatro mejoras principales respecto a v1:

  • Entidad como campo independiente: en v1, entidad y acción iban combinadas en un único string (banco-xx:movement). En v2 la entidad se especifica en el campo top-level entity y las acciones quedan limpias ({ "id": "movement" }).
  • Nuevo formato de credenciales: se pasan como objeto con modo encrypted, persisted o raw, en lugar de campos sueltos.
  • Composición de acciones: una sola tarea puede ejecutar múltiples acciones (movement, product-balance, tef) sobre la misma entidad.
  • Webhook configurable: en lugar de un booleano, el webhook es un objeto que permite habilitarlo y ajustar el número de reintentos.
curl --request POST \
'https://${URL}/api/v2/tasks' \
-H 'Authorization: Bearer ${TOKEN}' \
-H 'Content-Type: application/json' \
-d '{
"entity": "banco-chile",
"credentials": {
"mode": "encrypted",
"value": "czuqliRO1DKMj4bbPIzMEIYyj4+GqFLBXXc/TM7d3x0==-Qlih4F8+I6kZv8xCuSAc2A=="
},
"actions": [
{ "id": "movement" }
]
}'

Response:

{ "taskId": "5cbae0b5e1b5d035d99469f42c653ff4bb8aecdf9dbdb8e10f45a31677683369" }

Referencia de campos

Request

CampoTipoRequeridoDescripción
entitystringSlug de la entidad bancaria (ej. banco-chile). Ver listado en la referencia OpenAPI
credentialsobjectCredenciales del usuario. Ver tabla de modos
actionsarrayLista de acciones a ejecutar. Mínimo una
webhookobjectNoNotificación al finalizar

Modos de credentials

modeCamposDescripción
encryptedvalue: string — formato ${CIPHER_TEXT}-${IV}Cifrado temporal con el token de sesión como llave (máx. 60 min)
persistedvalue: string — ciphertext obtenido del servicio de cifrado persistenteCifrado persistente, reutilizable entre requests
rawusername: string, password: stringTexto plano, protegido por TLS

Campos de actions[]

CampoTipoRequeridoDescripción
idstringAcción a ejecutar: movement, product-balance, tef
paramsobjectNoParámetros opcionales según la acción

Campos de webhook

CampoTipoRequeridoDescripción
enablebooleanActiva la notificación al finalizar el proceso. Si es false, no se envía aunque el objeto webhook esté presente
retriesintegerNoCantidad total de intentos de entrega (incluye el intento inicial). Rango 15. Default 3

Credenciales

El campo credentials define cómo se envían las credenciales del usuario. Soporta tres modos:

  • Opción 1 — Cifrado temporal (encrypted): Las credenciales se cifran en cada request usando tu token de sesión como llave (AES-256-CBC; la llave se deriva aplicando SHA-256 sobre el token antes de usarla). El cifrado tiene una duración máxima de 60 minutos, por lo que es ideal para integraciones en tiempo real. Consulta la guía de cifrado temporal.
  • Opción 2 — Cifrado persistente (persisted): Las credenciales se cifran una sola vez a través del servicio de cifrado de Boufin y el resultado se reutiliza en múltiples requests. Ideal para extracciones periódicas sin requerir la interacción del usuario. Consulta la guía de cifrado persistente.
  • Opción 3 — Texto plano (raw): Las credenciales se envían en "texto plano", protegidas en todo momento por TLS, tanto en la conexión externa como en la comunicación interna.

Opción 1 — Cifrado temporal

{
"entity": "banco-chile",
"credentials": {
"mode": "encrypted",
"value": "czuqliRO1DKMj4bbPIzMEIYyj4+GqFLBXXc/TM7d3x0==-Qlih4F8+I6kZv8xCuSAc2A=="
},
"actions": [{ "id": "movement" }]
}

Opción 2 — Cifrado persistente

{
"entity": "banco-chile",
"credentials": {
"mode": "persisted",
"value": "sdfAgNUFdLoF7eDGAcB3BB17gEhWG+3Q6Q5Z6Q=="
},
"actions": [{ "id": "movement" }]
}

Opción 3 — Texto plano

{
"entity": "banco-chile",
"credentials": {
"mode": "raw",
"username": "11.111.111-1",
"password": "123456789"
},
"actions": [{ "id": "movement" }]
}

Acciones

Una tarea puede ejecutar múltiples acciones en secuencia sobre la misma entidad. Cada acción puede incluir parámetros opcionales para filtrar la extracción.

Acción simple

{
"entity": "banco-chile",
"credentials": {
"mode": "persisted",
"value": "sdfAgNUFdLoF7eDGAcB3BB17gEhWG+3Q6Q5Z6Q=="
},
"actions": [{ "id": "movement" }]
}

Con filtros

La acción movement acepta parámetros opcionales para acotar la extracción:

{
"entity": "banco-chile",
"credentials": {
"mode": "persisted",
"value": "sdfAgNUFdLoF7eDGAcB3BB17gEhWG+3Q6Q5Z6Q=="
},
"actions": [
{
"id": "movement",
"params": { "date_range": { "from": "2025-01-01", "to": "2025-01-31" } }
}
]
}
info

El historial disponible varía según la entidad. Si from es anterior al registro más antiguo disponible o to es posterior a la fecha más reciente, la fecha fuera de rango se ajusta internamente al límite disponible — la solicitud no falla por estar fuera de rango. El formato YYYY-MM-DD sí es obligatorio.

Composición

Se pueden combinar múltiples acciones. Se ejecutan en orden sobre la misma sesión bancaria:

{
"entity": "banco-chile",
"credentials": {
"mode": "persisted",
"value": "sdfAgNUFdLoF7eDGAcB3BB17gEhWG+3Q6Q5Z6Q=="
},
"actions": [
{ "id": "product-balance" },
{
"id": "movement",
"params": { "date_range": { "from": "2025-01-01", "to": "2025-01-31" } }
}
]
}
AcciónDescripciónParámetros opcionales
movementMovimientos de cuentadate_range
product-balanceSaldo de productos
tefDestinatarios TEF (Transferencia Electrónica de Fondos)

Configuración del webhook

precaución

Para utilizar el webhook debes solicitar la activación con el equipo de soporte. La URL de destino y la llave compartida para descifrar el payload se configuran en esa misma instancia.

Si se omite el objeto webhook, la API no enviará notificaciones — el cliente debe consultar el estado vía GET /api/v2/tasks/{taskId}.

Habilitado

{
"entity": "banco-chile",
"credentials": {
"mode": "persisted",
"value": "sdfAgNUFdLoF7eDGAcB3BB17gEhWG+3Q6Q5Z6Q=="
},
"actions": [{ "id": "movement" }],
"webhook": { "enable": true }
}

Con reintentos configurados

{
"entity": "banco-chile",
"credentials": {
"mode": "persisted",
"value": "sdfAgNUFdLoF7eDGAcB3BB17gEhWG+3Q6Q5Z6Q=="
},
"actions": [{ "id": "product-balance" }, { "id": "movement" }],
"webhook": { "enable": true, "retries": 3 }
}

Recepción de la notificación

Cuando el proceso finaliza, Boufin enviará una notificación HTTP POST a la URL configurada con el equipo de soporte.

Payload

El cuerpo de la notificación es un JSON con un único campo data que contiene el payload completamente cifrado como string:

{
"data": "<cifrado>"
}

Al descifrar data obtienes un JSON con los campos del resultado:

{
"taskId": "5cbae0b5e1b5d035d99469f42c653ff4bb8aecdf9dbdb8e10f45a31677683369",
"taskStatus": "success",
"taskStatusCode": 200
}
CampoDescripción
taskIdID de la tarea que finalizó
taskStatusEstado final del proceso (ver tabla de estados)
taskStatusCodeCódigo numérico del estado

El webhook solo se dispara cuando el proceso termina definitivamente. Los posibles valores son:

taskStatusCodetaskStatusDescripción
200successTodas las acciones completadas exitosamente
206partialAl menos una acción completó, otra(s) fallaron
401wrong_loginCredenciales incorrectas
401lockedLa cuenta del usuario está bloqueada en la entidad
500errorError general — ninguna acción pudo ejecutarse
nota

taskStatusCode: 401 aplica a las credenciales de la entidad bancaria (sea wrong_login o locked), no al Bearer token. Una falla del Bearer se devuelve como HTTP 401 en la respuesta de la propia llamada, sin envolver en taskStatus.

info

Por el momento los estados se mantienen igual que en la v1. Puedes ver la referencia completa en la documentación del endpoint de estado de tarea.

Cifrado del payload

El campo data está cifrado con el mismo algoritmo descrito en Credenciales (AES-256-CBC). La llave compartida es acordada previamente con el equipo de soporte.

El formato del string cifrado es el mismo que en el cifrado temporal:

${CIPHER_TEXT}-${IV}

La llave se deriva aplicando SHA-256 sobre la llave compartida antes de usarla para descifrar.

Autenticidad

Poder descifrar el campo data con tu llave compartida es prueba de origen: una petición que no provenga de Boufin no podrá producir un ciphertext válido bajo esa llave.

Ejemplo de request entrante

Así se verá la solicitud POST que llegará a tu servidor:

POST /tu-endpoint HTTP/1.1
Content-Type: application/json

{
"data": "2iHTdihWU9zAcb+ixoavm6xcmk3xq8+3NMIBd5gpleTHnWT41EoPltpcllnRdiJb7V6EK/2mz3ccxozaZ79Wcw==-0s8j3MAEU7bBEYHjVIK6aQ=="
}

Al descifrar el campo data con la llave compartida obtienes:

{
"taskId": "5cbae0b5e1b5d035d99469f42c653ff4bb8aecdf9dbdb8e10f45a31677683369",
"taskStatus": "success",
"taskStatusCode": 200
}
Recomendación

Cifrar el body completo como un único bloque es más seguro y simple que cifrar campo por campo: no expone la estructura del mensaje y se descifra en un solo paso.

Reintentos

Si tu servidor no responde con 200 o 204, Boufin reintentará la entrega. La cantidad total de intentos se controla con webhook.retries (default 3, rango 15). Intervalo de 30 segundos entre intentos. Cada intento espera un máximo de 5 segundos antes de marcarlo como fallido.

IntentoMomento
Al finalizar el proceso
+30 segundos
+60 segundos
(continúa hasta retries)

Si todos los intentos fallan, el evento queda registrado internamente. Puedes consultar el estado final de la tarea directamente usando GET /api/v2/tasks/{taskId}.

Para ejemplos de implementación del descifrado puedes referirte a la guía de cifrado temporal, ya que usa el mismo algoritmo.


Respuestas

info

Esta es la estructura base de la API v2 y todavía está en proceso de trabajo. Puede evolucionar — especialmente por la variabilidad en las respuestas de las entidades financieras durante extracciones compuestas.

Una vez finalizado el proceso, consulta los datos extraídos usando el taskId obtenido al crear la tarea:

curl "https://${URL}/api/v2/tasks/${TASK_ID}" \
-H "Authorization: Bearer ${TOKEN}"
tip

No basta con tener un token válido — debe ser el mismo cliente que inició el proceso de extracción, como indica la documentación oficial. Esto aplica tanto al polling como a la consulta del resultado final.

Estados de la tarea

El taskStatus y taskStatusCode reflejan el resultado consolidado de todas las acciones ejecutadas:

taskStatusCodetaskStatusDescripción
202pendingExtracción encolada, aún no comenzó
202runningExtracción en ejecución
200successTodas las acciones completadas exitosamente
206partialAl menos una acción completó, otra(s) fallaron
401wrong_loginCredenciales incorrectas
401lockedLa cuenta del usuario está bloqueada en la entidad
500errorError general — ninguna acción pudo ejecutarse
nota

taskStatusCode: 401 aplica a las credenciales de la entidad bancaria (sea wrong_login o locked), no al Bearer token. Una falla del Bearer se devuelve como HTTP 401 en la respuesta de la propia llamada, sin envolver en taskStatus.

La tabla del webhook (Recepción de la notificación) es un subconjunto: solo lista los estados terminales.

Escenarios de respuesta

Cada acción retorna su propia respuesta dentro de results.actions, con su propio status, data y, en caso de fallo, reason y errorCode.

Éxito completo

Todas las acciones completaron sin problemas:

{
"taskStatus": "success",
"taskStatusCode": 200,
"results": {
"username": "11111111-1",
"entityId": "banco-estado",
"actions": [
{
"id": "product-balance",
"status": "success",
"data": [
/* productos */
]
},
{
"id": "movement",
"status": "success",
"data": [
/* movimientos */
]
}
]
}
}

Resultado parcial

Al menos una acción completó y otra falló. Cada acción indica su propio estado:

{
"taskStatus": "partial",
"taskStatusCode": 206,
"results": {
"username": "11111111-1",
"entityId": "banco-estado",
"actions": [
{
"id": "product-balance",
"status": "success",
"data": [
/* productos */
]
},
{
"id": "movement",
"status": "error",
"data": null,
"reason": "Entity did not respond during extraction",
"errorCode": "ENTITY_UNAVAILABLE"
}
]
}
}

Credenciales incorrectas

{
"taskStatus": "wrong_login",
"taskStatusCode": 401,
"results": null
}

Credenciales bloqueadas

La cuenta del usuario está bloqueada en la entidad bancaria (típicamente tras múltiples intentos fallidos). Las credenciales podrían ser correctas, pero la entidad rechaza el acceso:

{
"taskStatus": "locked",
"taskStatusCode": 401,
"results": null
}

Error general

La entidad no estuvo disponible y ninguna acción pudo ejecutarse:

{
"taskStatus": "error",
"taskStatusCode": 500,
"results": null
}

Referencia de campos

Campos de results

CampoTipoDescripción
usernamestringIdentificador del usuario consultado (formato según la entidad)
entityIdstringSlug de la entidad bancaria. Ver listado en la referencia de la API
actionsarrayResultados por acción. Ver tabla siguiente

Campos de results.actions[]

CampoTipoDescripción
idstringIdentificador de la acción ejecutada
status"success" | "error"Estado de esta acción en particular
dataarray | nullDatos extraídos. null si status = error
reasonstringDescripción del problema en inglés, pensada para uso interno/debugging. Presente si status = error
errorCodestringCódigo de error en UPPER_SNAKE_CASE. Es el identificador estándar para manejo programático. Presente si status = error

Códigos de error

errorCodeDescripción
WRONG_LOGINCredenciales de la entidad bancaria incorrectas
LOCKED_CREDENTIALSCredenciales válidas pero la cuenta está bloqueada en la entidad bancaria
ENTITY_UNAVAILABLELa entidad no respondió durante la extracción
EXTRACTION_TIMEOUTLa extracción excedió el tiempo máximo permitido
INVALID_PARAMSParámetros del request inválidos para la acción solicitada
nota

Estamos consolidando la lista completa de códigos. Esta tabla cubre los casos más frecuentes hoy.