Bank statement converter API
Send a bank statement PDF, scan or photo and get back every transaction as JSON, plus the balance-check result. Optionally get the file in Excel, CSV, QuickBooks, Xero, OFX, QIF or Tally format in the same response.
Authentication
Create a key under Account, then send it with every request as Authorization: Bearer sp_live_.... Keys are shown once and stored only as a hash. Revoke a key any time from the same page.
Convert a statement
POST /v1/convert as multipart form data with a file field. Optional fields: password for protected PDFs, and format to also receive a file.
curl -X POST "https://clever-kiwi-15.convex.site/v1/convert" \
-H "Authorization: Bearer $STATEMENTPANDA_KEY" \
-F "file=@statement.pdf" \
-F "format=xlsx"Or send the raw file as the body, with the file name in the query string:
curl -X POST "https://clever-kiwi-15.convex.site/v1/convert?filename=statement.pdf" \
-H "Authorization: Bearer $STATEMENTPANDA_KEY" \
--data-binary @statement.pdfThe request waits for the conversion (usually a few seconds; scans and photos can take up to a minute). The response:
{
"id": "k57d2v9a1x8m3c0q",
"pages_used": 2,
"statement": {
"bank": "Barclays",
"currency": "GBP",
"account_type": "bank",
"period_start": "2026-01-01",
"period_end": "2026-01-31",
"opening_balance": "1523.40",
"closing_balance": "1766.34",
"method": "text",
"pages": 2,
"warnings": [],
"transactions": [
{
"date": "2026-01-02",
"description": "CARD 4421 COFFEE HOUSE",
"debit": "4.80",
"credit": null,
"balance": "1518.60",
"category": "Meals & entertainment",
"page": 1,
"raw_date": "02 Jan",
"flags": []
}
]
},
"validation": {
"status": "verified",
"mode": "running+totals",
"mismatched_rows": [],
"expected_closing": "1766.34",
"difference": "0.00",
"message": "All 42 transactions reconcile to the statement balances."
},
"file": {
"filename": "barclays-2026-01-31.xlsx",
"mime": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"base64": "UEsDBBQABgAIAAAAIQ...",
"rows_skipped": 0
}
}validation.status is verified when every row reconciles to the printed balances, mismatch when a row doesn't (see mismatched_rows and each row's flags), or unverified when the statement prints no balances to check against. file is only present when you asked for a format.
Formats
Check your balance
GET /v1/balance
curl "https://clever-kiwi-15.convex.site/v1/balance" \
-H "Authorization: Bearer $STATEMENTPANDA_KEY"{
"plan": "pro",
"pages_available": 2431,
"monthly_left": 2431,
"rollover": 0,
"pack_pages": 0
}Errors
Errors return JSON like { "error": { "code": "NO_CREDITS", "message": "..." } }.
| HTTP | Code | Meaning |
|---|---|---|
| 400 | BAD_REQUEST, NO_FILE, NO_FILENAME, BAD_FORMAT | The request is missing the file, its name, or uses an unknown format. |
| 401 | UNAUTHORIZED | Missing, invalid or revoked API key. |
| 402 | NO_CREDITS | Not enough pages left. The response includes pages_available. |
| 403 | UPGRADE | Your plan doesn't include the API or the requested format. |
| 413 | TOO_LARGE | Files can be up to 20 MB. |
| 415 | BAD_FILE | Not a PDF or supported image (JPG, PNG, WebP, HEIC). |
| 422 | PASSWORD, WRONG_PASSWORD, UNREADABLE | The PDF needs a password, the password was wrong, or no transactions were found. Not charged. |
| 500 | ERROR | Something went wrong on our side. Not charged. |
Pricing
The API uses the same pages as the website: one page of a statement is one page, and failed conversions are never charged. API access is included in Pro ($49/mo, 2,500 pages/month) and Business ($129/mo, 8,000 pages/month). Page packs top up the same balance. See pricing. You can try the converter itself with 5 free pages before choosing a plan.
Data handling
Uploaded files are deleted as soon as each conversion finishes, whatever the outcome, and are never used to train AI. The extracted transactions are returned to you and kept in your account history until you delete them. See Security.
Limits
Files up to 20 MB. PDF, JPG, PNG, WebP and HEIC. One statement per request; send several requests in parallel for batches.