Back to Blog
June 25, 2026

Bank Statement Webhook Integration — Async Fintech Workflows

TL;DR

For asynchronous bank statement processing, submit the PDF and receive a job ID immediately, then let the API POST the finished result to your webhook URL when extraction completes. This suits large files and batch uploads: your service stays responsive, and you verify the payload signature before trusting the data.

Bank Statement Webhook Integration

For large PDF files or high-volume workflows, asynchronous processing is essential. With webhook integration, you submit a PDF and automatically receive a notification when processing completes.

How Webhooks Work

1. Submit a PDF with your webhook URL

2. The API accepts it and immediately returns 202 Accepted

3. When processing completes, the API POSTs the result to your webhook URL

4. Your server handles the result (store to DB, send notification, etc.)

Python Flask Webhook Server

from flask import Flask, request, jsonify

import requests

app = Flask(__name__)

def submit_pdf(pdf_path: str, webhook_url: str, api_key: str) -> dict:

resp = requests.post(

"https://api.bankstatementparser.net/extract",

headers={

"X-Api-Key": api_key,

"X-Webhook-Url": webhook_url

},

files={"file": open(pdf_path, "rb")}

)

return resp.json()

@app.route("/webhook/bank-statement", methods=["POST"])

def receive_statement():

data = request.json

transactions = data.get("transactions", [])

format_key = data.get("bankKey", "unknown")

print(f"✓ {format_key}: {len(transactions)} transactions received")

for txn in transactions:

save_to_database(txn)

return jsonify({"ok": True})

def save_to_database(txn: dict):

print(f" {txn['date']} | {txn['description'][:40]:40} | {txn['amount']:>10.2f}")

if __name__ == "__main__":

result = submit_pdf(

"statement.pdf",

"https://your-app.com/webhook/bank-statement",

"pex_your_api_key"

)

print("Queued:", result)

app.run(port=5000)

Node.js / Express Webhook

const express = require('express');

const FormData = require('form-data');

const fs = require('fs');

const fetch = require('node-fetch');

const app = express();

app.use(express.json());

async function submitPdf(filePath, webhookUrl, apiKey) {

const form = new FormData();

form.append('file', fs.createReadStream(filePath));

const resp = await fetch('https://api.bankstatementparser.net/extract', {

method: 'POST',

headers: {

'X-Api-Key': apiKey,

'X-Webhook-Url': webhookUrl,

...form.getHeaders()

},

body: form

});

return resp.json();

}

app.post('/webhook/bank-statement', (req, res) => {

const { bankKey, transactions, pageCount } = req.body;

console.log(✓ ${bankKey}: ${transactions.length} transactions, ${pageCount} pages);

transactions.forEach(t => {

console.log( ${t.date} | ${t.description.slice(0, 40).padEnd(40)} | ${t.amount});

});

res.json({ ok: true });

});

app.listen(3001, async () => {

console.log('Webhook server listening on port 3001');

const result = await submitPdf('statement.pdf', 'https://your-app.com/webhook/bank-statement', 'pex_your_api_key');

console.log('Queued:', result);

});

Webhook Payload Schema

{

"bankKey": "format_v1",

"pageCount": 3,

"transactionCount": 47,

"transactions": [

{

"date": "2026-05-01",

"description": "PAYMENT",

"amount": -245.90,

"balance": 12450.10

}

]

}

Free Tier

50 pages/month free, no credit card. [Sign up →](https://bankstatementparser.net/en/register)

Get Started for Free

Up to 50 pages/month free. No credit card required.

Create Account