Bank statement conversion API
Three calls: create a conversion, upload the file, poll for the result. You get the same reconciled JSON the website shows, or any of the export files. Pages come out of your normal allowance.
Getting a key
Sign in, open your account page and press Create API key. The key is shown once; store it like a password. Your API URL is shown next to it. Every request carries the key as Authorization: Bearer sk_live_….
Keys are tied to your account, so conversions use your plan's pages (10 a month on Free, 300 on Pro, 1,200 on Business, plus any Pages Pack). Revoke a key on the same page; it stops working on the next request.
1. Create a conversion
Tell us the file name (the extension decides how it is read: PDF, PNG/JPG, CSV, QIF, OFX/QFX).
curl -X POST https://YOUR-API-URL/v1/conversions \
-H "Authorization: Bearer sk_live_…" \
-H "Content-Type: application/json" \
-d '{"fileName": "jan-2026.pdf"}'The response contains a one-time upload URL, valid for 15 minutes:
{
"id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"fileName": "jan-2026.pdf",
"upload": {
"url": "https://…s3.amazonaws.com/…?X-Amz-Signature=…",
"method": "PUT",
"headers": { "content-type": "application/pdf" },
"expiresAt": "2026-09-12T10:15:00.000Z",
"maxBytes": 20971520,
"maxPages": 60
},
"statusUrl": "https://YOUR-API-URL/v1/conversions/0f8fad5b-…"
}2. Upload the file
PUT the raw bytes to upload.url with exactly the headers given. No API key on this request; the URL is the credential. Processing starts the moment the upload completes.
curl -X PUT "<upload.url>" \ -H "Content-Type: application/pdf" \ --data-binary @jan-2026.pdf
3. Poll for the result
status is processing, done or error. Poll every few seconds.
curl https://YOUR-API-URL/v1/conversions/0f8fad5b-… \ -H "Authorization: Bearer sk_live_…"
{
"id": "0f8fad5b-…",
"status": "done",
"result": {
"fileName": "jan-2026.pdf",
"pageCount": 3,
"summary": { "bankName": "Example Bank", "accountLast4": "4821", "currency": "USD",
"periodStart": "2026-01-01", "periodEnd": "2026-01-31",
"openingBalance": 4210.00, "closingBalance": 3911.71 },
"transactions": [
{ "date": "2026-01-01", "description": "ACME PAYROLL DEP", "amount": 6300.00,
"balance": 10510.00, "page": 1, "confidence": "high", "category": "Income" }
],
"reconciliation": { "status": "balanced", "difference": 0, "sumCredits": 6344.15,
"sumDebits": 6642.44, "firstSuspectRow": null, "notes": [] }
}
}On error you get { code, message }. Codes: LIMIT_ACCOUNT (out of pages; nothing charged), TOO_MANY_PAGES, FILE_TOO_LARGE, UNSUPPORTED_FORMAT, ENCRYPTED_PDF, NO_TRANSACTIONS, EXTRACTION_FAILED. Failed conversions are never charged.
4. Export files
Once done, fetch any format: xlsx (Excel with categories and a Summary sheet), csv, xero (Xero bank import CSV), qbo (QuickBooks Web Connect), qbcsv (QuickBooks 3-column CSV), tally (TallyPrime Receipt and Payment voucher XML), report (PDF reconciliation report: the verdict in plain words, the figures, then every row).
curl "https://YOUR-API-URL/v1/conversions/0f8fad5b-…/export?format=xlsx" \ -H "Authorization: Bearer sk_live_…" -o jan-2026.xlsx
Tally defaults to an inferred bank ledger and Statement Import Clearing. Add &bankLedger=HDFC%20Bank and &offsetLedger=Import%20Clearing to use the exact ledger names in your company.
Files with several accounts (a combined checking and savings statement) come back with an accounts array on result: one reconciled result per account in the order printed, ids {id}#0, {id}#1…, with the top-level fields mirroring the first account. On export, format=xlsx without an account parameter returns one workbook with a sheet per account; add &account=1 (0-based) to export one account in any format. Pages are charged once per file.
Your allowance
GET /v1/me returns your plan and pages left, so you can stop before a batch runs out.
API questions
What does an API conversion cost?
The same as on the website: one page of a PDF or image is one page of your monthly allowance or Pages Pack. There is no separate API fee. Failed conversions are never charged.
How long does a conversion take?
Usually 10 to 40 seconds for a typical statement, up to a couple of minutes for a 60-page scan. Poll the status URL every few seconds; you will get status "processing" until it is done.
Is the result the same as what the website shows?
Yes. The JSON is exactly what the results page renders: the summary, every transaction with its suggested category, and the reconciliation object (status, difference, first suspect row, notes). Exports are byte-for-byte what the download buttons produce.
How do I know the numbers are right?
Check result.reconciliation.status. "balanced" means opening balance + money in − money out equals the printed closing balance and every running balance follows from the previous row. "unbalanced" gives you firstSuspectRow and notes explaining what to look at. Do not import an unbalanced result without a human glance.
What happens to the file?
Deletion is attempted when processing ends, with an AWS lifecycle rule as the fallback. Result JSON becomes eligible for deletion after 7 days. You can delete it earlier from the account page.
Are there rate limits?
Only your page allowance. Please keep it under a few conversions per second; the pipeline processes about ten statements at a time and queues the rest.