API integration

Wiring somebody else's API into software you own.

Two systems that both work fine on their own do not automatically work together. The interesting failures are not in the happy path. They are in what happens when a webhook fires twice, a field gets renamed on one side, or the other system is down for ten minutes during your busiest hour.

What this is

Integration is connecting a CRM to an ERP, a storefront to accounting software, an internal tool to a vendor's API, so data moves between systems that were each built without the other in mind. The first real work is not code, it is reconciling the schema mismatch: a "customer" in one system is an "account" in another, a status field has five values on one side and three on the other, and someone has to decide what happens to the two values that do not map cleanly rather than silently dropping them. Authentication differs per system too: OAuth tokens that expire and need refreshing, API keys that need rotating, IP allowlisting that has to be requested from the vendor before the first call works.

The part that separates a working integration from one that quietly corrupts data over months is failure handling. A webhook can and will arrive twice, so every handler needs an idempotency key that makes processing the same event twice a no-op instead of a duplicate order. A call that fails needs a retry with backoff rather than either silently dropping the event or hammering a rate-limited endpoint into a longer outage. And the exchanges that keep failing need a dead-letter path that puts them in front of a person, because an integration that fails silently is worse than one that fails loudly and pages someone.

The specifics that bite are the vendor's, not yours. Cursor pagination that invalidates mid-run when a record you already read gets updated, so a nightly sync silently skips rows. OAuth refresh tokens that rotate on use, where a replayed refresh kills the session for everybody and the only symptom is a 401 an hour later. Sandbox rate limits that do not match production, so the thing you load-tested against is not the thing you shipped against. We read the vendor's changelog and their status page as part of the work, because the integration breaks on their schedule rather than ours.

What you get

A written mapping between the two systems' data models

Including the fields that do not mean quite the same thing on each side, and the decision for each.

The integration itself

Webhook receivers, polling jobs or a queue consumer, whichever the two systems actually support.

Idempotency handling

So a retried or duplicated event does not create a duplicate record on the other side.

Retry, backoff and a dead-letter path

For the exchanges that keep failing, so they surface to a person instead of vanishing silently.

A reconciliation job

That checks the two systems still agree, catching drift before a customer or an accountant does.

Monitoring and alerting on the integration itself

Not just on the two systems either side of it, which can both look healthy while the pipe between them is not.

Authentication handled per system

OAuth refresh, API key rotation, IP allowlisting, whatever each side actually requires.

Source, infrastructure and the mapping documentation

Handed over, so the next person who touches it is not starting from the code alone.

When this fits, and when it does not

A good fit

  • Two systems both work and both stay, and the job is making them agree, not replacing either one.
  • The exchange has to survive one side being down, slow or rate-limited without losing or duplicating data.
  • Data currently moves by someone exporting a CSV from one system and importing it into the other by hand.
  • You are adding a new tool, payments, shipping or a CRM, to a stack that already works, and it has to plug in without a rewrite of either side.
  • The exchange needs to run continuously in production, not once, and needs someone watching it after launch.

Not a good fit

  • The job is two business systems that both stay and have to keep agreeing about customers, orders or stock. That is system integration, and it is a different page. This one is the narrower case: one vendor API, one direction, wired into code you already own.
  • You want us to own the vendor relationship: chase their support, sit in their partner programme, be the ones on the call when their API breaks. We write the client and the failure handling. The commercial relationship with the vendor stays yours.
  • You need a new interface for people to look at, not a new pipe between two systems nobody watches. That is internal tools.
  • One of the two systems does not exist yet. Build it first, whether that is SaaS product development or an internal tool, and integrate once there is a second system to connect it to.

How it runs

  1. 01

    Map both systems' data models

    And find where the words mean different things before writing an exchange between them.

  2. 02

    Decide the pattern

    Webhook, poll or queue, based on what the sender actually supports and how fast the receiver needs the data.

  3. 03

    Build the exchange with idempotency and retries in

    From the start, not added after the first duplicate record ships to production.

  4. 04

    Add reconciliation and monitoring

    Because an integration that fails silently is worse than one that pages someone.

  5. 05

    Hand over the mapping and the runbook

    Including what to do the day a vendor changes their API without telling anyone.

Questions we get

What if one of the systems has no API at all?

There are fallbacks, a scheduled database export, in rare cases screen scraping as a last resort, but if a system genuinely has nothing to integrate against, that is usually a sign the underlying system needs modernizing first rather than integrating around.

How do you stop duplicate records when a webhook fires twice?

Every event carries or gets assigned an idempotency key, and processing checks that key before creating anything. A duplicate event becomes a no-op instead of a second order, a second invoice or a second customer record.

Who monitors it once it is live?

Alerting is handed over configured and working by default. Whoever is on call for it should be agreed before it ships rather than discovered the first time it fires. What is not optional is that something watches it.

Can you work with a specific vendor's API?

If it has a documented API, yes. We read the documentation and the rate limits before quoting, and if a vendor's API genuinely cannot support what is being asked, we say that plainly rather than discover it mid-project.

Two systems that need to actually talk to each other?

Name both systems and what currently happens by hand between them. An engineer reads it and tells you whether the vendor's API can actually do what you are assuming it can.