Introducción
La API de Balanzio te permite convertir PDFs de extractos bancarios a formatos de datos estructurados (CSV, XLSX, JSON). Nuestra API soporta tanto PDFs de texto como basados en imágenes (escaneados) con procesamiento OCR.
Procesamiento Rápido
PDFs de texto en segundos, OCR en <30s por página
Seguro y Conforme con GDPR
Eliminación automática después de 24h
Soporte Multi-Banco
Más de 100 bancos soportados
Autenticación
Todas las solicitudes API requieren autenticación usando un token Bearer. Incluye tu clave API en el encabezado Authorization:
Authorization: Bearer YOUR_API_KEYNunca expongas tu clave API en código del lado del cliente ni la confirmes en control de versiones.
Endpoints
URL Base
https://api.balanzio.app/api/v1Subir Extracto Bancario
/bank-statementSube uno o múltiples archivos PDF para procesamiento. La API detectará automáticamente si el PDF es de texto o basado en imagen (escaneado).
Parámetros de Solicitud
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
files | file[] | Sí | Archivo(s) PDF para procesar (máx. 3MB cada uno) |
Ejemplo de Solicitud
curl -X POST https://api.balanzio.app/api/v1/bank-statement \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "files=@statement.pdf"Respuesta (201 Created)
[
{
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"filename": "statement.pdf",
"pdfType": "TEXT_BASED",
"state": "READY",
"numberOfPages": 3
}
]Campos de Respuesta
| Campo | Tipo | Descripción |
|---|---|---|
uuid | string | Identificador único para el archivo subido |
filename | string | Nombre de archivo original |
pdfType | string | TEXT_BASED o IMAGE_BASED |
state | string | READY (texto) o PROCESSING (OCR) |
numberOfPages | number | Páginas totales en el PDF |
Verificar Estado de Procesamiento
/bank-statement/statusVerifica el estado de procesamiento de los archivos subidos. Usa este endpoint para consultar la finalización del OCR.
Ejemplo de Solicitud
curl -X POST https://api.balanzio.app/api/v1/bank-statement/status \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"uuids": ["550e8400-e29b-41d4-a716-446655440000"]
}'Respuesta (200 OK)
[
{
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"filename": "statement.pdf",
"pdfType": "IMAGE_BASED",
"state": "COMPLETED",
"numberOfPages": 3,
"progress": 100
}
]Convertir a Formato
/bank-statement/convertConvierte extractos procesados a formato CSV, XLSX o JSON.
Parámetros de Consulta
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
format | string | Sí | CSV, XLSX o JSON |
Ejemplo de Solicitud (CSV)
curl -X POST "https://api.balanzio.app/api/v1/bank-statement/convert?format=CSV" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"uuid": "550e8400-e29b-41d4-a716-446655440000"
}' \
-o statement.csvEjemplo de Solicitud (JSON)
curl -X POST "https://api.balanzio.app/api/v1/bank-statement/convert?format=JSON" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"uuid": "550e8400-e29b-41d4-a716-446655440000"
}'Respuesta (formato JSON)
{
"transactions": [
{
"date": "2024-01-15",
"description": "VIREMENT SALAIRE",
"amount": 3500.00,
"balance": 4250.50,
"currency": "EUR"
},
{
"date": "2024-01-16",
"description": "CARTE 12/01 SUPERMARCHE",
"amount": -85.30,
"balance": 4165.20,
"currency": "EUR"
}
],
"metadata": {
"bank": "BNP Paribas",
"accountNumber": "****1234",
"statementPeriod": "2024-01"
},
"warnings": []
}Establecer Contraseña de PDF
/bank-statement/set-passwordProporciona contraseña para PDFs protegidos con contraseña.
Ejemplo de Solicitud
curl -X POST https://api.balanzio.app/api/v1/bank-statement/set-password \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"password": "mySecretPassword123"
}'Respuesta (200 OK)
{
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"state": "READY",
"passwordSet": true
}Obtener Información de Usuario
/userRecupera la información del usuario actual, incluyendo créditos y detalles del plan.
Ejemplo de Solicitud
curl -X GET https://api.balanzio.app/api/v1/user \
-H "Authorization: Bearer YOUR_API_KEY"Respuesta (200 OK)
{
"user": {
"userId": 123,
"firstName": "John",
"lastName": "Doe",
"email": "john@example.com",
"emailVerified": true,
"referralCode": "ABC123"
},
"credits": {
"paidCredits": 1000,
"freeCredits": 50
},
"unlimitedCredits": false,
"subscriptionCount": 1,
"plan": "pro",
"saveConvertedFiles": false,
"hasPaymentMethod": true
}Códigos de Error
Todos los errores devuelven una respuesta JSON con un código de error y mensaje:
{
"error": "INVALID_FILE_TYPE",
"message": "Only PDF files are accepted",
"recovery": "Please upload a PDF file"
}| Estado | Código de Error | Descripción |
|---|---|---|
400 | INVALID_FILE_TYPE | El archivo no es un PDF |
400 | INVALID_FORMAT | Parámetro de formato inválido (debe ser CSV, XLSX o JSON) |
401 | UNAUTHORIZED | Clave API inválida o faltante |
403 | INSUFFICIENT_CREDITS | No hay suficientes créditos para procesar el archivo |
404 | FILE_NOT_FOUND | UUID de archivo no encontrado |
413 | FILE_TOO_LARGE | El archivo excede el límite de 3MB |
422 | PASSWORD_REQUIRED | El PDF está protegido con contraseña |
422 | INVALID_PASSWORD | Contraseña de PDF incorrecta |
429 | RATE_LIMIT_EXCEEDED | Demasiadas solicitudes |
500 | INTERNAL_ERROR | Error del servidor, por favor reintenta |
Límites de Velocidad
Usuarios Anónimos
• 10 solicitudes por minuto
• 1 página por día
• Sin subidas concurrentes
Usuarios Autenticados
• 60 solicitudes por minuto
• Basado en créditos (dependiente del plan)
• Hasta 5 subidas concurrentes
Encabezados de límite de velocidad: Todas las respuestas incluyen encabezados X-RateLimit-Limit, X-RateLimit-Remaining y X-RateLimit-Reset.
Ejemplos de Código Completos
Python
import requests
import time
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.balanzio.app/api/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
# 1. Upload PDF
with open("statement.pdf", "rb") as f:
files = {"files": f}
response = requests.post(
f"{BASE_URL}/bank-statement",
headers=HEADERS,
files=files
)
data = response.json()
file_uuid = data[0]["uuid"]
pdf_type = data[0]["pdfType"]
print(f"Uploaded: {file_uuid} ({pdf_type})")
# 2. Poll status if OCR is needed
if pdf_type == "IMAGE_BASED":
while True:
response = requests.post(
f"{BASE_URL}/bank-statement/status",
headers=HEADERS,
json={"uuids": [file_uuid]}
)
status = response.json()[0]
if status["state"] == "COMPLETED":
print("Processing complete!")
break
elif status["state"] == "ERROR":
print("Processing failed:", status.get("error"))
break
print(f"Progress: {status.get('progress', 0)}%")
time.sleep(3)
# 3. Convert to JSON
response = requests.post(
f"{BASE_URL}/bank-statement/convert",
headers=HEADERS,
params={"format": "JSON"},
json={"uuid": file_uuid}
)
transactions = response.json()
print(f"Found {len(transactions['transactions'])} transactions")
for txn in transactions["transactions"]:
print(f"{txn['date']}: {txn['description']} - {txn['amount']} {txn['currency']}")Node.js
const FormData = require('form-data');
const fs = require('fs');
const fetch = require('node-fetch');
const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://api.balanzio.app/api/v1';
const HEADERS = { 'Authorization': `Bearer ${API_KEY}` };
async function convertBankStatement() {
// 1. Upload PDF
const form = new FormData();
form.append('files', fs.createReadStream('statement.pdf'));
let response = await fetch(`${BASE_URL}/bank-statement`, {
method: 'POST',
headers: HEADERS,
body: form
});
const uploadData = await response.json();
const fileUuid = uploadData[0].uuid;
const pdfType = uploadData[0].pdfType;
console.log(`Uploaded: ${fileUuid} (${pdfType})`);
// 2. Poll status if OCR needed
if (pdfType === 'IMAGE_BASED') {
let completed = false;
while (!completed) {
response = await fetch(`${BASE_URL}/bank-statement/status`, {
method: 'POST',
headers: { ...HEADERS, 'Content-Type': 'application/json' },
body: JSON.stringify({ uuids: [fileUuid] })
});
const statusData = await response.json();
const status = statusData[0];
if (status.state === 'COMPLETED') {
console.log('Processing complete!');
completed = true;
} else if (status.state === 'ERROR') {
throw new Error(`Processing failed: ${status.error}`);
} else {
console.log(`Progress: ${status.progress || 0}%`);
await new Promise(resolve => setTimeout(resolve, 3000));
}
}
}
// 3. Convert to JSON
response = await fetch(
`${BASE_URL}/bank-statement/convert?format=JSON`,
{
method: 'POST',
headers: { ...HEADERS, 'Content-Type': 'application/json' },
body: JSON.stringify({ uuid: fileUuid })
}
);
const transactions = await response.json();
console.log(`Found ${transactions.transactions.length} transactions`);
transactions.transactions.forEach(txn => {
console.log(`${txn.date}: ${txn.description} - ${txn.amount} ${txn.currency}`);
});
}
convertBankStatement().catch(console.error);PHP
<?php
$apiKey = 'YOUR_API_KEY';
$baseUrl = 'https://api.balanzio.app/api/v1';
// 1. Upload PDF
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$baseUrl/bank-statement");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $apiKey"
]);
$file = new CURLFile('statement.pdf', 'application/pdf', 'statement.pdf');
curl_setopt($ch, CURLOPT_POSTFIELDS, ['files' => $file]);
$response = curl_exec($ch);
$data = json_decode($response, true);
$fileUuid = $data[0]['uuid'];
$pdfType = $data[0]['pdfType'];
echo "Uploaded: $fileUuid ($pdfType)\n";
// 2. Poll status if OCR needed
if ($pdfType === 'IMAGE_BASED') {
do {
sleep(3);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$baseUrl/bank-statement/status");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $apiKey",
"Content-Type: application/json"
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'uuids' => [$fileUuid]
]));
$response = curl_exec($ch);
$statusData = json_decode($response, true);
$status = $statusData[0];
echo "Progress: " . ($status['progress'] ?? 0) . "%\n";
} while ($status['state'] !== 'COMPLETED' && $status['state'] !== 'ERROR');
echo "Processing complete!\n";
}
// 3. Convert to JSON
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$baseUrl/bank-statement/convert?format=JSON");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $apiKey",
"Content-Type: application/json"
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'uuid' => $fileUuid
]));
$response = curl_exec($ch);
$transactions = json_decode($response, true);
echo "Found " . count($transactions['transactions']) . " transactions\n";
foreach ($transactions['transactions'] as $txn) {
echo "{$txn['date']}: {$txn['description']} - {$txn['amount']} {$txn['currency']}\n";
}
curl_close($ch);
?>