AI & Automation

How Three AI Agents Closed Our Quarter in Billit: API, Mailbox and Bank Matching

The technical side of our Q3 close: how our agents connect to the Billit API, which operations run in Billit, which run in the mailbox, and how every invoice reaches the accounting system.

R
Roy Perel
Perel Web Studio Team
How Three AI Agents Closed Our Quarter in Billit: API, Mailbox and Bank Matching

The quarter nobody wants to close

Every quarter, the same email arrives from the accountant: send us your documents.

For us, the hard part is never the sales side. Our own invoices already live in Billit. The hard part is purchases. Dozens of software subscriptions, card payments in dollars, cloud bills split across several accounts, freelancers paid by transfer. Each bank debit needs its invoice, and the invoice is never where you expect it.

At the start of this close, Billit showed 159 debits for Q3, and 141 of them had no invoice attached.

This quarter we handed the work to three AI agents working together in Buzz, our team chat: Opus, Claude and Codex. The film above shows the story. This post shows the plumbing.

1. How we connect to Billit

Billit has a REST API at api.billit.be. Billit allows personal API keys for integrations that automate your own administration, which is exactly this case.

Every call carries two headers:

ApiKey: <your API key>
PartyID: <your company's party id>

The key comes from your Billit profile (My profile, API section). It never sits in a file: on our side it lives in the macOS keychain and is read at runtime, so no agent ever prints it in a chat or a log.

Lists use OData filters and come back in pages of 120:

GET /v1/orders?$filter=OrderDirection eq 'Cost' and OrderType eq 'Invoice'
GET /v1/financialTransactions?$filter=ValueDate ge DateTime'2026-07-01'

Two reading traps cost us time, so here they are:

  • Bank amounts are always positive. The direction is in TransactionType (Debet or Credit). A line with an empty AssignedEntities has no invoice linked: that is how we counted the 141.
  • Peppol e-invoices can show a payable amount of zero. Bank fee invoices are marked as prepaid by direct debit, so PayableAmount is 0,00. The real total is TaxInclusiveAmount. Read the wrong field and a whole category of costs disappears.

2. What we do in Billit

The first job is a single table: every Q3 bank debit with no invoice, with its date, amount, counterparty and the full bank note. Opus built it from the API and split it into lanes: the mailbox (68 lines) and supplier portals (27 lines). The remaining 46 debits have no invoice by nature (VAT payments, internal transfers, bank fees, card verification micro debits) and only need to be recognised as such.

Creating purchase invoices. Once a PDF is found and checked, we create the purchase invoice directly through the API, with the PDF attached:

POST /v1/orders
{
  "OrderType": "Invoice",
  "OrderDirection": "Cost",
  "OrderNumber": "<number printed on the PDF>",
  "OrderDate": "...", "ExpiryDate": "...",
  "Currency": "USD",
  "FXRateToForeign": 1.13688,
  "Supplier": { "PartyID": "<supplier party>" },
  "OrderLines": [ ... ],
  "OrderPDF": { "FileName": "...", "MimeType": "application/pdf", "FileContent": "<base64>" }
}

A few rules we learned on the way:

  • Amounts come from the PDF, never from the bank line. A 7 € email marketing invoice can be paid through a 10 € PayPal top up.
  • Dollar invoices carry the real exchange rate. We take it from the bank note itself (“x USD at 1,13688”), so the euro value in the books matches the euro that left the account.
  • VAT inclusive receipts are booked as VAT inclusive. One line with the total marked as VAT included gives 24,79 + 5,20 = 29,99 exactly, with no one cent correction line.
  • The ventilation code is copied from the supplier’s previous invoice, so the accountant sees the same classification as last quarter.

In this quarter, 69 purchase invoices were created this way, with 0 amount mismatches on the second check.

Reading the intake queue. Billit also has a queue of documents waiting for OCR (/v1/toProcess). The list only returns file ids, so we download each file (/v1/files/{id}) and read it: PDFs as text, Peppol documents as UBL XML. That is how we found the queue repeated the same files (68 entries, 60 unique) and that an OCR re-import had created a duplicate invoice with no number. We deleted the duplicate after saving a backup.

What the API cannot do. There is no endpoint that links a bank line to an invoice. The API can read a link, not create one. Billit does auto-match on its own within a few hours (31 of 68 euro invoices by the next morning), but it gets recurring same-amount payments wrong: it can attach the July invoice to the August debit. So every link, automatic or manual, is read back and checked on date as well as amount.

3. What we do in the mailbox

The mailbox work starts from the list, not from the inbox. Before anyone opened Gmail, we had the 68 bank lines marked for the mailbox. We searched for those 68 and nothing else.

Search through the API, never the screen. We query Gmail through its API, one search per bank line: the supplier’s sender address, a date window around the debit, and an attachment filter. We keep a map of about 30 recurring suppliers, saying which send a PDF (Anthropic, Google Workspace and Cloud, Cloudflare, GitHub, HeyGen, Calendly, GTranslate, Infomaniak and anything billed through Stripe) and which never do (OpenAI, Notion, Google Ads, ElevenLabs, CapCut, AWS). Lines from the second group go straight to the browser lane.

Some invoices are not attachments. Infomaniak puts a direct PDF link in the email body, and some Stripe receipts only link to a hosted page. We follow the link and save the PDF. When an email shows the amount but no invoice at all, we print the email to PDF and flag it as a receipt, so the accountant knows it is not a real invoice. Ten documents got that flag.

Every PDF is checked against its bank line. We read the amount inside the PDF and compare it to the debit, to the cent. For foreign currency card payments, we compare against the original USD amount written in the bank note, not the converted euro amount. Freelancer payments go through Wise, so we match each transfer to the freelancer invoice with the same USD total.

The result, seven minutes later: 48 of 68 found and verified, 7 with no invoice by mail (a lease, a social security portal, PayPal payments), and 13 with no billing email at all, handed to the portal lane. Each file is saved as date_supplier_amount.pdf and its row is updated in the shared table. Nothing goes to Billit from the mailbox: the files go to the agent that creates the invoices through the API.

4. From supplier portals to the right bank line

Not every supplier sends a usable invoice by email. For the remaining gaps, our browser agent worked in our own signed in browser session and downloaded documents from Google Ads, AWS, Orange Business, Doccle for social security, Trustindex, Higgsfield and the right Notion workspace. Each PDF was checked against the company details, invoice period, original currency and the matching bank debit. The process also surfaced exceptions: CapCut showed no invoice history, AWS required MFA, and the paid Notion plan belonged to a second workspace with the same name.

Since the API cannot create a bank link, the pairing happened in Billit’s Bank screen. A prepared table mapped every invoice to its exact bank line, so the work was selecting and verifying, not searching and retyping.

We started with three simple euro payments. After each link, a second agent read the result back through the API. For dollar invoices, Billit can cap the allocation at the euro value of the debit, leaving a small balance open (0,64 USD short in one case). We detached the capped allocation, relinked the full dollar amount at the exact bank rate, restored the invoice’s original rate, and checked again.

5. How emails and PDFs reach the accounting system

There are three doors into Billit, and we use each for a reason.

  1. Peppol e-invoices arrive by themselves. Suppliers on the Peppol network (bank fees, the accountant, several Belgian suppliers) land directly in Billit. We only read them, to avoid creating them twice.
  2. Billit’s dedicated intake mailbox. Every Billit account has its own email address. Any PDF forwarded there goes into the OCR queue, where it waits for review. This is our everyday route: invoices that arrive by email during the quarter are forwarded there in batches. It is simple, but the OCR result still needs a human check, and a document forwarded twice becomes two documents.
  3. Direct creation through the API. For a catch up like this one, we skip the queue. The agent already knows the supplier, number, date, currency, rate and amount from the PDF it just verified, so it creates the finished invoice with the PDF attached. No OCR guesswork, no review step, and the agent checks for an existing invoice with the same number first.

The rule we follow: one document, one door. Before creating anything, the agent checks the Peppol inbox, the OCR queue and the existing invoices for the same supplier and number. That rule is why we found duplicates instead of creating new ones.

6. No agent trusts another agent’s work

The part that made this safe is not speed. It is the cross checking.

  • Claude found the mailbox PDFs. Opus created the 69 invoices. Then Claude reopened every created invoice and compared it to its PDF: supplier, currency, amount. Result: no wrong supplier, currency or amount.
  • Codex did the bank pairing in the browser. After each batch, Opus read the links back through the API. On one batch the answer was “7 of 8 are correct, 1 is not”: the dollar invoice allocated 0,64 USD short. Codex fixed it, and it was checked again.
  • Each piece of work is claimed in the thread before anyone starts, so two agents never create the same invoice.
  • Nothing left the building without approval. The email to the accountant was prepared as a draft. A human pressed Send.

At the end of the close, every Q3 debit was either linked to its invoice or had no invoice by nature (VAT payments, internal transfers, bank fees), and the accountant received one email with everything in it.

What it changes

Last quarter, closing the books took me around ten hours of digging through inboxes and portals. This quarter, my own time was about one hour: the kickoff message, a few answers, a “go”, and the Send button. Next quarter, with the queries, the supplier map and the checks already in place, we expect twenty minutes.

The agents did not replace the accountant, and they did not replace judgment. They replaced the searching, the retyping and the second guessing, and they made every step checkable.

If your bookkeeping runs on Billit, or any tool with a decent API, this kind of close is possible today. Talk to us about automating your own administration.

#AI Agents #Billit #Accounting Automation #API #Automation

Ready to Transform Your Online Presence?

Let's discuss how we can help your business grow with a high-performing website

Roy Perelgut

Founder & Digital Strategist

With 22 years of IT experience, Roy founded Perel Web Studio with one core belief: passion is what separates a good web agency from a bad one.

Passionate about creating digital solutions that drive real results, he leads a team of 6 from Brussels, collaborating with talented developers in Sri Lanka, delivering projects that achieve #1 Google rankings and multiply leads.

His approach combines technical excellence, sharp SEO strategy, and an uncompromising commitment to every client's success.

Connect on LinkedIn

Client Testimonials

What our clients say about us

Gilles Van Doorne
Stéphane Pujol
Caroline Pujol
Tom Sellekaerts
Emanuel Cristea
Gregory Marlier
Raphael Galant
Iron Jordan
Maître Géraldine Balthazar
Lionel Majorovic
Stéphane Roche
Alexandre Gelfged
Michael Schipper
Pierre Gerondal

Gilles Van Doorne

Owner of Hercules Merchandise

Perelweb delivers on their promises, but more importantly, they think with you and are genuinely involved in your business. By staying up to date with the latest in technology and AI, they help us keep improving.