parsr.
Financial document API for AI agents

Send a PDF.
Get back structured JSON.

Bank statements, payslips, brokerage reports — drop into LangChain, LlamaIndex, or any MCP-aware agent in three lines. Schema-validated, signed webhooks, multi-region. Self-serve from €29/mo.

200 pages/moFree tier
< 3 secondsMedian parse
every responseSchema validated
day oneMCP / LangChain / LlamaIndex

What you ship

One endpoint. Every layout.

We use Claude with vision + tool-use, so the model emits JSON that's already validated against a strict schema. Then we run a balance-chain check (opening + Σtransactions = closing) to catch sign errors before you ever see them.

  • Bank statements

    GA

    EU IBAN, US ABA, UK sort code. Single page or 30 — same endpoint.

  • Payslips

    Beta

    Gross, net, deductions, employer details. Schema-validated tax buckets.

  • Brokerage statements

    Beta

    Holdings, trades, dividends across multiple custodians.

  • Invoices & receipts

    Soon

    Line items, VAT, supplier metadata. EU + US tax flavors.

POST /v1/parse?wait=60
200 OK · 2.1s
{
  "schema_version": "bank_statement.v1",
  "model": "claude-sonnet-4-6",
  "warnings": [],
  "result": {
    "institution_name": "NORDIC TRUST BANK",
    "account_holder": "Test Customer",
    "account_iban": "BE12345678901234",
    "statement_period_start": "2026-04-01",
    "statement_period_end":   "2026-04-30",
    "currency": "EUR",
    "opening_balance": { "amount": "1000.00", "currency": "EUR" },
    "closing_balance": { "amount": "2159.59", "currency": "EUR" },
    "transactions": [
      {
        "posted_date": "2026-04-03",
        "description": "Salary payment",
        "amount":      { "amount":  "2500.00", "currency": "EUR" },
        "balance_after": { "amount": "3500.00", "currency": "EUR" },
        "type": "credit"
      },
      {
        "posted_date": "2026-04-05",
        "description": "Rent",
        "amount":      { "amount": "-1200.00", "currency": "EUR" },
        "balance_after": { "amount": "2300.00", "currency": "EUR" },
        "type": "debit"
      },
      {
        "posted_date": "2026-04-08",
        "description": "Grocery store",
        "amount":      { "amount":   "-87.50", "currency": "EUR" },
        "balance_after": { "amount": "2212.50", "currency": "EUR" },
        "type": "debit"
      }
    ]
  }
}

Real response from a synthetic statement · 7 transactions · 0 warnings

Why parsr

Four reasons to trust this with production volume

We started parsr because every doc-parsing API for a fintech project either failed compliance, started at $500/mo, or both. The opinion baked into the platform: developer-first, EU-first, no-bullshit.

01 / Sovereignty

Real EU residency, not a region toggle

Compute on Exoscale Zürich (Swiss-based, A1 Group, no US parent). Storage on Cloudflare R2 with jurisdiction='eu'. Postgres + Stripe records on EU instances. DORA, BaFin, and public-sector buyers can tick the box on the first call.

Zero US Cloud Act exposure for EU customers.

02 / Pricing

Built for the indie SaaS, not the procurement team

€19/mo for 1k pages. €99 for 10k. €499 for 100k. Free tier with 100 pages, no credit card to try. Same accuracy as the enterprise vendors charging $500/month entry.

Linear, transparent overage. No quotes.

03 / Accuracy

LLM-backed, schema-validated, balance-checked

Most APIs train per-template and fail on the long tail. We force Claude to emit JSON against a strict Pydantic schema, then run a balance-chain validator (opening + Σtransactions = closing). Most layouts work first try; the rest surface as warnings, not silent corruption.

Schema mismatch → 4xx, never wrong data.

04 / Speed

Sub-3-second median, 60-second sync mode

Async with Idempotency-Key by default. Pass `?wait=60` for synchronous mode if you'd rather block than poll. HMAC-signed webhooks on completion with 6-attempt exponential backoff. Region-bound API keys so EU traffic never crosses the Atlantic.

p50 2.1s · p95 4.8s on bank statements.

Who's using it

Wherever a customer hands you a PDF instead of a CSV

You don't need a vendor evaluation cycle, a security review, or a minimum commitment. Most teams ship a prototype on the free tier in an afternoon.

Lending & underwriting

Verify income from 6 months of statements in seconds.

  • Opening / closing balance per statement
  • Recurring credits flagged as salary signals
  • Categorical spend bucketing for affordability checks
Σ

AI bookkeeping & accounting

Replace your Tesseract+regex pipeline with one HTTPS call.

  • Dates, descriptions, amounts, balance after each line
  • Multi-currency aware (EUR / USD / GBP / CHF native)
  • Webhook on completion so you can stream into your ledger

PFM & wealth tools

Aggregate multi-bank PDFs where Open Banking doesn't reach.

  • Customer uploads PDF; you call /v1/parse
  • 60-second sync mode for instant flows
  • Idempotent retries — never double-bill the user

How it works

Three calls. No surprises.

Spec lives at docs.tryparsr.dev. Postman collection and SDK examples included.

  1. 01

    POST your document

    Send `document_url` or `document_base64`. Add an `Idempotency-Key` header to make retries safe. SSRF-protected: only `https://` URLs to public hosts, no peeking at metadata services.

  2. 02

    We extract + validate

    Worker pulls from NATS JetStream, calls Claude with vision + a JSON schema as a tool, validates the result, computes balance-chain checks, stores in regional R2.

  3. 03

    Poll, sync-wait, or get a webhook

    Three ways: poll `/v1/jobs/{id}`; pass `?wait=60` for synchronous mode; or register an HMAC-signed webhook. Whichever fits your flow.

Drop into any stack

A bearer token and three minutes. That's it.

Same endpoint shape across every SDK we publish. Idempotency-Key on retries, region-bound bearer token, JSON in and out — the way you already write integration code.

POST /v1/parse
curl https://eu-api.tryparsr.dev/v1/parse?wait=60 \
  -H "Authorization: Bearer $PARSR_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "document_url": "https://example.com/statement.pdf",
    "doc_type":     "bank_statement"
  }'
We rebuilt our document onboarding around parsr in two days. Same accuracy as the vendor we were paying $700/month, schema-validated by default.
Solo founder, AI bookkeeping
EU residency was non-negotiable for our DORA filing. parsr was the only API that didn't require six rounds of legal back-and-forth.
Head of Risk, EU credit startup
Idempotency-Key + signed webhooks meant zero retry plumbing on our side. Felt like Stripe-tier developer experience.
CTO, fintech in stealth

Anonymised feedback from design partners during private beta · Public reference logos coming with the launch cohort.

Pricing

Linear pricing. No quotes.

One unit = one parsed page. Cached re-uploads are free. Validation-failed parses don't bill. Sandbox keys are unlimited. Upgrade or downgrade at any time.

MonthlyAnnualSave 17%

Free

€0/mo
0

200 pages/mo + 500 signup-bonus

  • Hard cap, no overage
  • 60 req/min · 1,000 pages/day
  • EU or US (one region)
Start free

Starter

€29/mo

≈ $32 USD

1,000 pages/mo

  • €0.04 per overage page
  • 120 req/min
  • Email support, 48h
Choose Starter
Most popular

Growth

€99/mo

≈ $109 USD

5,000 pages/mo

  • €0.030 per overage page
  • 600 req/min · 5 RPS
  • Email 24h + Slack Connect
  • EU + US keys
Choose Growth

Scale

€399/mo

≈ $439 USD

25,000 pages/mo

  • €0.022 per overage page
  • 3,000 req/min · 30 RPS
  • Priority email 4h + Slack
  • ZDR available
Choose Scale

Enterprise

Custom

100K+ pages, committed

  • Volume-discounted overage
  • Custom DPA, SLA, region
  • Dedicated support, 99.9% SLA
Talk to us

Every plan includes EU sovereignty, region-bound keys, HMAC-signed webhooks, idempotency, and unlimited sandbox-mode keys for development.

Security & compliance

Engineered for the team that has to defend it in a security review

Every line below is a real implementation choice — not aspirational. Full security posture at tryparsr.dev/security.

Data residency
EU traffic stays in the EU. US traffic stays in the US. Region-bound API keys (`sk_eu_…` / `sk_us_…`) refuse cross-region calls at the edge.
Encryption in transit
TLS 1.3 from your client to Cloudflare; Authenticated Origin Pulls between Cloudflare and our boxes. No plaintext anywhere on the wire.
Encryption at rest
Cloudflare R2 server-side encryption (AES-256) on all stored documents. Postgres-at-rest encryption on Neon. Stripe handles cards; we never touch them.
Webhook signing
HMAC-SHA256 over the raw body with a customer-side secret. Replay window 5 min. We publish reference implementations in 4 languages.
Authentication
Argon2id-hashed API keys with a server-side pepper. Bearer-token only — no implicit cookies, no session leakage.
Audit & retention
30-day retention by default; configurable. Deletion-on-request endpoint for GDPR Article 17. DPA available on signup.

Frequently asked

The questions your security team will ask first

Everything below is answered the same way in our public docs and in our DPA. No double-speak between sales and engineering.

Which document types are supported today?

Bank statements (GA), payslips and brokerage statements (Beta). Invoices and receipts are next on the roadmap. The schema for each type lives in the public docs and is versioned (e.g. bank_statement.v1).

Where exactly does my data go?

EU keys (sk_eu_…) hit eu-api.tryparsr.dev, which runs on Exoscale Zürich. Documents land in Cloudflare R2 with jurisdiction='eu'. Postgres + Stripe records are EU-hosted. US keys (sk_us_…) hit us-api.tryparsr.dev on Hetzner Ashburn with R2 location='enam'. The two regions never share data.

What's the latency target?

Median ~2 seconds for a single-page bank statement, p95 ~5 seconds. Multi-page documents scale roughly linearly. You can pass ?wait=60 to block synchronously, or use the default async + webhook pattern.

How do you handle retries and double-billing?

Send an Idempotency-Key header on POST /v1/parse. We dedupe on (org_id, key) for 24 hours. Cache hits don't pay the LLM cost but DO bill against quota — we treat the unit as a 'parse you initiated', not a 'cache miss we paid for'.

How do webhook signatures work?

We POST to your URL with a Parsr-Signature header in the format t=<unix>,v1=<hex>. The HMAC is over `<unix>.<raw_body>` using the secret you receive at registration. 5-minute replay window. Reference implementations in Python, Node, Go, and FastAPI in the docs.

What happens when a parse fails?

Failures with our fault (LLM down, R2 down) don't bill. Customer-fault failures (oversized file, invalid base64) emit a quantity=0 usage event so they show up in your dashboard but don't charge. The job ends in status 'failed' with a structured error_code.

Can I self-host or get a private region?

Self-hosted is roadmap, not today. Private regions are available on enterprise — contact us with your volume estimate and required jurisdiction.

Is there an SLA?

99.5% on Starter and Growth, 99.9% on Scale. Enterprise SLA on request. Public status page at status.tryparsr.dev.

Stop building the same statement parser again.

Sign up, get a region-bound API key, and parse 100 pages on the free tier. No credit card. No sales call. The first parse is usually live inside 60 seconds.