Reference
API reference
Every endpoint below is generated from the same catalog the API serves — this page can’t drift from what’s actually deployed. Machine-readable versions: /api/openapi and /llms.txt.
Base URL
https://ledgerary.com/api/v1
Auth
Optional for /extract and /pricing (anonymous = throttled trial, no API/MCP access on Free). Send `Authorization: Bearer nmr_live_…` (or `x-api-key`) for a Pro/Scale key.
Metering
Metered by page (one statement page = one billable unit).
Response envelope
Every successful /extract response includes a request_id for tracing, a disclaimer, the balance check and a confidence score. Free/anonymous responses also carry an attribution field.
{
"extraction_id": "ext_9f3ac1d0",
"status": "completed",
"meta": {
"doc_type": "bank_statement",
"institution": "Northgate Bank",
"currency": "USD",
"period_start": "2026-05-01",
"period_end": "2026-05-31",
"opening_balance": 4120.55,
"closing_balance": 4863.28
},
"transactions": [
{ "date": "2026-05-02", "description": "SQ *BLUE BOTTLE COFFEE", "amount": -6.75, "direction": "debit", "balance": 4113.80, "category": "Coffee/Dining" },
{ "date": "2026-05-03", "description": "PAYROLL ACME CORP DIRECT DEP", "amount": 3200, "direction": "credit", "balance": 7313.80, "category": "Payroll" }
],
"totals": { "debits": -2570.27, "credits": 3374.99 },
"balance_check": "passed",
"balance_delta": 0,
"confidence": 0.97,
"page_count": 2,
"warnings": [],
"request_id": "req_9f3ac1d0",
"disclaimer": "Ledgerary is a document-conversion tool: it extracts the data already ...",
"attribution": "Extracted with Ledgerary (free tier only)"
}Errors
Structured, never silent
Every non-2xx response is JSON — never a fabricated fallback.
| code | status | meaning |
|---|---|---|
| invalid_request | 400 | A required field is missing or malformed (e.g. neither file_base64 nor file_url given). |
| unauthorized | 401 | The Authorization header is missing a valid, unrevoked API key for an endpoint that requires one. |
| upgrade_required | 402 | The Free plan has no API/MCP access, or the requested export format needs Pro or Scale. |
| not_found | 404 | No extraction exists for the given id (or it belongs to a different owner). |
| payload_too_large | 413 | The file exceeds the 15 MB limit. |
| unsupported_media_type | 415 | Only PDF statements are supported right now. |
| unprocessable | 422 | The file couldn't be read as a statement, or wasn't a bank/card statement at all — never a fabricated fallback. |
| rate_limited | 429 | You've exceeded your plan's per-minute burst rate or the anonymous daily cap. |
| not_configured | 503 | A required backend credential isn't configured on our side. |
| upstream_unavailable / upstream_timeout | 502 / 504 | The extraction backend didn't respond in time. Safe to retry with backoff. |
| internal | 500 | An unexpected server error. Safe to retry; contact support if it persists. |
error response
{
"error": {
"code": "unprocessable",
"message": "This file doesn't look like a bank or card statement."
},
"request_id": "req_9f3ac1d1"
}Rate limits
By plan
| Tier | Burst | Volume | Batch |
|---|---|---|---|
| Anonymous | 4/min | 20/day | No API access — trial only |
| Free | — | 10/mo (web only) | No API/MCP access |
| Pro | 120/min | 500/mo incl., then $0.1/page | Up to 25 files/call |
| Scale | 600/min | 5,000/mo incl., then $0.05/page | Up to 200 files/call |
Full plan details at /pricing or the machine-readable /api/v1/pricing.
Endpoints
Every route
/api/v1/extract
Auth optionalExtract every transaction from a bank/card statement PDF — balance-checked, with a confidence score.
| Param | In | Required | Description |
|---|---|---|---|
| file | body | no | multipart/form-data field with the PDF (alternative to file_base64/file_url). |
| file_base64 | body | no | Base64-encoded PDF bytes (JSON body). |
| file_name | body | no | Original file name, used with file_base64. |
| file_url | body | no | https:// URL to fetch the PDF from (fetched server-side, SSRF-guarded). |
| format | query | no | excel | csv | json | quickbooks | xero | sage — return a converted file instead of JSON. |
curl -X POST https://ledgerary.com/api/v1/extract \ -H "Authorization: Bearer nmr_live_..." \ -F "file=@statement.pdf"
/api/v1/extractions
Requires paid keyList the caller's own saved extractions, newest first.
curl https://ledgerary.com/api/v1/extractions -H "Authorization: Bearer nmr_live_..."
/api/v1/extractions/{id}
Requires paid keyGet one saved extraction with its full transaction list.
| Param | In | Required | Description |
|---|---|---|---|
| id | path | yes | Extraction id returned by POST /extract. |
curl https://ledgerary.com/api/v1/extractions/EXTRACTION_ID -H "Authorization: Bearer nmr_live_..."
/api/v1/extractions/{id}/export
Requires paid keyDownload a saved extraction converted to Excel, CSV, JSON, QuickBooks, Xero or Sage.
| Param | In | Required | Description |
|---|---|---|---|
| id | path | yes | Extraction id. |
| format | query | yes | excel | csv | json | quickbooks | xero | sage. |
curl -OJ "https://ledgerary.com/api/v1/extractions/EXTRACTION_ID/export?format=excel" -H "Authorization: Bearer nmr_live_..."
/api/v1/pricing
Auth optionalMachine-readable pricing — plans, included pages, per-page overage, rate limits and features.
curl https://ledgerary.com/api/v1/pricing
Ledgerary is a document-conversion tool: it extracts the data already present in the files you upload. It is not accounting, tax, lending or financial advice. Automated extraction can misread low-quality scans — always review the results (Ledgerary flags a balance mismatch and a confidence score on every job) before you rely on them.