Start with the Python sandbox quickstart for an upload → status → transactions → CSV walkthrough.

Bank statement API reference

Authenticate with a Bearer API key: `sk_live_…` or `sk_test_…`. Test keys return fixed sandbox responses; live keys process your statements.

Statement statuses: queued, processing, succeeded, needs_review, rejected, failed. A needs_review result requires checking against the PDF; file generation does not prove accuracy.

Use this summary to find endpoints, statuses and parameters. The interactive reference below includes complete request/response schemas, correction operations and code samples; it requires JavaScript. Download the OpenAPI schema.

Upload a statement

POST /v1/statements

Response codes: 202, 401, 402, 408, 409, 413, 422, 429, 503. Request body: multipart/form-data.

  • 202: Queued
  • 401: Missing, invalid or revoked key
  • 402: Not enough credits
  • 408: The upload took too long to arrive
  • 409: Not possible in its current state (`code` says why)
  • 413: The file is larger than 20 MB
  • 422: Invalid request (`code` says which field)
  • 429: Rate limited; see `Retry-After`
  • 503: Temporarily unavailable
  • Idempotency-Key (header, optional) — Retry safely: the same key and request within 24 hours returns the same statement; the same key with a different request is 422 `idempotency_key_reused`

Get a statement

GET /v1/statements/{stm_id}

Response codes: 200, 401, 404, 422, 429.

  • 200: Successful Response
  • 401: Missing, invalid or revoked key
  • 404: No such statement for this key
  • 422: Invalid request (`code` says which field)
  • 429: Rate limited; see `Retry-After`
  • stm_id (path, required)

Delete a statement and its files

DELETE /v1/statements/{stm_id}

Response codes: 204, 401, 404, 429.

  • 204: Successful Response
  • 401: Missing, invalid or revoked key
  • 404: No such statement for this key
  • 429: Rate limited; see `Retry-After`
  • stm_id (path, required)

List its transactions

GET /v1/statements/{stm_id}/transactions

Response codes: 200, 401, 402, 404, 409, 422, 429.

  • 200: Successful Response
  • 401: Missing, invalid or revoked key
  • 402: Not enough credits
  • 404: No such statement for this key
  • 409: Not possible in its current state (`code` says why)
  • 422: Invalid request (`code` says which field)
  • 429: Rate limited; see `Retry-After`
  • stm_id (path, required)

Correct transactions

PATCH /v1/statements/{stm_id}/transactions

Response codes: 200, 401, 402, 404, 409, 422, 429. Request body: application/json.

  • 200: Successful Response
  • 401: Missing, invalid or revoked key
  • 402: Not enough credits
  • 404: No such statement for this key
  • 409: Not possible in its current state (`code` says why)
  • 422: Invalid request (`code` says which field)
  • 429: Rate limited; see `Retry-After`
  • stm_id (path, required)
  • if-match (header, required) — The `corrections_version` your edit is based on (409 `version_conflict` if it moved)

Download an export

GET /v1/statements/{stm_id}/export

Response codes: 200, 401, 402, 404, 409, 422, 429.

  • 200: The file. `X-Document-Status` is the statement's status; for OFX / QBO, `X-QBO-Bank-Verified` says whether the bank id was verified in QuickBooks
  • 401: Missing, invalid or revoked key
  • 402: Not enough credits
  • 404: No such statement for this key
  • 409: `not_ready`; `acct_id_unconfirmed` (OFX / QBO: record the account number first); `needs_review_unconfirmed` (send `confirm_review=true` once checked); or why this format cannot be produced, e.g. `missing_amount` (a row without an amount cannot go to OFX / QBO)
  • 422: Invalid request (`code` says which field)
  • 429: Rate limited; see `Retry-After`
  • stm_id (path, required)
  • format (query, optional) — File type Choices: xlsx, csv, ofx, qbo.
  • layout (query, optional) — xlsx / csv: separate debit and credit columns, or one signed amount Choices: split, signed.
  • acctid (query, optional) — A one-off OFX / QBO account number for this download. Prefer recording it once with `set_meta acct_id` (a query string ends up in logs)
  • confirm_review (query, optional) — OFX / QBO of a `needs_review` statement: true once a person has checked the flagged rows

Retry a failed statement

POST /v1/statements/{stm_id}/retry

Response codes: 202, 401, 402, 404, 409, 422, 429.

  • 202: Successful Response
  • 401: Missing, invalid or revoked key
  • 402: Not enough credits
  • 404: No such statement for this key
  • 409: Not possible in its current state (`code` says why)
  • 422: Invalid request (`code` says which field)
  • 429: Rate limited; see `Retry-After`
  • stm_id (path, required)

Parse again as another account type

POST /v1/statements/{stm_id}/account-type

Response codes: 202, 401, 402, 404, 409, 410, 422, 429, 503. Request body: application/json.

  • 202: Successful Response
  • 401: Missing, invalid or revoked key
  • 402: Not enough credits
  • 404: No such statement for this key
  • 409: Not possible in its current state (`code` says why)
  • 410: The original PDF is no longer kept (`retention=none`, or deleted): it cannot be parsed again
  • 422: Invalid request (`code` says which field)
  • 429: Rate limited; see `Retry-After`
  • 503: Temporarily unavailable
  • stm_id (path, required)

Credits

GET /v1/usage

Response codes: 200, 401, 429.

  • 200: Successful Response
  • 401: Missing, invalid or revoked key
  • 429: Rate limited; see `Retry-After`

Webhooks: statement.completed / statement.failed

Signature header: X-Signature.

Sent when a statement finishes. Answer 2xx within 10 seconds; anything else — another status, a redirect (never followed), a timeout or a network error — is retried after 1m, 5m, 30m, 2h, 6h and 12h. A test event sent from the console is a `statement.completed` with `data.mode` `test`, `data.id` `stm_000…` and `data.metadata.test_event: true`: answer 2xx and do not fetch it (it is no statement).