Case study

Freelancing.ba logoAccounting on autopilot for freelancers and sole proprietors in BiH

The bank statement engine behind Freelancing.ba

Freelancing.ba runs the whole accounting cycle for independent workers in Bosnia and Herzegovina. We built the piece that closes the loop: a bank statement goes in as a PDF, and expenses, invoice payments and tax obligations come out already reconciled.

Client
Freelancing.ba
Industry
Accounting software for freelancers
Scope
AI document engine and matching rules
Stack
Supabase, n8n, Claude Opus 5
Guardrails
The model reads, the rules decide

The challenge

The last mile of accounting is the bank statement

An independent worker in Bosnia and Herzegovina runs a full accounting cycle by hand every month, across three tax jurisdictions with different rates, forms and deadlines. Issue the invoices, chase the payments, record the expenses, keep the book of income, compute contributions and income tax, produce the government forms and the payment slips, file, pay. Freelancing.ba already automated most of that.

What was left was the reconciliation. Until the bank tells you what actually moved, nothing is settled: an invoice is only paid when the money lands, an expense is only real when it leaves the account, and a contribution payment only counts against the month it was owed for. That evidence arrives as a PDF, formatted differently by every bank, and it is the one place where automation is genuinely dangerous. Book a payment twice and the expenses are inflated. Attribute a contribution to the wrong month and the whole year's attribution collapses quietly, while the totals still add up.

What we did

The model reads the document, the rules decide what it means

We split the problem in two and kept the halves strictly apart. Claude Opus 5 reads the statement PDF directly as a document, with no OCR step, no text-extraction library and no template per bank, and returns a strict JSON schema: statement header, then one row per line with direction, amount, reference, counterparty and payment purpose copied verbatim. The prompt's standing instruction is that if something is not on the statement, the answer is null. Never guess. The same pipeline powers receipt scanning, where a photo or a PDF becomes a pre-filled expense with a suggested category.

Everything after that is deterministic. The model's answer is normalised, the totals are recomputed from the parsed lines rather than trusted, and every consequence is decided by explicit SQL with stated thresholds, running in a Postgres trigger so that an upload, a mailbox import and a manual insert all behave identically. An invoice settles only when the number appears verbatim, the amount matches to the last fening and exactly one candidate exists. A tax payment is bound to the obligation month printed on the statement, never to whichever obligation happens to carry the same amount. Anything less than certain is parked in a review queue for a person, which is what the team asked for: they see only the exceptions.

Deliverables

What we built

Six pieces that turn a bank PDF into reconciled books.

  1. 01

    Statement intake, two ways

    Upload a PDF, or connect a mailbox and let a whitelist of senders and labels pull statements in on a schedule. Both paths land in the same private, audited store.

  2. 02

    Direct PDF extraction

    Claude reads the statement itself and fills a strict schema, so a new bank needs no template, no parser and no configuration.

  3. 03

    Receipt scanning

    A photo or PDF of a receipt becomes a pre-filled expense with amount, date, tax and a suggested category, resolved against the user's own category list.

  4. 04

    Booking in the database, not the app

    One trigger books every line, so upload, inbox import and manual entry can never drift apart in behaviour.

  5. 05

    Invoice settlement that learns

    Payments settle invoices on an exact number and an exact amount. When a client never writes the number, one manual link teaches the engine that payer's name and account for next month.

  6. 06

    Tax and contribution matching

    Public-revenue payments are read for the revenue code and the period the bank prints, and joined to the exact obligation they pay, not to a matching amount.

The engine

What keeps an AI engine safe around money

Reading a PDF is the easy half. The hard half is deciding what to do with it, and knowing when to do nothing.

  • The model extracts, rules decide

    No model output ever changes a financial record on its own. Every consequence is a deterministic rule with a threshold you can read.

  • Certainty or nothing

    Every matcher returns exactly one answer or none at all. Two plausible candidates is not a tie to be broken, it is a question for a person.

  • Never guess, learn instead

    There is no fuzzy name matching anywhere. The engine only gets better by recording what someone did by hand, and it forgets that the moment they undo it.

  • Never destroy, always park

    A suspected double booking is flagged and queued with a "book it anyway" button. A false positive costs one click; a silent duplicate corrupts the books.

Results

What changed for the team

Freelancing.ba hasn't published figures from this work, and we don't invent them. What we can describe is what the engine now does on its own, and where it deliberately stops.

What changed

  • A statement from any bank is read end to end, every line including fees and interest, with no template to write first.
  • Expenses, invoice payments and tax obligations are reconciled from the statement without anyone retyping a row.
  • Contribution payments land on the month they actually pay for, taken from the period the bank prints rather than from a matching amount.
  • The same payment entered by hand and later imported from the bank is caught even months apart, and parked for review instead of booked twice.
  • The team sees only the exceptions: everything certain is booked, everything else waits for a person.
  • Live in production, with the matching rules the app is accountable for kept out of reach of the browser.
“We build accounting software for solo entrepreneurs, where every error costs a client. Agenthos automated document processing so our team only ever sees the exceptions.”
Milica KaurinCEO, Freelancing.ba

Reach us

How about a free audit?

Tell us a little about your business and where time gets lost. We'll come back with what's worth automating first.

* Required. No spam, ever. By submitting you agree to our Privacy Policy.

What to expect

  • Confirmation email

    01

    You'll receive an immediate confirmation with next steps.

  • Response within 24 hours

    02

    A team member will reach out within one business day.

  • Discovery call

    03

    30-minute conversation about your goals and challenges.

  • No obligation

    04

    Exploratory conversations carry no commitment.