Skip to main content
Bankflow

Bank statement API: Statements in over HTTP, transactions out as JSON.

POST a bank statement PDF, CSV, XLSX, or JSON file to one endpoint and get the parsed, balance-checked transactions back in the response. Or queue it, and let a signed webhook tell your system when it is done. No template per bank, no parser to maintain.

50 free page credits · No card · Cancel anytime

  • One-shot parse endpoint
  • Signed webhooks
  • OpenAPI spec
Imports & API

Forward statements to

statements@mail.bankflow.app

Workflows watch

Google DriveOneDriveDropbox

POST /api/v1/parse

Authorization: Bearer bnfw_••••

200 { "transactions": 142 }

Every bank prints its statement differently, and keeps changing it.

Building statement parsing in-house starts as a regex for one bank's layout and becomes a maintenance line item: a second bank, a redesigned PDF, a scanned upload, a card statement whose credits sit in the wrong column. Each fix is small and none of them end. The part of your product that needs the transactions does not care how they were read; it needs them structured, with a signal when the numbers do not add up. That is the part worth buying rather than building.

How it works

Wiring statements into your product

  1. 01

    Create a token

    Generate a personal access token in the app. Tokens carry a bnfw_ prefix, can be revoked at any time, and authenticate every request as a Bearer header.

  2. 02

    Parse in one call

    POST the file to /api/v1/parse as a raw PDF body or multipart form data. The response carries the stored statement, with its bank, currency, and balances, and the transactions inline. Files up to 50 MB.

  3. 03

    Or queue it and listen

    Upload to /api/v1/statements and return immediately. When the parse finishes, transactions.created delivers the full transaction list to your endpoint; statement.failed tells you when a file could not be read.

    The webhooks tab: an endpoint URL, the events it subscribes to, and a signed delivery secret.
    A webhook endpoint, the events it subscribes to, and its signing secret.
  4. 04

    Read, correct, export

    List a statement's transactions, update a transaction's category, notes, or tags, pull a statement's insights, or ask for an export in any of the product's formats, all over the same API.

In code

One POST, and the transactions are back

The one-shot endpoint holds the request open while the file is read, checks the rows against the balances the statement prints, and returns both the statement and its transactions. No polling, no job id to track.

Request

curl -X POST https://api.bankflow.app/api/v1/parse \
  -H "Authorization: Bearer bnfw_live_xxx" \
  -H "Content-Type: application/pdf" \
  --data-binary @statement.pdf

Response

{
  "data": {
    "id": 8412,
    "fileName": "statement.pdf",
    "status": "completed",
    "bankName": "Chase",
    "currency": "USD",
    "transactionCount": 38,
    "openingBalance": 4820.11,
    "closingBalance": 6190.44
  },
  "transactions": [
    {
      "id": 90211,
      "date": "2026-08-01",
      "description": "STRIPE PAYOUT 4AF2C9",
      "amount": 4820.50,
      "type": "credit",
      "category": "Income",
      "tags": [],
      "balance": 9640.61
    }
  ]
}

Files up to 50 MB, as a raw body or multipart form data. Queue the same file at POST /api/v1/statements instead and the result arrives as a signed webhook.

Read the full API reference

The API surface

Structured transactions

Date, description, amount, type, category, and the statement's opening and closing balances, as JSON your code can use directly.

Five webhook events

statement.completed, transactions.created, statement.failed, statement.deleted, and transaction.updated, each signed with a secret you can rotate.

More than PDFs

CSV, XLSX, and JSON statements go through the same endpoints and come back in the same shape, with a column-detection endpoint for tabular files.

Revocable tokens

Create, copy, and revoke tokens from the app. A leaked token is one click from useless.

An OpenAPI spec

A machine-readable specification at /api/v1/openapi.json for client generation and Swagger-style tooling.

Other ways in, same events

A statement forwarded by email fires the same transactions.created event as an API upload, so one handler covers both routes in.

Endpoints at a glance

The full reference, with request and response shapes, is in the API docs.

EndpointWhat it does
POST /api/v1/parseParse a file and return its transactions inline
POST /api/v1/statementsQueue a file; results arrive by webhook
GET /api/v1/statements/:id/transactionsList a statement's transactions
GET /api/v1/statements/:id/exportExport a statement in a chosen format
PATCH /api/v1/transactions/:idUpdate category, notes, or tags
POST /api/v1/webhooksRegister an endpoint and receive its signing secret

Base URL https://api.bankflow.app. Every endpoint takes a Bearer token. Requests are budgeted per key, at 60 a minute on the free plan and 120, 300, or 600 on the paid ones, and every response carries RateLimit-Limit, RateLimit-Remaining, and RateLimit-Reset so a client can pace itself rather than discover the limit by tripping it.

FAQ

Common questions

Is parsing synchronous or asynchronous?

Both are available. /api/v1/parse holds the request open and returns the transactions in the response; /api/v1/statements accepts the file and returns straight away, with the result delivered by webhook.

What happens when a statement does not balance?

The parse validates running balances against the statement's printed opening and closing figures. A statement that cannot be reconciled is flagged for review rather than returned as if it were clean.

How are webhooks secured?

Each endpoint gets a signing secret, shown once when you register it, and deliveries are signed with it. The secret can be rotated through the API without re-registering the endpoint.

What does a parsed page cost?

One credit, where a credit is one standard page, and the same credit whether the file arrives through the API or the app. That works out at about 5 cents a page on the $14.99 plan, 4 cents on the $39.99 plan, and 3.3 cents on the $99.99 plan, with top-up packs at 4 cents. API access itself costs nothing extra and is on every plan, the free one included. Note that page-priced and document-priced APIs are not comparable until you know your page count: a per-document price looks cheaper until a statement runs to twelve pages.

What are the rate limits?

Sixty requests a minute per key on the free plan, and 120, 300, or 600 on the paid plans. Uploads are bounded separately by how many documents an account can parse at once and by a daily document limit. Every response carries RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, and RateLimit-Policy, and a 429 carries Retry-After, so backing off correctly takes no guesswork.

How is this different from open banking, such as Plaid or TrueLayer?

An open banking provider connects to the account itself and needs the account holder to authenticate, which gives you live transactions and typically 90 days to 24 months of history depending on the bank. A statement API needs no connection and no credentials: it reads the document your user already has, which means older history than any feed reaches, banks no aggregator covers, closed accounts, and files a user can hand over by email. Plenty of products use both: a feed for ongoing data, statements for the history and the banks the feed cannot see.

Which banks are supported?

There is no per-bank template. The parser reads the statement's layout itself, including scanned and password-protected PDFs, so a bank's first statement works the same way as its hundredth.

Is there a sandbox?

The free tier is the sandbox: 50 page credits, the full API, and webhooks, with no card required.

Parse your first statement with curl.

Create a free account, generate a token, and POST a PDF. The transactions come back in the response.