Bank Statement API for Developers: Complete Integration Guide 2026
Bank Statement API: Complete Integration Guide for Developers
Whether you're building a fintech app, accounting software, or a data pipeline, integrating bank statement parsing via API saves months of development time.
Why Use an API Instead of Building Your Own?
Building a reliable bank statement parser from scratch requires:
- Handling 100+ different PDF layouts
- Parsing dates in 20+ formats across languages
- Distinguishing debits from credits across different conventions
- Rebuilding templates every time a bank updates its format
An API abstracts all of this. You send a PDF, you get structured JSON.
Authentication
Get an API key from your dashboard (starts with pex_):
curl -X POST https://api.bank-statement-parser.clkr.work/extract \
-H "X-Api-Key: pex_your_api_key" \
-F "file=@statement.pdf"
Python Integration
import requests
from pathlib import Path
class BankStatementParser:
BASE_URL = "https://api.bank-statement-parser.clkr.work"
def __init__(self, api_key: str):
self.session = requests.Session()
self.session.headers.update({"X-Api-Key": api_key})
def extract(self, pdf_path: str | Path) -> dict:
with open(pdf_path, "rb") as f:
response = self.session.post(
f"{self.BASE_URL}/extract",
files={"file": (Path(pdf_path).name, f, "application/pdf")}
)
response.raise_for_status()
return response.json()
def extract_batch(self, pdf_paths: list) -> list[dict]:
return [self.extract(p) for p in pdf_paths]
# Usage
parser = BankStatementParser("pex_your_api_key")
result = parser.extract("statement.pdf")
print(f"Bank: {result['bankKey']}")
print(f"Pages: {result['pageCount']}")
print(f"Transactions: {len(result['transactions'])}")
Node.js / TypeScript Integration
import FormData from 'form-data';
import fs from 'fs';
interface Transaction {
date: string;
description: string;
amount: number;
balance: number;
}
interface ParseResult {
bankKey: string;
pageCount: number;
transactions: Transaction[];
}
async function parseStatement(filePath: string): Promise {
const form = new FormData();
form.append('file', fs.createReadStream(filePath));
const response = await fetch(
'https://api.bank-statement-parser.clkr.work/extract',
{
method: 'POST',
headers: {
'X-Api-Key': 'pex_your_api_key',
...form.getHeaders(),
},
body: form as unknown as BodyInit,
}
);
if (!response.ok) {
throw new Error(Parse failed: ${response.status} ${response.statusText});
}
return response.json();
}
Error Handling
import requests
def safe_extract(pdf_path: str, api_key: str) -> dict | None:
try:
response = requests.post(
"https://api.bank-statement-parser.clkr.work/extract",
headers={"X-Api-Key": api_key},
files={"file": open(pdf_path, "rb")},
timeout=60
)
match response.status_code:
case 200:
return response.json()
case 402:
print("Monthly quota exceeded — upgrade your plan")
case 415:
print("File is image-based (OCR not yet supported)")
case 422:
print("Could not parse this format")
case 429:
print("Rate limited — slow down requests")
case _:
response.raise_for_status()
except requests.Timeout:
print("Request timed out — file may be too large")
except requests.ConnectionError:
print("Connection error")
return None
Webhook Integration
For async processing (large files, high-volume workflows):
from flask import Flask, request, jsonify
import requests
app = Flask(__name__)
# Submit a PDF for async processing
def submit_async(pdf_path: str, webhook_url: str):
return requests.post(
"https://api.bank-statement-parser.clkr.work/extract",
headers={
"X-Api-Key": "pex_your_api_key",
"X-Webhook-Url": webhook_url,
},
files={"file": open(pdf_path, "rb")}
).json()
# Your webhook endpoint receives the result
@app.route("/bank-callback", methods=["POST"])
def handle_result():
data = request.json
transactions = data["transactions"]
bank = data["bankKey"]
# Store in database, trigger next step, etc.
print(f"Received {len(transactions)} transactions from {bank}")
return jsonify({"ok": True})
Response Schema
{
bankKey: string; // e.g. "garantibbva_v1", "isbank_v2"
pageCount: number; // number of PDF pages processed
transactions: Array<{
date: string; // ISO 8601: "2026-05-15"
description: string; // raw transaction description
amount: number; // negative = debit, positive = credit
balance: number | null; // running balance (null if not in PDF)
}>;
}
Rate Limits & Quotas
| Plan | Pages/month | Requests/min |
|------|-------------|--------------|
| Free | 3,000 | 10 |
| Starter | 500 | 30 |
| Professional | 3,000 | 60 |
| Enterprise | 15,000 | 200 |
Get Your API Key
[Create a free account →](https://bank-statement-parser.clkr.work/en/register) — 3,000 pages/month, no credit card.