BankConv API documentation
The BankConv REST API converts bank statement PDFs into structured data. Send a PDF with your team API key, poll until the conversion completes, then get the transactions as clean JSON rows, or download CSV, OFX, QFX, QBO or Xero CSV.
Base URL: https://bankconv.com/api/v1
OpenAPI spec: openapi.json
Authentication
Every request needs a team API key, sent as a Bearer token:
Authorization: Bearer sk_live_your_api_keyAPI keys belong to a team. Create them in the BankConv app under your team settings. The full key is shown once, when you create it, so store it somewhere safe. API conversions use your team’s page allowance; see billing.
Quick start
1. Upload a statement
curl -X POST https://bankconv.com/api/v1/conversions \
-H "Authorization: Bearer sk_live_your_api_key" \
-F "[email protected]"The API answers 201 Created with the new conversion:
{
"data": {
"id": "9a8b7c6d-…",
"status": "processing",
"pages_count": 3,
"created_at": "2026-10-11T12:00:00Z",
"input": {
"filename": "statement.pdf",
"pages_count": 3
}
}
}2. Poll the status
curl https://bankconv.com/api/v1/conversions/9a8b7c6d-… \
-H "Authorization: Bearer sk_live_your_api_key"Repeat every few seconds until status is completed or failed.
3. Download the results
# JSON (default)
curl https://bankconv.com/api/v1/conversions/9a8b7c6d-…/download \
-H "Authorization: Bearer sk_live_your_api_key"
# CSV, with matching tables merged into one transaction list
curl "https://bankconv.com/api/v1/conversions/9a8b7c6d-…/download?format=csv&view=merged" \
-H "Authorization: Bearer sk_live_your_api_key" \
-o statement.csv
# QBO for QuickBooks Desktop (also ofx, qfx or xero)
curl "https://bankconv.com/api/v1/conversions/9a8b7c6d-…/download?format=qbo" \
-H "Authorization: Bearer sk_live_your_api_key" \
-o statement.qboEndpoints
All paths are relative to https://bankconv.com/api/v1.
| Method | Path | What it does |
|---|---|---|
POST | /conversions | Upload a PDF and start a conversion |
GET | /conversions | List your team’s conversions (paginated) |
GET | /conversions/{id} | Get a conversion’s status |
GET | /conversions/{id}/transactions | Get the transactions as clean JSON rows |
GET | /conversions/{id}/download | Download as JSON, CSV, OFX, QFX, QBO or Xero CSV |
DELETE | /conversions/{id} | Delete a conversion |
GET | /credits | Check your page balance |
GET | /credits/usage | Pages used in the current period |
Create a conversion
POST /conversions takes a multipart/form-data body.
| Field | Type | Required | Description |
|---|---|---|---|
file | file | Yes | The statement PDF, up to 30 MB |
password | string | No | Password for a protected PDF. It is used to open the file and not stored. |
For a password-protected statement, send the password with the file:
curl -X POST https://bankconv.com/api/v1/conversions \
-H "Authorization: Bearer sk_live_your_api_key" \
-F "[email protected]" \
-F "password=the_pdf_password"If you are not sure what the password is, the bank pages list the formats banks use where we could confirm them.
List conversions
GET /conversions returns your team’s conversions, newest first.
| Parameter | Default | Description |
|---|---|---|
page | 1 | Page number |
per_page | 15 | Results per page, up to 100 |
status | none | Filter by pending, processing, completed or failed |
sort | -created_at | Sort field; a leading - sorts descending |
Get transactions
GET /conversions/{id}/transactions returns the statement's transactions ready to use: real dates, one signed amount (money in positive, money out negative), the running balance, and the opening balance and total lines left out. Amounts are decimal strings in the statement's currency.
curl https://bankconv.com/api/v1/conversions/9a8b7c6d-…/transactions \
-H "Authorization: Bearer sk_live_your_api_key"{
"data": {
"tables": "0:1,1:0",
"institution": "JPMorgan Chase Bank, N.A.",
"country": "US",
"account_type": "checking",
"account_number": "XXXX4821",
"currency": "USD",
"period": { "start": "2026-01-03", "end": "2026-01-31" },
"transaction_count": 42,
"transactions": [
{ "date": "2026-01-03", "description": "Payroll deposit", "reference": null, "amount": "3200.00", "balance": "4450.00" },
{ "date": "2026-01-04", "description": "Coffee shop", "reference": null, "amount": "-4.80", "balance": "4445.20" }
],
"warnings": []
}
}BankConv picks the group of tables that reads into the most transactions and tells you which in tables (page and table indexes, from 0). To read other tables, pass them, for example ?tables=2:0,3:0. If they can't be read as transactions, such as an account summary, the response is 422 unreadable_statement with the reason.
Download results
GET /conversions/{id}/download works once the conversion is completed.
| Parameter | Default | Description |
|---|---|---|
format | json | json, csv, ofx, qfx (Quicken), qbo (QuickBooks Web Connect) or xero (Xero CSV) |
view | raw | For CSV: raw keeps each table as extracted, page by page; merged joins tables with the same columns into one list |
tables | picked for you | For OFX, QFX, QBO and Xero: the tables to use, as in Get transactions |
The JSON response contains every extracted page with its blocks (tables and text), so you can map columns yourself. For ready-made rows, use Get transactions instead.
OFX, QFX, QBO and Xero downloads carry any warnings, such as a bank QuickBooks doesn't list, as a JSON array in the X-BankConv-Warnings header.
Credits and usage
GET /credits returns your page balance for the current billing period:
{
"data": {
"total": 1000,
"remaining": 842,
"bonus": 50,
"bonusRemaining": 50
}
}GET /credits/usage returns the pages used since the start of the period:
{
"data": {
"period_start": "2026-09-11",
"period_end": "2026-10-11",
"pages_used": 158
}
}Responses and errors
Successful responses wrap the result in a data key. Lists add pagination details:
{
"data": [ … ],
"links": { … },
"meta": {
"current_page": 1,
"last_page": 5,
"per_page": 15,
"total": 72
}
}Errors share one shape:
{
"error": {
"code": "insufficient_credits",
"message": "Not enough credits. You have 2 remaining but need 5.",
"status": 422
}
}| Code | Status | Meaning |
|---|---|---|
unauthenticated | 401 | Missing or invalid API key |
not_found | 404 | The conversion does not exist or belongs to another team |
gone | 410 | The conversion was deleted under your retention policy |
validation_error | 422 | Invalid parameters, such as a missing file or a wrong password |
insufficient_credits | 422 | Not enough pages left for the whole document |
payment_failed | 402 | The last subscription payment failed and the plan is paused; billing_url opens the billing portal. Conversions refused meanwhile run once the payment goes through, if that is within your data retention window |
not_ready | 422 | The conversion is still processing, or its statement details are still being read (transactions and accounting formats only, for up to five minutes after completion) |
unreadable_statement | 422 | The tables can't be read as transactions; failure_class says why |
rate_limited | 429 | Too many requests; wait for the number of seconds in Retry-After |
Rate limits
Each API key can make 60 requests per minute. Responses carry X-RateLimit-Limit and X-RateLimit-Remaining headers, and a 429 response includes Retry-After with the seconds to wait.
Billing
Each page of a converted PDF uses one page of your plan’s monthly allowance. A conversion needs enough pages left for the whole document; partial conversions are not made, and the request returns insufficient_credits instead. If your subscription payment has failed, the request returns payment_failed until the card is updated.
| Plan | Pages per month | Price |
|---|---|---|
| Starter | 500 | $29/month, or $19/month billed yearly |
| Professional | 1,000 | $49/month, or $29/month billed yearly |
| Business | 5,000 | $79/month, or $49/month billed yearly |
Compare plans on the pricing page.
Data retention
Conversions are deleted automatically under your team’s retention policy: 24, 48 or 72 hours, 24 by default. After that, download requests return 410 Gone. Download what you need before then, or delete a conversion yourself with DELETE /conversions/{id}. See security and data handling.