Developers

Bank statement extraction API

Send a bank statement. Receive structured transactions.

POST /v1/statements

{
  "bank": "Example Bank",
  "currency": "USD",
  "statement_period": {
    "from": "2026-01-01",
    "to": "2026-01-31"
  },
  "transactions": [
    {
      "date": "2026-01-02",
      "description": "AMAZON MARKETPLACE",
      "debit": 42.19,
      "credit": null,
      "balance": 4821.43
    }
  ]
}

API documentation

Authentication

Authenticate every request with a bearer API key created in the dashboard. Keys are shown once at creation and stored only as a hash — treat them like passwords and rotate immediately if exposed.

Authorization: Bearer sk_live_...

Upload statement

POST /v1/statements accepts a multipart upload (PDF, JPG or PNG). Small documents return the extraction synchronously; larger documents return 202 Accepted with a statement ID to poll or receive via webhook.

curl -X POST https://api.statementconvert.example.com/v1/statements \
  -H "Authorization: Bearer sk_live_..." \
  -F "file=@statement.pdf"

Retrieve result

GET /v1/statements/:id returns the extraction: detected bank, statement period, page count and the normalized transaction array with per-row confidence.

curl https://api.statementconvert.example.com/v1/statements/stmt_8f2ka1 \
  -H "Authorization: Bearer sk_live_..."

Webhooks

Register a webhook URL to receive statement.completed and statement.failed events instead of polling. Payloads are signed; verify the signature header before trusting the body.

{
  "type": "statement.completed",
  "data": {
    "id": "stmt_8f2ka1",
    "status": "complete",
    "transaction_count": 128,
    "page_count": 6
  }
}

Errors

Errors use conventional HTTP status codes with a machine-readable code and a human next action. Common codes: unsupported_file, file_too_large, password_protected, no_transactions, usage_limit_reached.

{
  "error": {
    "code": "password_protected",
    "message": "The uploaded PDF is password-protected.",
    "next_action": "Remove the password and re-upload the file."
  }
}

Usage limits

API page usage counts toward the same monthly limit as browser uploads — see pricing for volumes per plan. Requests are rate-limited per key; limit state is returned in X-RateLimit-* headers, and exceeding your monthly pages returns 402 with usage_limit_reached.