for developers

Bank Statement Parser API

A local-first PDF, OFX, QFX, MT940 and CAMT.053 parser that runs entirely in the browser via WebAssembly. No uploads, no API key, no per-document fee, no vendor lock-in.

Zero uploads
PDFs never leave the user's browser. No data-processor agreements, no PCI scope creep, no breach risk.
WebAssembly
Near-native parsing speed. A 12-month statement returns JSON in under a second on mid-range hardware.
No backend
No Lambda, no API key, no rate limit, no per-call billing. Ship the library and forget about it.
GDPR / SOC 2 friendly
If the file never leaves the device, your app is not a sub-processor. Compliance review drops by an order of magnitude.
8 formats
PDF, OFX, QFX, QBO, MT940, CAMT.053, BAI2, and PayPal CSV. One normalized JSON output.
Typed output
Each transaction is { date, amount, description, balance, raw } so you can map to QBO, Xero, or your own schema.

Quick start

Drop into any frontend. Same call signature in Node, Electron, and Tauri.

Browser — script tag
<script src="https://convertbank.online/parser.wasm.js"></script>
<script>
  const file = document.querySelector('input[type=file]').files[0];
  const { transactions } = await convertbank.parse(file);
  // transactions: [{ date, amount, description, balance, raw }, ...]
</script>
NPM / TypeScript
import { parse } from "@convertbank/parser";

const buf = await file.arrayBuffer();
const { transactions, format } = await parse(buf, {
  format: "auto",        // "pdf" | "ofx" | "qfx" | "mt940" | "camt053" | "bai2" | "csv"
  locale: "en-GB",       // affects date parsing (DD/MM vs MM/DD)
  ocrFallback: true,     // scanned PDFs only
});

// format === "pdf" | "ofx" | ...
// transactions[0] === { date, amount, description, balance, raw }
Electron / Tauri (local-first desktop)
// In an Electron / Tauri / Capacitor app: same import, same API.
// Bank statements stay on the user's filesystem — no cloud round-trip.
import { parse } from "@convertbank/parser";
import { readFile } from "node:fs/promises";

const buf = await readFile("/Users/alice/Downloads/chase-jan.pdf");
const { transactions } = await parse(buf);

Why local-first matters for financial data

Most "Bank Statement Parser API" vendors are hosted endpoints. Your app POSTs a customer's PDF, the vendor's server runs OCR, and you get JSON back. That model has three durable problems: every customer file becomes a sub-processor relationship under GDPR, every outage at the vendor breaks your product, and every parsed document costs $0.05 – $0.50.

The local-first model flips this. The same parsing logic — PDF text extraction, OCR for scanned statements, XML schema validation for CAMT.053, fixed-format decoding for MT940 — is compiled to WebAssembly and shipped inside your frontend. The customer's browser does the work. The bank statement never reaches your server, the vendor's server, or any third party. There is no per-document cost, no rate limit, and no compliance review of an external data processor because there is no external data processor.

The tradeoff is bundle size — typically 2–3 MB of gzipped WASM, loaded lazily on the page that needs it. For a fintech, accounting, or bookkeeping product where the parsing page is a deliberate user action, that's a sensible cost. For a high-frequency consumer app where every kilobyte matters, the hosted route may still win.

Supported formats

FormatUsed byNotes
PDFAlmost every retail bankText-layer extraction, OCR fallback for scans.
OFX / QFXUS retail banks, QuickenXML-ish; QFX adds an Intuit ID.
QBOQuickBooks Web ConnectOFX wrapped with Intuit identifiers.
MT940SWIFT corporate bankingFixed-tag :20: :25: :60F: :61: :86: format.
CAMT.053SEPA / ISO 20022XML schema-validated against camt.053.001.x.
BAI2US corporate / treasuryFixed-record cash-management standard.
PayPal CSVPayPal Reports → ActivityLocale-aware date and amount parsing.

FAQ

Is there a hosted Bank Statement Parser API?

No — and that is the point. Hosted parsers send your customers' bank statements to a third-party server, which creates compliance and breach risk. The convertbank parser is shipped as a browser library powered by WebAssembly. Your users' PDFs never leave their device, so you avoid the data-processor classification under GDPR, SOC 2, and PCI scope creep entirely.

What formats does the parser support?

PDF (text and scanned with OCR fallback), OFX, QFX, QBO, MT940, CAMT.053 XML, BAI2, and PayPal CSV. Output is a normalized JSON array of transactions with date, amount, description, balance, and original raw line — so you can build CSV, QBO, or your own format on top.

Why WebAssembly?

PDF parsing, OCR, and XML schema validation are CPU-heavy. WebAssembly runs at near-native speed inside the browser sandbox, which means a 12-month statement parses in under a second on a mid-range laptop. It also means no Node.js server, no Lambda cold starts, and no per-call billing.

How do I integrate it into my app?

Drop the script tag or NPM package into your frontend, call parse(file) with a File or ArrayBuffer, and get back a typed array of transactions. There is no API key, no rate limit, and no network call. The same code path runs in Chrome, Safari, Firefox, and Electron apps.

How does this compare to hosted parsers like Plaid, Ocrolus, or BankStatementConverter.com?

Hosted parsers charge per-document, require you to upload customer data, and add 200–800 ms of network latency per call. A local-first library is free at the marginal level, keeps data on the user's machine, and removes a whole class of vendor dependencies from your stack. The tradeoff is that you ship slightly more JS — typically 2–3 MB gzipped of WASM.

Can I use it for production fintech workloads?

Yes. The parser powers convertbank.online, which processes thousands of statements per month. The same WASM module is reusable in any frontend — React, Vue, Svelte, vanilla JS, or a Tauri / Electron desktop app where local-first is a hard requirement.

Want early access to the NPM package?

The WASM library powers convertbank.online today. The standalone package ships next — request access and we'll send the install instructions.

Request access