Most businesses don't need one more tool. They need the tools they already have to talk to each other: the store and the accounting system, the CRM and the email platform, the booking calendar and the payment provider. That's integration work, and it's often where custom software delivers its clearest return.
The copy-paste tax
Every time someone re-types an order into the accounting system, exports a CSV to update a CRM, or checks stock in one system before confirming a sale in another, the business pays a small tax in time and errors. Individually the tasks are minor. Added up across a team and a year, they're a significant cost — and the errors they introduce are often discovered much later, when they're harder to fix.
Map the flow of data first
Before writing code, draw where each piece of data is created, who changes it and where it needs to end up. For each kind of record — customer, product, order, invoice — decide which system is the source of truth. When two systems disagree, the source of truth wins.
This step often reveals that the problem isn't technical at all: two teams were maintaining the same customer list in different places, each assuming theirs was correct.
APIs, webhooks and schedules
- Webhooks — the source system notifies yours the moment something changes. Fast and efficient, when the system supports it.
- API polling — your system asks regularly whether anything has changed. Simple and reliable, but less immediate.
- Scheduled batch sync — a nightly or hourly job moves data in bulk. Fine for reporting and data that doesn't need to be fresh.
- File exchange — sometimes the only option with older systems, and still perfectly workable with care.
The right choice depends on how fresh the data needs to be and what each system supports. Many integrations combine them: webhooks for speed, plus a nightly reconciliation to catch anything missed.
Design for failure
Networks drop, services go down for maintenance, and APIs occasionally return errors for no clear reason. Good integrations assume all of this will happen. They retry safely with increasing delays, never process the same event twice, and tell someone when they're stuck rather than failing silently.
// Process each event exactly once, even if it's delivered twice.
if (await processed.has(event.id)) return;
await syncOrder(event.payload);
await processed.add(event.id);Failed events should land in a queue a person can inspect and replay — so a two-hour outage at your payment provider becomes a short delay, not a set of missing orders.
Security and access
Integrations hold keys to your most important systems. Give each one the narrowest access it needs, store credentials in a secrets manager rather than the code, rotate them on a schedule, and verify that incoming webhooks genuinely come from the system they claim to.
Own it after launch
APIs change versions, credentials expire, and a vendor occasionally retires an endpoint with a few months' notice. Monitoring, alerts and a named owner keep integrations working long after the project that built them. Budget for a little ongoing care; it's far cheaper than discovering a broken sync after a month of missing data.