Articles
Two ways to connect two systems, and how to choose
A live call and a nightly file fail differently, and the difference decides who is awake at 2am. What each buys, costs, and three checks to keep.
- integration
- data
- operations
A live call buys you an answer now and a dependency forever; a scheduled file buys you a copy you can prove and a day of staleness. Neither is better in general, and the argument between them is usually settled by fashion rather than by the work. The choice comes down to one question: when this breaks at 2am, does someone need to know within a second, or within a day?
What does an API actually buy you?
Immediacy, and a refusal you can act on. The stock level is right at the moment of the sale rather than at midnight, and when the other system says no it says so while the customer is still standing there, with a reason attached. That is worth real money at a counter and worth almost nothing in a monthly report.
The cost is that you inherit their operability. Their uptime becomes your uptime; when their status page turns yellow, your screen turns yellow and you can do nothing about it. You also inherit their rate limits, their versioning and their idea of an error. A timeout is not a refusal, and treating the two as the same thing is how one sale gets recorded twice.
What does a scheduled file buy you?
A copy you can prove, and a re-run you can repeat. The file sits on disk. You can open it, count its rows, sum its amounts, keep it for an auditor, and diff it against yesterday's. When an import fails you fix the parser and run the same bytes again, so the result is deterministic and the incident has a timeline.
The cost is latency and silent staleness. A file that stopped arriving is indistinguishable from a quiet night, and nobody investigates a quiet night. The other cost is that the file is a photograph of a moment that has already passed: a price corrected at nine in the morning reaches the other system tomorrow.
A file also has a shape you can check before it touches the ledger. Published document standards, such as UBL for orders and invoices, name each field, so a validator can refuse an incomplete document before an import has to guess.
So which one fits?
| When this happens | Live call | Nightly file |
|---|---|---|
| Their system is down | The sale is blocked now | Nothing until the next run |
| A bad record arrives | Rejected while the customer waits | Found the next morning |
| Someone asks for proof | Logs, if you kept them | The file itself |
| They change a field | Breaks without warning | Breaks at the next run |
Why do most integrations settle into a hybrid?
Because the two mechanisms answer different questions, and pretending one of them answers both is where the trouble starts. Live for the movement that cannot wait: a payment, a stock reservation at the counter, a price check before a quote. File for the bulk that must be reconcilable: the day's orders, the ledger entries, the customer list.
What makes the hybrid work is one rule: one direction per fact, and the live call is never the only record. If a sale exists only because a call succeeded, then a timeout means the sale does not exist. Write the fact locally with its own number first, then deliver it, then mark it delivered. The local record is the truth; the call is transport.
What are the three checks every transfer needs?
A count, a total, and a replay. Each catches a different failure, and two of the three are usually missing.
- A count. N records sent, N received, per file, per day. Not a dashboard with a line on it — a check that fails and opens an incident when the difference is not zero.
- A total. One amount that must match: invoice totals, quantity moved, whatever the batch is about. A count passes while the rows inside it are wrong; a total catches the row that arrived with the wrong sign or the truncated decimals.
- A replay. Yesterday's input can be processed again and produce the same result, because the receiver refuses a duplicate by its identifier. Without replay you cannot recover from a bad run; you can only apologise for it.
In what order do you choose?
- Write down every fact that crosses the boundary: customer, price, quantity, order, invoice, balance.
- For each, ask how late it may be. Minutes point to a live call, a day points to a file. That is the whole decision, and it is cheap.
- Ask who is awake at 2am when the transfer stops, and name that person before any code.
- Read the far side's contract: does it publish a documented interface, and what does that document say about errors, limits and versions? Read it before the demo, not after the pilot.
- Design the local record first: write the fact in your own system with its own number, then deliver it.
- Add the three checks before the first real file, not after the first incident.
- Keep the file even after moving to live calls. It is the only evidence of what actually happened.
Where this goes wrong
- The API is chosen because it sounds current. Then every counter sale waits on a third party's afternoon.
- Rate limits are discovered in production. A loop that works on a hundred test rows and dies on four thousand, at the busiest hour.
- The file format is agreed in a screenshot rather than a schema, and each side reads the date column differently.
- Staleness with no clock. The import does not record the source timestamp, so "last night" could mean any night.
- Partial failure exits zero. Nine hundred of a thousand rows imported, the job reports success, and the missing hundred are found by a customer.
- Two-way sync over a nightly file. A day of conflicting edits, resolved by whoever happens to run next.
What this does not cover
It does not compare vendors, recommend a platform or quote prices, and it assumes you can change at least one side. When neither side can be changed, the answer is a file plus a person, and the honest description of that is a workaround with a known cost. It also does not settle the harder question underneath: an interface's documented behaviour is not its observed behaviour. The limits in a specification are a claim, and the only number that matters is the one you measured during the pilot.
We build the connection between systems you already run: a live call only where someone is waiting, a file for everything that has to be proven, and three checks that fail loudly when the two sides disagree.
Services in this article
Articles
Related articles.
Two systems, one customer: who owns the record
When two systems both accept edits to the same customer, both look right and neither is. How to assign an owner per record, and what a sync must answer.
- integration
- data
- operations
Automated data onboarding without duplicate records
Automated data onboarding works when the import repeats: normalised records, duplicate detection, a reconciliation total, and a queue for the rows that fail.
- data
- migration
- automation
Invoice exception handling: where automation succeeds or fails
Invoice exception handling automation decides whether the pipeline survives: who owns each exception, what the system records, and what is not approved alone.
- invoice-automation
- exceptions
- operations
Start a project
Have something to build?
One short brief is enough. You get a written scope and a fixed quote before anything starts.
