API v1.0.0 · disponible

Referencia de la API de finO$

Consulta por HTTP los datos financieros de tu workspace: transacciones extraídas de estados de cuenta, saldos por cuenta, patrimonio y resúmenes mensuales. También puedes subir PDFs para procesar.

URL base

https://api.getfinos.com

Introducción

finO$ convierte estados de cuenta bancarios en PDF en datos estructurados. El API te da acceso programático a esos datos ya procesados y normalizados: un solo formato sin importar de qué banco venga el estado de cuenta.

  • Transacciones normalizadas de cualquier banco, con especialidad en México y Latinoamérica
  • Saldos y patrimonio por cuenta, con arrastre entre periodos
  • Resumen mensual y serie histórica de ingreso, gasto y patrimonio
  • Conversión de divisas a la tasa de cada fecha
  • Subida de PDFs para procesar, de forma asíncrona
  • Conector MCP: tu agente de IA (Claude, ChatGPT) consulta estos mismos datos con tu llave
  • SDKs oficiales y webhooks de notificación Próximamente

Tu primera llamada

  1. 1 Crea una API key en la app: Configuración → API. Se muestra una sola vez, guárdala como secreto.
  2. 2 Mándala en el header Authorization de cada petición.
  3. 3 Pide el resumen del mes. Si tu workspace ya tiene estados de cuenta procesados, ahí están tus cifras.

Con la llave lista, esta es la petición más corta que devuelve algo útil: el resumen del mes en curso.

cURL
curl -H "Authorization: Bearer $FINOS_API_KEY" \
  "https://api.getfinos.com/api/v1/summary?month=2026-07"

Crear una API key en la app

Autenticación

Todas las peticiones llevan la API key en el header Authorization, con el esquema Bearer.

Authorization: Bearer fin_sk_...

La llave se crea en la app (Configuración → API) y se muestra UNA sola vez. Cada llave está atada al workspace donde se creó: no mandes ningún encabezado de workspace; no hace falta y no cambia nada.

La misma llave conecta un cliente MCP: das de alta el conector en Claude, ChatGPT o el agente que uses, y consulta estos mismos endpoints con el scope que le diste. Más sobre esto en la comparativa con ChatGPT.

Scopes

  • read Leer transacciones, cuentas, categorías, estados de cuenta, resumen y periodos.
  • statements:write Subir PDFs para procesar. Va aparte porque consume saldo del wallet.

Antes de escribir código

El signo importa

En amount, negativo es salida de dinero y positivo es entrada. No hay un campo aparte de dirección.

No todo está confirmado

Cada transacción trae status. Las validated las revisó una persona; las pending salieron de la extracción automática del PDF y nadie las ha confirmado todavía.

Por eso los números no siempre cuadran, y no es un bug

/summary y /periods cuentan SOLO transacciones validadas, mientras que /transactions devuelve validadas y pendientes. Si sumas la lista y la comparas contra el resumen, va a dar distinto. Si necesitas cifras firmes, usa el resumen o filtra la lista por status.

Las divisas se convierten a la tasa de su fecha

El parámetro display_currency controla la divisa de salida; el default es MXN.

Forma de la respuesta

Todas las respuestas comparten la misma envoltura. Las listas además traen paginación:

{
  "data": [ ... ],
  "pagination": { "limit": 50, "offset": 0, "total": 213, "has_more": true }
}

Usa has_more para saber si falta pedir más; no hace falta hacer cuentas con total y offset.

Endpoints

Ocho operaciones sobre una sola URL base. Todas las de lectura funcionan con el scope read.

Método Path Descripción
GET /api/v1/summary Resumen del mes: patrimonio, flujo y top de gasto
GET /api/v1/periods Serie mes a mes de ingreso, gasto y patrimonio
GET /api/v1/transactions Lista transacciones
GET /api/v1/accounts Lista cuentas con su saldo
GET /api/v1/categories Lista las categorías activas del workspace
GET /api/v1/statements Lista estados de cuenta y su estado de procesamiento
GET /api/v1/statements/{id} Estado de un estado de cuenta
POST /api/v1/statements Sube un PDF para procesar
GET

/api/v1/summary

Resumen del mes: patrimonio, flujo y top de gasto

La respuesta a "¿cómo voy?". Es un SNAPSHOT del mes pedido: el patrimonio es el del cierre de ese mes, no el de hoy, y coincide con el que devuelve /periods para el mismo mes. IMPORTANTE: estas cifras cuentan SOLO transacciones validadas, mientras que /transactions devuelve validadas y pendientes. Si sumas las transacciones y comparas contra este resumen, no van a coincidir, y no es un error.

Parámetros

  • month string opcional YYYY-MM. Por default, el mes en curso.
  • display_currency string opcional · default: MXN Divisa de salida. Todo se convierte a la tasa de su fecha.

Devuelve Un Summary

GET

/api/v1/periods

Serie mes a mes de ingreso, gasto y patrimonio

Una fila por mes. Como en /summary, cuenta SOLO transacciones validadas. Los saldos son de arrastre: una cuenta sin estado de cuenta ese mes conserva su último saldo conocido.

Parámetros

  • from string opcional YYYY-MM.
  • to string opcional YYYY-MM. Default: mes en curso.
  • display_currency string opcional · default: MXN

Devuelve Lista de Period

GET

/api/v1/transactions

Lista transacciones

Devuelve validadas y pendientes, de más reciente a más antigua. Filtra por fecha, banco, categoría, cuenta, tipo o texto libre.

Parámetros

  • limit integer opcional · default: 50 Máximo 200. Un valor mayor se acota en vez de fallar.
  • offset integer opcional · default: 0
  • from string<date> opcional
  • to string<date> opcional
  • bank string opcional
  • category string opcional
  • account_id string opcional
  • kind string opcional expense | income | internal_transfer | refund
  • search string opcional Busca en concepto y contraparte, sin distinguir acentos.

Devuelve Lista de Transaction · paginado

GET

/api/v1/accounts

Lista cuentas con su saldo

Devuelve Lista de Account

GET

/api/v1/categories

Lista las categorías activas del workspace

Devuelve Lista de Category

GET

/api/v1/statements

Lista estados de cuenta y su estado de procesamiento

Parámetros

  • limit integer opcional · default: 50 Máximo 200. Un valor mayor se acota en vez de fallar.
  • offset integer opcional · default: 0

Devuelve Lista de Statement · paginado

GET

/api/v1/statements/{id}

Estado de un estado de cuenta

Consúltalo después de subir, hasta que status sea completed: ahí sus transacciones ya aparecen en /transactions.

Parámetros

  • id string obligatorio

Devuelve Un Statement

Otras respuestas

  • 404 No existe, o no pertenece al workspace de tu llave.
POST

/api/v1/statements

Scope requerido: statements:write

Sube un PDF para procesar

Requiere el scope statements:write. Procesar consume saldo del wallet (se cobra por hoja), por eso el permiso es aparte del de lectura. Responde 202: el procesamiento es asíncrono: consulta GET /api/v1/statements/{id} hasta que status sea completed. Si el saldo no alcanza y ya tienes estados previos, se encola con status: pending y se procesa cuando recargues.

Cuerpo de la petición · multipart/form-data

  • file string<binary> obligatorio El PDF. Máximo 10 MB.
  • filename string opcional Opcional; por default el del archivo.

Otras respuestas

  • 202 Aceptado. status es processing o pending.
  • 400 Falta el archivo, está vacío, excede 10 MB o no es PDF.
  • 402 Saldo insuficiente. Trátalo distinto de un fallo: reintentar NO ayuda, hay que recargar. Trae required_cents y available_cents.
  • 502 El procesador de PDFs falló. Reintentar puede servir.

Recorrer todas las transacciones

JavaScript
async function allTransactions(from, to) {
  const out = [];
  let offset = 0;

  for (;;) {
    const url = new URL('https://api.getfinos.com/api/v1/transactions');
    url.search = new URLSearchParams({ from, to, limit: '200', offset: String(offset) });

    const res = await fetch(url, {
      headers: { Authorization: `Bearer ${process.env.FINOS_API_KEY}` },
    });
    const { data, pagination } = await res.json();

    out.push(...data);
    if (!pagination.has_more) return out;
    offset += pagination.limit;
  }
}

// Ojo: incluye validadas y pendientes.
const confirmed = (await allTransactions('2026-01-01', '2026-07-31'))
  .filter((tx) => tx.status === 'validated');

Subir un PDF y esperar el resultado

cURL
# 1. Subir (responde 202 con el estado de cuenta creado)
curl -X POST "https://api.getfinos.com/api/v1/statements" \
  -H "Authorization: Bearer $FINOS_API_KEY" \
  -F "file=@estado-de-cuenta.pdf"

# 2. Consultar hasta que status sea "completed"
curl -H "Authorization: Bearer $FINOS_API_KEY" \
  "https://api.getfinos.com/api/v1/statements/STATEMENT_ID"

Modelo de datos

Estos son los objetos que devuelve el API. Los campos marcados como obligatorios siempre vienen en la respuesta, aunque su valor pueda ser null.

Transaction

Campo Tipo Descripción
id string Identificador estable de la transacción.
statement_id string Estado de cuenta del que salió.
date string<date> | null Fecha del movimiento.
amount number | null Negativo = salida, positivo = entrada.
currency string | null Código ISO-4217 (MXN, USD…).
kind string expense, income, internal_transfer o refund.
status string | null validated (confirmada por el usuario), pending o dismissed.
concept string | null Descripción tal como la imprime el banco.
counterparty string | null Contraparte, cuando el banco la reporta.
merchant string | null Comercio canónico.
category string | null Clave de categoría (ver /categories).
bank string | null Banco emisor.
account_id string | null
account_type string | null debit o credit.
original_amount number | null Monto en la divisa original, si el banco la reporta distinta.
original_currency string | null
fx_rate number | null

Summary

Campo Tipo Descripción
month string Mes en formato YYYY-MM.
currency string | null Código ISO-4217 (MXN, USD…).
net_worth number Activos menos deuda AL CIERRE del mes pedido, no el de hoy. Los saldos son de arrastre: una cuenta sin estado ese mes conserva el último conocido. Un mes anterior a tu primer estado de cuenta da 0.
assets number Saldos de cuentas de débito, incluyendo holdings registrados a mano.
debt number Deuda de tarjetas, positiva cuando se debe.
net_worth_change number | null Cambio contra el mes anterior. null si no hay mes previo con qué comparar.
income number Ingreso del periodo. SOLO transacciones validadas.
expense number Gasto del periodo. SOLO transacciones validadas.
net number income - expense.
transaction_count integer Cuántas transacciones validadas entraron en estas cifras.
top_expense_categories array Las 5 categorías con más gasto del mes.
msi_committed number | null Mensualidad comprometida en compras a meses sin intereses PARA ESE MES. Es decreciente: cada plan deja de aportar cuando termina de pagarse, así que un mes lejano puede ser 0. null para un mes que ya pasó: no guardamos el estado histórico de los planes, así que cualquier cifra sería inventada.

Period

Campo Tipo Descripción
period string Mes del periodo, YYYY-MM.
income number Ingreso del periodo. SOLO transacciones validadas.
expense number Gasto del periodo. SOLO transacciones validadas.
net number income - expense.
transaction_count integer Cuántas transacciones validadas entraron en las cifras de este mes.
assets number Saldos de débito al cierre, con arrastre si no hubo estado de cuenta ese mes.
debt number Deuda de tarjetas al cierre del mes.
net_worth number Activos menos deuda al cierre del mes.
msi_committed number | null Compromiso de meses sin intereses de ESE mes. Se reporta cuando ningún estado de cuenta cubre el mes todavía, incluso si el mes ya pasó, porque el compromiso es real aunque no esté extraído. null cuando el mes ya está cubierto: ahí el cargo real ya viene en expense y reportarlo aparte sería contarlo dos veces.

Account

Campo Tipo Descripción
id string Identificador de la cuenta.
bank string | null Banco emisor.
account_number string | null Enmascarado por el banco.
account_type string | null debit o credit.
currency string | null Código ISO-4217 (MXN, USD…).
balance number | null Saldo al último corte, incluyendo holdings registrados a mano.
first_period_start string<date> | null
last_period_end string<date> | null
statement_count integer
transaction_count integer Cuántas transacciones se han extraído de esta cuenta en total.

Category

Campo Tipo Descripción
key string Clave estable; es lo que trae category.
label string Nombre legible.
kind string expense, income, internal_transfer o refund.
archived boolean

Statement

Campo Tipo Descripción
id string Identificador del estado de cuenta.
filename string
bank string | null Banco emisor.
period_start string<date> | null
period_end string<date> | null
status string | null pending (subido, aún sin procesar), processing, completed o error. Es como sabes si ya puedes leer sus transacciones.
page_count integer | null
uploaded_at string<date-time>

El formato es idéntico para todos los bancos soportados: la normalización pasa antes, al procesar el PDF. Detalle por banco en las páginas de banco .

Errores

Los errores devuelven { "error": "...", "code": "..." } con el status HTTP correspondiente. Estos aplican a cualquier endpoint:

HTTP Descripción
401 Llave inválida o revocada.
403 A la llave le falta el permiso (scope) necesario.
404 El recurso no existe, o el workspace ya no está a tu alcance.
429 Demasiadas peticiones. Respeta el header Retry-After antes de reintentar.
{
  "error": "Invalid API key",
  "code": "unauthorized"
}

Límites y comportamiento

Comportamiento que conviene tener presente al construir contra el API:

  • limit tiene un máximo de 200. Un valor mayor se acota en vez de fallar.
  • Los PDFs pesan máximo 10 MB por archivo.
  • El procesamiento de un PDF es asíncrono: la subida responde 202 y hay que consultar el estado hasta que sea completed.
  • Un 402 al subir significa saldo insuficiente. Reintentar NO ayuda: hay que recargar. La respuesta trae required_cents y available_cents.
  • Ante un 429, respeta el header Retry-After antes de reintentar.

Precio

Gratis cada mes

30 hojas

Por workspace, en el plan Gratis · no se acumulan

Después, prepago

$5 MXN / hoja

Cargas saldo y se descuenta por uso

El API no tiene costo propio ni suscripción: se cobra lo mismo que en el dashboard, por hoja de PDF procesada. Consultar los datos ya procesados no cuesta.

¿Equipo con muchos clientes? El plan Pro trae más hojas incluidas y un precio por hoja más bajo. Ver precios · Calculadora de costos

Preguntas frecuentes sobre el API

¿Cómo obtengo una API key de finO$?

Se crea desde la app, en Configuración → API, con tu cuenta ya abierta. La llave se muestra una sola vez y empieza con fin_sk_; guárdala como secreto porque no se puede volver a ver. Cada llave queda atada al workspace donde se creó.

¿Cuánto cuesta usar el API?

El API no tiene costo propio ni suscripción. Se cobra lo mismo que en el dashboard: $5 MXN por hoja de PDF procesada, con 30 hojas gratis cada mes en el plan Gratis. Leer datos ya procesados (transacciones, saldos, resúmenes) no consume saldo.

¿Por qué el total de /transactions no coincide con /summary?

Porque no cuentan lo mismo, y es intencional. /summary y /periods usan solo transacciones validadas (revisadas por una persona), mientras que /transactions devuelve validadas y pendientes. Si necesitas que cuadren, filtra la lista por status=validated o usa directamente el resumen.

¿El API procesa PDFs o solo lee datos ya extraídos?

Ambas cosas. POST /api/v1/statements sube un PDF de hasta 10 MB para procesar y requiere el scope statements:write. El procesamiento es asíncrono: responde 202 y consultas GET /api/v1/statements/{id} hasta que status sea completed; ahí sus transacciones ya aparecen en /transactions.

¿Hay SDKs oficiales o webhooks?

Todavía no. Hoy el API es REST sobre HTTP con autenticación Bearer, así que funciona con cualquier cliente HTTP. Los SDKs oficiales y los webhooks de notificación están en el roadmap; mientras tanto, para saber si un PDF terminó de procesarse se consulta el estado del estado de cuenta.

¿Qué significa un error 402 al subir un estado de cuenta?

Saldo insuficiente en el wallet. Es distinto de un fallo: reintentar no ayuda, hay que recargar. La respuesta trae required_cents y available_cents para que sepas cuánto falta. Si ya tienes estados de cuenta previos, el archivo se encola con status pending y se procesa solo cuando recargas.

¿En qué divisa vienen los montos?

Por default en MXN. El parámetro display_currency cambia la divisa de salida en /summary y /periods, y la conversión se hace a la tasa de la fecha de cada movimiento, no a la tasa de hoy. Cada transacción conserva además su monto y divisa originales en original_amount y original_currency.

Crea tu API key

Abre una cuenta, procesa tu primer estado de cuenta y genera la llave desde Configuración → API. Cada mes, las primeras 30 hojas van por nuestra cuenta.

Empezar gratis

Seguir leyendo: Referencia interactiva · finO$ para desarrolladores · Integraciones · ¿Por qué no subirlo a ChatGPT?