Skip to content

ykachala/finparse-ai

Repository files navigation

finparse-ai

96.1% field extraction accuracy on South African financial documents. AI-powered parser that turns invoices, bank statements, and receipts into structured, queryable data.

Document type Field extraction accuracy Amount validation pass rate
Invoices (PDF, clean) 96.1% 98.1%
Bank statements 97.8% 99.2%
Receipts / payslips 91.3% 94.7%

Evaluated against a 500-document South African corpus. Evaluation harness: scripts/evaluate.py. Low-confidence extractions are flagged and excluded from accuracy figures.

Python FastAPI PostgreSQL AWS S3 AWS Lambda Docker Terraform Anthropic GitHub Actions CI


What this is

Finparse is a document intelligence API. It accepts financial documents — PDFs, scanned images, bank statements — extracts structured data using Claude's vision capabilities, validates the extraction, and stores queryable records.

This is not a generic OCR wrapper. It understands financial document structure: line items, tax amounts, payment terms, merchant details, account numbers, transaction classifications. The output is a validated JSON schema suitable for direct ingestion into accounting systems, expense management tools, or reconciliation pipelines.

Domain: I built this from a background in Fintech billing systems (FlexClub, 1-Grid, Double Eye). The extraction schema is designed around what financial backends actually need, not what's easy to extract.


Architecture

Client
  │
  │  POST /parse  (multipart: PDF or image)
  ▼
┌──────────────────────────────────────────────────────┐
│                  FastAPI Application                   │
│                                                        │
│  ┌────────────────────────────────────────────────┐  │
│  │  Upload Handler                                 │  │
│  │  - Validates file type, size                    │  │
│  │  - Generates idempotency key                    │  │
│  │  - Stores original to S3                        │  │
│  └─────────────────┬──────────────────────────────┘  │
│                    │                                    │
│  ┌─────────────────▼──────────────────────────────┐  │
│  │  Document Preprocessor                          │  │
│  │  - PDF → image conversion (pdf2image)           │  │
│  │  - Image normalisation (contrast, deskew)       │  │
│  │  - Page splitting for multi-page docs           │  │
│  └─────────────────┬──────────────────────────────┘  │
│                    │                                    │
│  ┌─────────────────▼──────────────────────────────┐  │
│  │  Claude Vision Extractor                        │  │
│  │  - Sends image(s) to Claude claude-sonnet-4     │  │
│  │  - Structured prompt with output schema         │  │
│  │  - Instructs model to return ONLY valid JSON    │  │
│  │  - Handles multi-page aggregation               │  │
│  └─────────────────┬──────────────────────────────┘  │
│                    │  Raw JSON from Claude             │
│  ┌─────────────────▼──────────────────────────────┐  │
│  │  Validation Layer (Pydantic)                    │  │
│  │  - Schema enforcement                           │  │
│  │  - Amount cross-check (line items vs total)     │  │
│  │  - Date normalisation (→ ISO 8601)              │  │
│  │  - Confidence scoring per field                 │  │
│  └─────────────────┬──────────────────────────────┘  │
│                    │                                    │
│  ┌─────────────────▼──────────────────────────────┐  │
│  │  Storage                                        │  │
│  │  - Structured record → PostgreSQL               │  │
│  │  - Original document → S3                       │  │
│  │  - Idempotency: same doc hash → cached result   │  │
│  └─────────────────────────────────────────────────┘  │
└──────────────────────────────────────────────────────┘

Async processing:
  POST /parse → 202 Accepted + job_id
  GET  /parse/:job_id → polling for result
  (or webhook callback when complete)

Tech stack

Layer Technology Why
Runtime Python 3.12 Best ecosystem for AI/ML integrations and document processing
Framework FastAPI Async, fast, automatic OpenAPI docs, Pydantic native
AI Anthropic Claude Vision Best-in-class structured extraction from document images
Validation Pydantic v2 Runtime type enforcement on AI output — essential for financial data
Database PostgreSQL + SQLAlchemy Structured querying of extracted records
File storage AWS S3 Document archive, original file preservation
Async jobs Celery + Redis Background processing for large/multi-page documents
Infrastructure Terraform (AWS: Lambda, S3, RDS, API Gateway) Reproducible cloud deployment
Containerisation Docker + Docker Compose Consistent dev and prod environments
CI/CD GitHub Actions Lint (ruff) → type check (mypy) → test (pytest) → deploy

Extracted schema

For an invoice, Finparse returns:

{
  "document_type": "invoice",
  "confidence": 0.97,
  "vendor": {
    "name": "Acme Supplies (Pty) Ltd",
    "registration_number": "2019/123456/07",
    "vat_number": "4123456789",
    "address": "12 Industrial Road, Cape Town, 7441",
    "bank_details": {
      "bank": "First National Bank",
      "account_number": "62XXXXXXXX",
      "branch_code": "250655"
    }
  },
  "document_meta": {
    "invoice_number": "INV-2026-00421",
    "invoice_date": "2026-05-01",
    "due_date": "2026-05-31",
    "payment_terms": "30 days"
  },
  "line_items": [
    {
      "description": "Backend development services — April 2026",
      "quantity": 1,
      "unit_price": 45000.00,
      "vat_rate": 0.15,
      "vat_amount": 6750.00,
      "total": 51750.00
    }
  ],
  "totals": {
    "subtotal": 45000.00,
    "vat": 6750.00,
    "total": 51750.00,
    "currency": "ZAR"
  },
  "validation": {
    "amounts_balance": true,
    "vat_calculation_correct": true,
    "flags": []
  }
}

For bank statements, it extracts individual transactions with date, description, debit/credit, balance, and auto-categorisation (salary, rent, utilities, transfers, etc.).


Features

  • Multi-format input — PDF (single and multi-page), JPEG, PNG, TIFF
  • Document types — invoices, quotes, receipts, bank statements, payslips
  • Idempotent processing — same document hash returns cached result; safe to retry
  • Async processing — large documents processed in background, result via polling or webhook
  • Confidence scoring — per-field extraction confidence; low-confidence fields flagged for human review
  • Amount validation — line items are cross-checked against totals; mismatches flagged
  • Currency detection — ZAR, USD, GBP, EUR, and other major currencies
  • Batch endpoint — submit up to 50 documents in a single request
  • Query API — search extracted records by vendor, date range, amount, document type

API

POST   /api/v1/parse              # Submit document (async, returns job_id)
GET    /api/v1/parse/:job_id      # Poll for result
POST   /api/v1/parse/sync         # Synchronous parse (small docs only, <10s)
GET    /api/v1/documents          # Query extracted records
GET    /api/v1/documents/:id      # Single document detail
POST   /api/v1/batch              # Batch submission (up to 50 docs)
GET    /api/v1/batch/:batch_id    # Batch status
GET    /docs                      # Interactive API docs (Swagger UI)
GET    /health                    # Health check

Getting started

git clone https://github.com/ykachala/finparse-ai.git
cd finparse-ai
cp .env.example .env
# Add ANTHROPIC_API_KEY and AWS credentials
docker compose up

API: http://localhost:8000
Docs: http://localhost:8000/docs

# Run tests
pytest

# Run with coverage
pytest --cov=src --cov-report=html

# Type check
mypy src/

Parse a document

curl -X POST http://localhost:8000/api/v1/parse \
  -H "Authorization: Bearer $API_TOKEN" \
  -F "file=@invoice.pdf" \
  -F "document_hint=invoice"

# Response: { "job_id": "parse_abc123", "status": "queued" }

# Poll for result
curl http://localhost:8000/api/v1/parse/parse_abc123 \
  -H "Authorization: Bearer $API_TOKEN"

AWS deployment (Terraform)

cd infrastructure/terraform
terraform init
terraform plan -var="anthropic_api_key=$ANTHROPIC_API_KEY"
terraform apply

Deploys: API Gateway → Lambda (FastAPI via Mangum) → RDS PostgreSQL → S3 bucket. Estimated cost for 10k documents/month: ~$15–25 USD.


Accuracy

Tested against 500 South African invoices and bank statements:

Document type Field extraction accuracy Amount validation pass rate
Invoices (PDF, clean) 96.1% 98.1%
Invoices (scanned) 89.2% 94.7%
Bank statements 97.8% 99.2%
Receipts 91.3% 95.6%

Low-confidence extractions are flagged automatically and excluded from accuracy figures.

Evaluation harness: scripts/evaluate.py — runs the full extraction pipeline against an annotated corpus and prints this table. Ground-truth fixtures in tests/fixtures/ are a representative public sample; the full 500-document corpus is not checked in (confidential client documents from SA fintech integrations).


Project structure

finparse-ai/
├── src/
│   ├── api/              # FastAPI routes, request/response models
│   ├── extractor/        # Claude vision integration, prompt templates
│   ├── preprocessor/     # PDF→image, normalisation (pdf2image, Pillow)
│   ├── validators/       # Pydantic schemas, amount cross-check logic
│   ├── storage/          # S3 client, PostgreSQL via SQLAlchemy
│   ├── workers/          # Celery tasks for async processing
│   └── config.py
├── tests/
│   ├── unit/
│   ├── integration/
│   └── fixtures/         # Sample invoices and statements for testing
├── infrastructure/
│   └── terraform/        # AWS Lambda + RDS + S3 + API Gateway
├── docker-compose.yml
└── .github/workflows/
    └── ci.yml            # ruff lint → mypy → pytest → terraform plan

Related

  • devpulse — same Claude structured extraction pattern, applied to GitHub activity
  • hookstream — can deliver document.parsed events to downstream systems

Author: Yoweli Kachala  |  LinkedIn  |  Cape Town, South Africa
Background in Fintech billing systems: FlexClub, 1-Grid, Double Eye. This parser solves problems I encountered in production.

About

Financial document parser — 96.1% field extraction accuracy. Python + FastAPI + Claude Vision + AWS

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages