Inspiration

Personal pain as entrepreneurs! The overhead of receipts management, digging through a pile of paper slips, manually keying amounts into a excel, chasing down what that €47.80 at "Jumbo" actually was three weeks later. bunq already lives in our pocket as our business bank; we wanted the receipts to live there too.

What it does

BunqBooks is an AI-powered receipt accounting companion that closes the gap between your transactions /expenses and your accountant.

  • Snap & extract: upload any receipt image (JPEG, PNG, WebP) and Claude's vision AI pulls out the merchant, total, VAT, line items, payment method, category, and a confidence score for each field
  • Match to transactions: extracted receipts are linked to your bunq transaction history, so every debit has a paper trail.
  • Correct & confirm: if the AI misread something you can patch any field via a simple API call; the corrected data is maintained by keeping a human in the loop.
  • Multiple points of entry: Receipt uploads happen from many places, including: payment notifications prompting immediate photos, direct receipt uploads from your transactions while browsing in the app, and even bulk uploads.

How we built it

| Layer | Choices | | AI | Anthropic Claude (claude-sonnet-4-6) via the Python SDK — vision endpoint for image-to-structured-JSON extraction | | Backend | FastAPI + async SQLAlchemy 2 on PostgreSQL 16; Alembic for schema migrations | | Storage | Local filesystem (UUID-named files); intending to swap in S3 when deploying to production | | Infra | Docker Compose for local dev; in the future we'd look at ECS Fargate task definitions or serverless architecture |

We wrote a structured prompt that forces Claude to return a strict JSON schema with per-field confidence scores, then wrapped it in a fallback parser that handles both raw JSON and markdown-fenced responses. The async-first FastAPI stack means file I/O and Claude calls never block the event loop.

Challenges we ran into

  • Claude Coding with Multi-shot AI prompt: We bit off more than we could chew at the start, with a larger than achievable scope, we used much of our hackathon disecting the AI generated code. After a few hours of this we decided to return back to basics, mock out endpoints, and build something that we could iterate on.
  • Prompt engineering for receipts: receipts are notoriously inconsistent: thermal-faded text, rotated images, hand-written totals, Dutch vs. English field labels. Getting Claude to return a stable, machine-readable schema. To make it happen took many iterations. We implemented also an explicit confidence scoring to give us another avenue for human interception.
  • Async database sessions in FastAPI: wiring up SQLAlchemy's async session lifecycle correctly with FastAPI's dependency injection (no leaked connections, no sync blocking) required careful attention.
  • Stateful mock data: building a realistic development environment with seeded bunq-style transactions (Dutch merchants, realistic amounts) so we could demo end-to-end without live banking credentials.

Accomplishments that we're proud of

  • Front and Backend in < 24h: upload a receipt image, get back a structured, database-persisted extraction with VAT and line items, matched to a bunq transaction (mocked).
  • Production-grade foundation: async everywhere, health/readiness probes, Alembic migrations, RFC 7807 error format, multi-stage Docker build. -Honour of Diversity: This team, consists of 4 people from 4 different countries, 2 generations and 2 genders. One of us (Kiwi) came for this event from New Zealand.
  • Powered through!!

What we've learnt

  • Claude's vision capability handles messy, real-world receipt images far better than we expected; including partially occluded text and non-standard layouts.
  • Confidence scoring per field is the right abstraction: rather than a binary pass/fail, it lets the UI highlight uncertain fields for human review instead of silently surfacing wrong data. Though this could be biased or the model could lie to us.
  • How to prioritise simplicity over complexity. Finding the tradeoffs between different solutions thinking about the leftover time we had.
  • To not let AI lead the way too much, or it generates too much bloated code.

What's next for BunqBooks

  • Bunq OAuth + live transaction sync: pull transactions directly from the bunq API and auto-match them to uploaded receipts by amount and date.
  • Frontend: a clean mobile-first UI (the backend is fully CORS-ready for a Vite/React app) where you photograph a receipt and watch it parse in real time.
  • Backend: cleanup the database interaction and deploy it to AWS on Lambda and Amazon RDS. Using CI/CD workflows.
  • Batch & email ingestion: forward receipts from your inbox; BunqBooks processes them overnight.
  • VAT report export: one-click CSV/PDF for your accountant with all BTW broken out by category and period.
  • Dashboarding and categorization: Having dashboards or analytics over the metadata generated by our receipt code long term.
  • Bank-side or Accountant software integration: surface matched receipts directly in the bunq app as transaction attachments, closing the loop entirely inside the banking experience. With the intent to integrate with Accounting software in the future.

Built With

Share this project:

Updates