blog·5 min read

Beyond invoices: what else you can build on an accounting connection

A connection to Exact Online is almost always built for one thing. That is a waste, because the same connection can tie together your stock, your point of sale and a customer order portal. Four building blocks from our own work.

Look in the copy of our accounting data for items with a sales price below
cost price and put them in a list with the difference per unit. Change
nothing.

A connection to an accounting package is almost always built for one task. Reading invoices, or creating items, or pulling revenue for a report. It works, the client is happy, and after that the connection sits there for years doing that one thing.

That is a waste. The work you put into it is not in that one task. It is in the connection itself: the login, refreshing the token, a copy of the data in your own database and dealing with the limits. Once that exists, the second use costs a fraction of the first.

We built such a connection for a client, to read supplier invoices. The client stays anonymous and there are no prices or margins here. What is here are the four things that could be built on top of that same connection afterwards. Two of them run, two are ready. We wrote about the pitfalls of writing earlier in what the docs do not say, and about the read only side in query your accounting from Claude.

1. Stock per warehouse, without blowing your limit

Fetching stock levels sounds like the kind of thing you do every few minutes and that burns through your daily call limit in a day. It does not have to, because there is a separate entrance for it: the sync variant of the stock positions.

The difference is simple but important. A regular list gives you everything, every time. The sync variant gives you only what changed since a timestamp you pass in. In practice that means one call per quarter of an hour, even with thousands of items. You store the last position and pick up from that point next time.

This is the pattern that makes the rest of such a connection sustainable. The limit is sixty calls per minute and five thousand per day, and you read the remaining room from the headers of every response. With full lists that is tight. With changes only it is roomy.

2. The point of sale that updates the warehouse

A shop with its own till and its own warehouse has a problem nobody enjoys solving by hand: what goes over the counter has to come off the warehouse stock.

The till produces a weekly export. That export is not in accounting language, so there is a translation step in between: per item the quantity, and then one stock transfer in the accounting package. One file in, one entry out.

What makes this one instructive is the failure side. An item in the till export that does not exist in the accounting package must not make the whole entry fail. We put those lines in a separate list for someone to review. A connection that stops at the first unknown item code is abandoned within two weeks.

3. An order portal that does not invent the price

Business customers who want to order without calling are the clearest reason to extend a connection. Your own order portal sends a sales order to the accounting package, and there something nice happens: the accounting package calculates the customer price itself.

That is worth more than it looks. Customer prices live in price lists with volume tiers, and every customer hangs off their own list. You do not want to retype that logic in your portal, because then you have two truths and one of them falls behind. Let the accounting package do the maths and show in the portal what comes out.

To show a price before ordering you use the price lists from your own copy. That is the part you fetch once during the first synchronisation and then only update where something changed.

4. An alert on prices below cost

The smallest of the four and perhaps the most useful. You have the sales prices in your copy, and you have the average cost price per item. The difference is a number nobody ever looks at.

Put a weekly check on it and you see which items go out below cost. Those are almost never mistakes made today. They are prices that were right three years ago.

One warning from experience: the average cost price in an accounting package is a calculated number with assumptions baked in. Items delivered for free, for instance, skew it. Use such a list as a question for a human, not as a conclusion.

What this says about how you build it

All four use the same three layers: a copy of the data in your own database, a synchronisation that only fetches changes, and a thin layer with the logic per use. Only that last layer is new per use.

And all four were built with the assistant alongside, with one hard rule: the connection that writes to the accounting package only runs in production. The development environment works on a copy with no connection. A test guards that nothing can be written to the accounting package from a place where that is not allowed. That is what makes building on an accounting package with an assistant workable: not slower, but with a brake it cannot release itself.

Common mistakes

Fetching everything live from the accounting package. It feels tidy to always query the source, but you hit the limits within a day and your application gets slow. Work with a copy and synchronise only changes.

Copying the pricing logic into your own application. Volume tiers and customer prices are exactly the kind of rules that change elsewhere without anyone telling you. Let the accounting package do the maths.

Building a connection that stops at the first error. Unknown item codes, rounded quantities and odd units are not exceptions, they are the normal state. Set them aside and carry on.

Granting write access because it is easier. A connection that only reads cannot break anything. Split reading and writing, give the writing as few rights as it needs and let a test guard that the line holds.

Thinking this is one off work. A connection is a service. An expired token, a changed field or a new administration takes it down. Put a check on it that warns you before your client does.

MK
Maarten Keizer

Founder of Invoker. Over twenty years in hosting, system administration and web development; builds the Claude hosting himself and tests everything on our own servers first.

about maarten