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", "params": { "dateRange": { "startDate": "2025-01-01", "endDate": "2025-01-31" } } }
]
}'

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
rawvalue: object — credenciales según la entidad (ej. username, password)Texto plano, protegido por TLS

Campos de actions[]

CampoTipoRequeridoDescripción
idstringAcción a ejecutar: movement, product-balance, tef
paramsobjectCondicionalObligatorio para movement y debe incluir dateRange; tef y product-balance no lo aceptan

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",
"params": {
"dateRange": { "startDate": "2025-01-01", "endDate": "2025-01-31" }
}
}
]
}

Opción 2 — Cifrado persistente

{
"entity": "banco-chile",
"credentials": {
"mode": "persisted",
"value": "sdfAgNUFdLoF7eDGAcB3BB17gEhWG+3Q6Q5Z6Q=="
},
"actions": [
{
"id": "movement",
"params": {
"dateRange": { "startDate": "2025-01-01", "endDate": "2025-01-31" }
}
}
]
}

Opción 3 — Texto plano

{
"entity": "banco-chile",
"credentials": {
"mode": "raw",
"value": {
"username": "11.111.111-1",
"password": "123456789"
}
},
"actions": [
{
"id": "movement",
"params": {
"dateRange": { "startDate": "2025-01-01", "endDate": "2025-01-31" }
}
}
]
}

Acciones

Una tarea puede ejecutar múltiples acciones en secuencia sobre la misma entidad. Algunas acciones requieren parámetros (movement requiere dateRange) y otras no aceptan ninguno (tef, product-balance).

Acción simple

Las acciones tef y product-balance no llevan params:

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

Con filtros

La acción movement requiere params con un dateRange que acota la extracción:

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

El historial disponible varía según la entidad. Si startDate es anterior al registro más antiguo disponible o endDate 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": {
"dateRange": { "startDate": "2025-01-01", "endDate": "2025-01-31" }
}
}
]
}
AcciónDescripciónParámetros
movementMovimientos de cuentadateRange (obligatorio)
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 verificar la firma del 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",
"params": {
"dateRange": { "startDate": "2025-01-01", "endDate": "2025-01-31" }
}
}
],
"webhook": { "enable": true }
}

Con reintentos configurados

{
"entity": "banco-chile",
"credentials": {
"mode": "persisted",
"value": "sdfAgNUFdLoF7eDGAcB3BB17gEhWG+3Q6Q5Z6Q=="
},
"actions": [
{ "id": "product-balance" },
{
"id": "movement",
"params": {
"dateRange": { "startDate": "2025-01-01", "endDate": "2025-01-31" }
}
}
],
"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 los campos del resultado:

{
"taskId": "5cbae0b5e1b5d035d99469f42c653ff4bb8aecdf9dbdb8e10f45a31677683369",
"taskStatus": "COMPLETED"
}
CampoDescripción
taskIdID de la tarea que finalizó
taskStatusEstado final del proceso (ver tabla de estados)

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

taskStatusDescripción
COMPLETEDTodas las acciones completadas exitosamente
PARTIALAl menos una acción completó, otra(s) fallaron
CREDENTIALS_WRONGCredenciales incorrectas
CREDENTIALS_LOCKEDLa cuenta del usuario está bloqueada en la entidad
FAILEDError general — ninguna acción pudo ejecutarse
nota

CREDENTIALS_WRONG y CREDENTIALS_LOCKED aplican a las credenciales de la entidad bancaria, 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

La v2 define su propio conjunto público de estados (taskStatus). Puedes ver la referencia completa en la documentación del endpoint de estado de tarea.

Verificación de la firma

Cada notificación incluye el header X-Boufin-Signature con una firma HMAC-SHA256 calculada sobre el body crudo de la request:

X-Boufin-Signature: sha256=<hmac-hex>

La firma se calcula como HMAC-SHA256(rawBody, sharedKey), donde sharedKey es la llave compartida acordada con el equipo de soporte.

Para verificar el origen:

  1. Leer el body crudo (antes de parsearlo como JSON).
  2. Calcular HMAC-SHA256(rawBody, sharedKey).
  3. Comparar el resultado con el valor del header usando una comparación en tiempo constante para evitar timing attacks.
precaución

Siempre usar el body crudo para calcular el HMAC. Si se parsea y re-serializa el JSON primero, el resultado puede diferir y la verificación fallará.

Autenticidad

Una firma válida bajo tu llave compartida es prueba de origen: una petición que no provenga de Boufin no podrá producir una firma correcta 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
X-Boufin-Signature: sha256=b94d27b9934d3e08a52e52d7da7dabfac484efe04b6f9d0a08805f2cde4b2218

{
"taskId": "5cbae0b5e1b5d035d99469f42c653ff4bb8aecdf9dbdb8e10f45a31677683369",
"taskStatus": "COMPLETED"
}

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


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.

¿Quieres probar?

Revisa los casos de prueba en sandbox: requests listos para copiar/pegar con resultados deterministas por cada escenario (COMPLETED, PARTIAL, CREDENTIALS_WRONG, FAILED).

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 refleja el resultado consolidado de todas las acciones ejecutadas:

taskStatusDescripción
PENDINGExtracción encolada, aún no comenzó
RUNNINGExtracción en ejecución
COMPLETEDTodas las acciones completadas exitosamente
PARTIALAl menos una acción completó, otra(s) fallaron
FAILEDError general — ninguna acción pudo ejecutarse
CREDENTIALS_WRONGCredenciales incorrectas
CREDENTIALS_LOCKEDLa cuenta del usuario está bloqueada en la entidad
nota

CREDENTIALS_WRONG y CREDENTIALS_LOCKED aplican a las credenciales de la entidad bancaria, 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, output y, en caso de fallo, un objeto error.

Éxito completo

Todas las acciones completaron sin problemas:

{
"taskStatus": "COMPLETED",
"results": {
"username": "11111111-1",
"businessId": "76111111-6",
"entityId": "banco-estado",
"actions": [
{
"id": "product-balance",
"status": "COMPLETED",
"output": {
/* productos */
}
},
{
"id": "movement",
"status": "COMPLETED",
"output": [
/* movimientos */
]
}
]
}
}

Resultado parcial

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

{
"taskStatus": "PARTIAL",
"results": {
"username": "11111111-1",
"businessId": "76111111-6",
"entityId": "banco-estado",
"actions": [
{
"id": "product-balance",
"status": "COMPLETED",
"output": {
/* productos */
}
},
{
"id": "movement",
"status": "FAILED",
"output": null,
"error": {
"code": "TIMEOUT_ERROR",
"message": "Entity did not respond during extraction"
}
}
]
}
}

Credenciales incorrectas

{
"taskStatus": "CREDENTIALS_WRONG",
"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": "CREDENTIALS_LOCKED",
"results": null
}

Error general

Ninguna acción se completó. A diferencia de las fallas de credenciales, results se incluye con la misma estructura que en COMPLETED/PARTIAL: cada acción reporta su propio status y un objeto error, de modo que el cliente puede ver qué se intentó y por qué falló:

{
"taskStatus": "FAILED",
"results": {
"username": "11111111-1",
"businessId": "76111111-6",
"entityId": "banco-estado",
"actions": [
{
"id": "product-balance",
"status": "FAILED",
"output": null,
"error": {
"code": "ACTION_ERROR",
"message": "The service is currently unavailable"
}
},
{
"id": "movement",
"status": "FAILED",
"output": null,
"error": {
"code": "ENTITY_API_ERROR",
"message": "user has no permission for transfers"
}
}
]
}
}

Referencia de campos

Campos de results

CampoTipoDescripción
usernamestringIdentificador del usuario consultado (formato según la entidad)
businessIdstringIdentificador de la empresa. Se devuelve solo si las credenciales del request lo incluían (banca empresa)
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
statusstringEstado de esta acción en particular. Ver tabla de estados de acción
outputobject | array | nullDatos extraídos; su forma depende de la acción (objeto para product-balance, arreglo para movement). null cuando la acción no entregó datos (p. ej. FAILED)
errorobjectDetalle del fallo. Presente si status = FAILED
error.codestringCódigo del catálogo en UPPER_SNAKE_CASE. Es el identificador estándar para manejo programático. Ver tabla de códigos
error.messagestringDescripción legible del problema en inglés. Es texto variable y puede cambiar; no lo uses para lógica programática

Estados de results.actions[].status

statusDescripción
COMPLETEDLa acción se completó exitosamente y retornó datos
FAILEDLa acción falló durante la ejecución (ver objeto error)
CREDENTIALS_WRONGCredenciales incorrectas para la entidad
CREDENTIALS_LOCKEDLa cuenta del usuario está bloqueada en la entidad

Códigos de error (error.code)

El error.code detalla qué pasó en la acción. Es un catálogo independiente del status (aunque algunos nombres puedan coincidir). Códigos públicos disponibles hoy:

error.codeDescripción
UNKNOWN_ERRORError no clasificado o inesperado
ACTION_ERRORLa acción no pudo completarse durante su ejecución
REQUEST_BLOCK_ERRORLa solicitud fue bloqueada (p. ej. por la entidad)
TIMEOUT_ERRORSe excedió el tiempo máximo de la operación
ENTITY_API_ERRORError reportado por la API / entidad bancaria
nota

El catálogo de códigos se irá ampliando con el tiempo. El error.message que acompaña a cada código es un texto descriptivo variable (puede cambiar entre versiones o casos); para manejo programático usa siempre error.code, no el message.