API Documentation · v1

REST API de finO$

Convierte estados de cuenta PDF a JSON estructurado vía REST API. $5 MXN por hoja procesada, sin suscripción mínima.

Versión

v1.2.0

Protocolo

HTTPS / REST

Rate limit

100 req/min

Introducción

El API de finO$ recibe PDFs de estados de cuenta bancarios y devuelve JSON estructurado con transacciones, balances, conceptos y categorías. Soporta 58+ bancos LATAM (MX, CO, AR, CL, PE).

Base URL

https://api.getfinos.com/v1

Capacidades

  • Sube PDFs (nativos o escaneados, hasta 50 MB)
  • Extracción automática con IA — 99%+ precisión en formatos soportados
  • Detección de tipo de PDF (nativo vs escaneado) y OCR automático
  • Categorización SAT/DIAN/AFIP/SII/SUNAT alineada
  • Webhooks asíncronos firmados con HMAC-SHA256
  • Export CSV / Excel / formato Contpaqi / Aspel

Autenticación

Cada petición requiere tu API key vía header HTTP. Las keys se obtienen al solicitar acceso (24-48 horas).

Authorization: Bearer YOUR_API_KEY

Sandbox vs producción

Al solicitar acceso recibes dos keys: sk_sandbox_* para testing (sin cargo, procesa documentos de muestra) y sk_live_* para producción (cobra $5 MXN por hoja procesada).

Endpoints

Método Path Descripción
POST /v1/upload Sube un PDF y crea un job de extracción.
GET /v1/jobs/{job_id} Consulta el estado de un job.
GET /v1/extractions/{extraction_id} Obtiene el JSON resultante.
GET /v1/accounts Lista cuentas asociadas a tu API key.
GET /v1/transactions Query de transacciones a través de extracciones procesadas.
POST /v1/webhooks Configura webhooks para notificación asíncrona.
GET /v1/extractions/{id}/export Genera export CSV / Excel / formato contpaqi / aspel.

POST /v1/upload

Sube un PDF de estado de cuenta y crea un job de extracción.

cURL
curl -X POST https://api.getfinos.com/v1/upload \
  -H "Authorization: Bearer $FINOS_API_KEY" \
  -F "file=@statement.pdf" \
  -F "bank_hint=bbva_mx"

Response (202 Accepted)

{
  "job_id": "job_abc123",
  "status": "processing",
  "estimated_seconds": 15
}

Estructura del resultado

Cada extracción exitosa devuelve un JSON con metadata de la cuenta, periodo, balances y array de transacciones.

{
  "bank_name": "BBVA Bancomer S.A.",
  "bank_canonical_name": "BBVA",
  "account_number": "012180001234567890",
  "account_type": "debit",

  "opening_balance":   { "amount": 18450.32, "currency": "MXN" },
  "closing_balance":   { "amount": 22107.18, "currency": "MXN" },
  "average_balance":   { "amount": 20278.75, "currency": "MXN" },

  "total_commissions": { "amount": 152.00, "currency": "MXN" },
  "statement_period_start": "2026-04-01",
  "statement_period_end":   "2026-04-30",

  "account_holder_name":    "JUAN PEREZ LOPEZ",
  "account_holder_rfc":     "PELJ810707H94",
  "account_holder_address": "AV. INSURGENTES 100, CDMX",

  "transactions": [
    {
      "day": 3, "month": 4,
      "description": "TRANSFERENCIA SPEI CLIENTE ACME SA",
      "transaction_concept": "Cobro de cliente",
      "counterparty_name": "ACME SA DE CV",
      "counterparty_rfc": "ACM800101AB1",
      "merchant_canonical_name": null,
      "amount": 15000.00,
      "currency": "MXN",
      "transaction_type": "DEBIT",
      "direction": "inflow",
      "channel": "SPEI",
      "category": "income",
      "kind_hint": "income",
      "is_recurring_likely": false
    }
  ],

  "zero_interest_installments": [
    {
      "description": "AMAZON A MESES",
      "purchase_date": "2026-02-15",
      "original_amount":    { "amount": 12000.00, "currency": "MXN" },
      "current_payment_number": 2,
      "total_payments_number": 12,
      "monthly_installment": { "amount": 1000.00, "currency": "MXN" },
      "interest_rate": 0,
      "pending_amount":      { "amount": 10000.00, "currency": "MXN" }
    }
  ]
}

Detalle de cada campo en cualquier página de banco. El JSON es idéntico para todos los bancos soportados — el mismo schema v5 aplica para BBVA, Nu, Mercado Pago, etc.

Regla clave: las líneas tipo "AMAZON A MESES 2/12" que aparecen en estados de tarjeta de crédito NO van a transactions[] — solo la compra original aparece como transaction; el plan se rastrea en zero_interest_installments[].

Códigos de error

Los errores siguen una shape consistente: HTTP status + JSON con error.code, error.message y error.request_id.

HTTP Code Descripción
401 unauthorized API key faltante o inválida.
403 forbidden API key válida pero sin permiso para este recurso.
404 not_found Recurso (job o extraction) no existe.
413 payload_too_large PDF excede el límite de 50 MB.
422 unprocessable_entity PDF recibido pero el parsing falló (¿corrupto, protegido sin password?).
429 too_many_requests Rate limit excedido. Implementa backoff exponencial.
500 internal_error Error del servidor. Reintenta con backoff.

Ejemplo de error

{
  "error": {
    "code": "invalid_pdf",
    "message": "The uploaded file could not be parsed as a PDF.",
    "request_id": "req_xyz789"
  }
}

Ejemplo end-to-end

Flujo completo: subir PDF, esperar procesamiento, obtener transacciones. En producción usa webhooks en vez de polling.

JavaScript
async function processStatement(pdfPath) {
  // 1. Upload
  const formData = new FormData();
  formData.append('file', await fs.openAsBlob(pdfPath));
  formData.append('bank_hint', 'bbva_mx');

  const upload = await fetch('https://api.getfinos.com/v1/upload', {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${process.env.FINOS_API_KEY}` },
    body: formData,
  }).then(r => r.json());

  // 2. Poll until completed (or use webhook in production)
  let job;
  do {
    await new Promise(r => setTimeout(r, 2000));
    job = await fetch(`https://api.getfinos.com/v1/jobs/${upload.job_id}`, {
      headers: { 'Authorization': `Bearer ${process.env.FINOS_API_KEY}` },
    }).then(r => r.json());
  } while (job.status === 'processing');

  if (job.status === 'failed') throw new Error(job.error.message);

  // 3. Fetch result
  const result = await fetch(`https://api.getfinos.com/v1/extractions/${job.extraction_id}`, {
    headers: { 'Authorization': `Bearer ${process.env.FINOS_API_KEY}` },
  }).then(r => r.json());

  return result.transactions;
}

Pricing

Cuenta gratis inicial

100 hojas

Al crear tu cuenta · One-time

Después, prepago

$5 MXN / hoja

Cargas saldo, se descuenta por uso

Mismo precio para personas, negocios y API — no hay tiers. Sin suscripción mensual, sin setup fee, sin compromiso. Pagas solo por hojas procesadas exitosamente (errores HTTP 4xx/5xx no se cobran). Tu saldo nunca caduca.

Descuento por volumen desde 5,000 hojas/mes. Ver /es/precios o calculadora de costos.

Empieza ahora

Solicita tu API key. Aprobamos solicitudes en 24-48 horas con sandbox y credenciales de producción.