What Breaks First When You Connect a Manual Business Workflow to an API
The decisions people make while copying data are part of the workflow. Find them before the API call replaces them.
2026-09-28 · By Boštjan Korošak, BKIT
Consider a small company where approved orders are copied from a spreadsheet into an accounting system every afternoon.
The request sounds simple: when an order is approved, create it through the API. Remove the copying and save some time.
Then someone asks what happens if the order changes after approval.
“We usually catch it before entering it.”
There is the first missing requirement. The afternoon delay gave someone time to spot a correction. An immediate API call removes that time.
This is an illustrative example. My work covers ERP-style internal systems, web platforms and third-party integrations, and it raises a question I would bring to any such project: what decisions are people making around the data transfer?
An API can accept a perfectly valid request for an action the business did not intend to take. Understanding the surrounding workflow helps prevent that.
Start with the last order that went wrong
Ask someone to describe a process and they will probably describe the normal version. An order arrives, a manager approves it, someone enters it into another system.
I would also ask them to open the last order that caused trouble.
Follow it through the spreadsheet, approval emails and destination system. Find the point where somebody paused, corrected a value or asked a colleague what to do. Those actions belong in the workflow even if nobody has documented them.
Perhaps the person copying orders recognises that “Acme” and “Acme Ltd” are the same customer. An empty delivery date might mean they should call sales. A note saying “same as last time” may be enough for a colleague who remembers the previous order.
Duplicated data entry can contain useful judgement. Before removing it, separate the copying from the decisions made while copying. For each decision, establish what information the person used and whether software will have access to it.
Define what approval actually approves
An API reference can tell you that a status field accepts approved. It cannot tell you whether your manager approved the price, quantity or payment terms, or
which later changes require another review.
Suppose a manager approves 10 units. Someone changes the quantity to 100, but the record still
says approved. A worker reading the latest values could send 100 units under an approval given for 10.
Tie approval to a specific revision. Store the approved values, or track a revision number and require new approval when relevant fields change. The team must decide which fields matter; correcting an internal note may need no review.
Keep approval separate from delivery, too. An approved order can still be waiting for the destination system to recover. A small operation record could look like this:
operation_id: op_7f31
local_order_id: 1842
approved_revision: 3
delivery_state: queued
remote_order_id: not_yet_known This separates the business decision from the work still needed to carry it out. Each state should have a clear meaning and an owner authorised to change it.
Decide where each value belongs
The “source of truth” does not have to be one system for the whole record. Sales might own the delivery address while accounting owns the invoice number and payment status.
But “keep everything in sync” leaves an awkward question unanswered: what happens when someone edits the same field in both places?
Imagine a colleague corrects an address in the destination system. The next sync sends the old address from sales and silently overwrites the correction. Choosing the most recently updated record would not necessarily help: a later edit to an unrelated note says nothing about which address is correct.
Agree where each shared value should be edited and how changes made elsewhere will be handled. Depending on the workflow, make the destination field read-only, send corrections back, or flag conflicts for review. Store stable local and remote IDs so that changing a customer’s name does not break the connection.
Also establish when editing stops being enough. Once an order has triggered fulfilment, changing its local status cannot undo the physical work. The business needs an amendment or cancellation process at that point.
An unanswered request has an unknown outcome
Suppose the integration sends an order, but the connection times out before a response arrives. The destination may already have created it. Sending it again without protection could create a duplicate.
Idempotency addresses this problem. Where an API supports it, an idempotency key lets the destination recognise a repeated operation and avoid performing it twice. Keep the same key for retries of that operation; a fresh key on every attempt defeats the protection. Check the provider’s rules, including how long keys remain valid. Stripe’s idempotency documentation provides a concrete example.[1]
If the API offers no such guarantee, find out whether it supports a unique external reference and a reliable lookup. A local operation record alone cannot stop the remote system from creating duplicates. Uncertain results may need investigation before anything is resent.
Treat other failures according to their cause. A missing customer reference needs a correction. A temporary outage may justify another attempt. Limit automatic retries, increase the delay between attempts, and add some random variation so waiting jobs do not all retry together.[2]
Before a delayed retry, check whether the action is still wanted. An order cancelled while waiting must not be sent just because the service has recovered. If the earlier attempt may already have succeeded, establish its outcome before deciding how to cancel it.
Log enough to trace one operation across both systems: record IDs, attempt times, results and useful error details. Keep credentials and unnecessary customer data out of those logs.
Give people a way to resolve exceptions
A message saying customer_id invalid leaves the person handling orders with little to act on. For a confirmed rejection, a more useful
message would be:
Order 1842 was not sent because this customer has no accounting record linked. Choose an existing accounting customer or ask an authorised colleague to create one, then retry.
The screen should show what happened, what remains uncertain and which actions are safe. An unresolved timeout should not offer an ordinary “send again” button. Keep the history of corrections and attempts visible so the next person does not have to guess what has already been tried.
Assign somebody to review unresolved items. Showing how long the oldest item has been waiting makes neglected work visible. Without an owner, the exception queue can become another forgotten spreadsheet.
Some exceptions should stay manual. An unusual order may require commercial judgement that is difficult to express as a rule. Detecting it and giving the right person the relevant information can be a useful result in itself.
Before launch, ask the eventual operator to resolve a failed item without developer help. That exercise will reveal whether the recovery process is usable.
A checklist before writing the integration
These are the questions I would take into a workflow review:
- • Can we trace a recent ordinary case and a recent exception from start to finish?
- • What does the person copying data check or correct, and does the current delay serve a purpose?
- • What exactly is approved, and which edits require approval again?
- • Which system owns each shared value, and which IDs connect the records?
- • How will we establish the outcome after a timeout and prevent duplicate actions?
- • What happens if an order changes or is cancelled while delivery is pending?
- • Who owns unresolved items, and can they handle ordinary failures without a developer?
Before connecting the order spreadsheet to an API, ask the person who enters the orders what would make them stop. Their answer may change the integration more than anything in the endpoint documentation.
Guest post by
Boštjan Korošak
Founder, BKIT
Boštjan Korošak is the founder of BKIT, a product and technology partner in Ljubljana, Slovenia, and works on ERP-style internal systems, web platforms and third-party integrations.
Let's Build Together
Your vision,
our expertise.
From AI integration to full-stack development, we turn ambitious ideas into products that perform.