Integration6 min read

    How to connect two business systems that were never built to talk

    Data direction, transport, record matching and conflict rules: the four decisions that decide whether a system integration works or breaks.

    Almost every business above a certain size has this problem. Two systems hold overlapping information, neither knows about the other, and a person is the integration. They export from one, reformat it, import into the other, and do it again next week.

    It is one of the most common things we are asked to fix, and it is also one of the easiest to get wrong — because the hard part is not moving the data. The hard part is deciding what should happen when the two systems disagree.

    This article walks through how these projects are actually designed, in the order the decisions have to be made.

    First: what direction does the data flow?

    This question sounds trivial and it determines most of the design.

    One-way. System A is the source of truth, system B receives a copy. Orders flow from the shop into accounting. Nobody edits the copy in B.

    This is by far the simplest case and it should be your default. If you can make the problem one-way, do it, even if that means telling people to stop editing records in the destination.

    Two-way. Both systems can change the same record, and both need to see the other's changes. A contact updated in the CRM should update in the support tool and vice versa.

    Two-way sync is a genuinely different class of problem. It introduces conflicts, and conflicts have no technically correct answer — only business answers. More on that below.

    One-way, both directions, different fields. Often the real answer. The CRM owns the contact details, the support tool owns the ticket history, and each sends its own fields to the other. This looks like two-way sync and is not, because no field has two owners. If you can decompose your problem into this shape, do.

    The question to settle on paper before anything is built: for every field, which system owns it? Write it as a table. Fields with two owners are where your project's difficulty lives.

    Second: how does the data get across?

    Ranked roughly by how pleasant they are to work with.

    Webhooks. The source system calls you when something changes. Near real-time, efficient, and the source does the work of noticing. Two caveats that catch people out: delivery is usually "at least once", so the same event can arrive twice and your handling must tolerate it; and if your endpoint is down, events may be lost entirely or retried on a schedule you do not control. Always pair webhooks with a periodic reconciliation.

    Polling an API. You ask "what changed since I last asked?" on a schedule. Simpler to reason about and to restart. Needs a reliable "modified since" filter — if the API lacks one, you end up fetching everything, which does not scale. Watch for rate limits.

    Scheduled file exchange. A CSV appears in a folder or on an SFTP server. Old-fashioned, completely fine, and often the only option with older systems. Its problems are ordering, partial files, and knowing whether a file is finished being written. Solvable, but be explicit about them.

    Direct database access. Reading another system's database directly. Avoid unless you own both. It bypasses that system's business rules, and it breaks without warning when the vendor changes their schema in an update.

    Screen automation. Driving the user interface because there is no other route. Fragile, breaks on every redesign, and may violate the vendor's terms. Sometimes it is genuinely the only option, but treat it as a stopgap with a plan to replace it, not an architecture.

    Third: how do you match records?

    This is where more time goes than anyone expects.

    Your CRM has a customer. Your accounting system has a customer. Are they the same customer? The computer needs a rule.

    A shared identifier is the clean case. If one system stores the other's ID, matching is exact. Where you have the option to store a reference field, take it — it is worth the setup.

    A natural key — email address, tax number, order reference. Usually workable, with the caveat that people change email addresses and some share them.

    Fuzzy matching on names. "Acme Ltd", "ACME Limited", "Acme Ltd." and "acme" are one company to you and four strings to a computer. You can normalise and get most of the way, but you will not get all of the way, and the remaining cases need a person.

    Whatever you choose, decide in advance what happens on no match and on multiple matches:

    • No match: create a new record, or hold it for review? Creating automatically is how duplicate customer records multiply.
    • Multiple matches: never guess. This is a review case, always.

    And build the matching so it improves: when a person resolves an ambiguous match, store that decision so the same pair is not asked about again.

    Fourth: what happens when both sides changed?

    Only relevant for two-way sync, and it is the reason to avoid two-way sync where you can.

    A contact's phone number was edited in both systems since the last sync. Which wins?

    The options, none of which are universally right:

    Last write wins. Whichever has the newer timestamp. Simple, and silently discards someone's work. Also relies on both systems having accurate, comparable timestamps, which is not guaranteed.

    One system always wins. Designate a master for that field. Predictable, and means edits in the other system are quietly reverted — which users find maddening unless they know the rule.

    Hold for review. Correct but expensive, and only viable if conflicts are rare.

    Merge field by field. Possible when changes touch different fields. Genuinely helpful, and more work to build.

    The right answer is a business decision. The wrong answer is not deciding — which in practice means "last write wins", chosen by accident, discovered when someone's correction disappears.

    Fifth: the unglamorous parts that decide whether it lasts

    Make it safe to run twice. Network calls fail after the work is done but before the confirmation arrives. If a retry creates a second record, you will eventually get duplicates. Use a stable key derived from the source and check before creating.

    Keep an audit trail. For every record moved: when, from where, to where, and what happened. When someone asks in four months why a record looks wrong, this is the difference between an answer and a shrug.

    Reconcile periodically. Even a well-built sync drifts, because events get missed and systems have outages. A weekly job that compares both sides and reports differences catches problems before anyone notices them as symptoms.

    Handle deletion explicitly. If a record is deleted in A, should it be deleted in B? Usually not — usually it should be marked inactive. Decide, because the default behaviour of doing nothing leaves ghost records forever.

    Alert on silence. If the sync has not run when it should have, that needs to be noticed. Failure alerts do not fire when nothing runs at all.

    A realistic first version

    Resist the urge to sync everything.

    1. One direction. The one that removes the most manual work.
    2. One record type. Customers, or orders — not both.
    3. The fields you actually use downstream. Not every field the API returns.
    4. A review queue for no-match and multi-match cases.
    5. A reconciliation report, from day one.

    Run it alongside the manual process for a couple of weeks and compare. That parallel run is what buys trust, and trust is what determines whether anyone lets you extend it.

    The question worth asking first

    Before any of this: is the integration the right fix?

    Sometimes two systems overlap because the business bought the second one to work around a limitation in the first, and the honest answer is to consolidate rather than connect. Sometimes the weekly export exists because one report needs it, and a report built directly against both sources would be a tenth of the work.

    We built a FastAPI backend moving data between Quickbase and Salesforce with cloud file storage behind it, and the integration was the right answer there — a genuine recurring handoff between two systems the business needed to keep. But it is worth ten minutes of asking, because an integration you did not need is a thing you now maintain forever.

    If someone on your team exports a file on a schedule, that is worth a look. Bring the two system names and what the export is for to a free consultation and we will tell you which of the above it is.

    Common questions

    Considerably, and it is worth avoiding where you can. One-way sync has a single source of truth for each field, so there is never a question of which value is correct. Two-way sync introduces conflicts, and a conflict has no technically correct resolution — only a business decision about which system wins, and what happens to the discarded edit.

    Check for a scheduled export first, because a file dropped on a schedule is a perfectly reasonable integration for most business processes. Reading the vendor's database directly bypasses their business rules and breaks on their updates. Driving the user interface is fragile and may breach their terms. If none of those are acceptable, the honest conversation is about changing the tool.

    Give every unit of work a stable identifier derived from the source system, and check whether it already exists before creating anything. This matters because network calls can fail after the work is done but before the confirmation arrives, so retries are inevitable. Designing for repeat runs from the start is far cheaper than retrofitting it after the first duplicate incident.

    Want this looked at properly?

    Bring one process to a free 30-minute consultation. You will leave with an approach and an honest cost range, whether or not you work with us.

    Ask on WhatsApp

    Related services

    Keep reading

    All articles