Back to Blog
June 9, 2026

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.

Get Started for Free

Up to 3,000 pages/month free. No credit card required.

Create Account