An API integration is easy to demonstrate and difficult to keep running. The demo works because everything is available, the data is clean and nothing has changed. Production is none of those things.
These are the failures that show up later, in roughly the order they arrive.
Both systems think they own the data
This is the big one, and it is a design decision rather than a bug. If a customer address can be edited in the CRM and in the e-commerce platform, and both push to each other, you have built a system where the last write wins and nobody can say which is correct.
Decide, per field, which system is the source of truth. Write it down. Then make the other one read-only for that field, in the interface, not just by convention. Convention loses to a salesperson in a hurry every time.
Nothing is idempotent
A message gets delivered twice. This is not rare; it is normal, and every serious queue guarantees at-least-once delivery rather than exactly-once.
If receiving the same order twice creates two orders, you will find out from a customer. The fix is to make operations safe to repeat: give each message a stable identifier, record which ones you have processed, and ignore repeats.
This is cheap at design time and expensive to retrofit after the duplicates are already in the ledger.
The other end goes down and yours goes with it
If your checkout calls a stock system synchronously and that system is slow, your checkout is slow. If it is down, your checkout is down. You have coupled your availability to theirs without meaning to.
Where an operation does not truly need an immediate answer, queue it. Where it does, set an aggressive timeout and define what happens when it expires. Failing quickly with a sensible fallback beats hanging.
Nobody notices it stopped
The most common serious integration failure is silent. A credential expires, an endpoint changes, a certificate lapses. Nothing errors visibly. Data simply stops flowing, and it is discovered weeks later when a report looks wrong.
Monitor the absence of activity, not just the presence of errors. If a feed normally carries something every hour, alert when it has been quiet for two. That single check catches more real incidents than any amount of error logging.
The data is not what the documentation says
Documented fields are optional in practice. Dates arrive in three formats. Free-text fields contain things nobody anticipated. A field documented as an integer sometimes contains a string.
Validate at the boundary, log what you rejected and why, and never assume the other end is as disciplined as its documentation implies. It rarely is, and that is not a criticism, it is just what accumulates in a system that has been running for a decade.
Rate limits arrive at the worst moment
Everything works during development because you are making a handful of calls. Then a bulk import runs, you hit a limit, and requests start failing.
Read the limits before you build, batch where the API allows it, and implement backoff that waits progressively longer rather than retrying immediately. Retrying hard against a rate limit is how a small problem becomes an outage.
The versioning surprise
Your integration was built against version 2. Version 3 is announced with a deprecation date. Whether that is a minor task or a rewrite depends entirely on how tightly you coupled to the original.
Keeping the code that talks to an external system separate from the code that uses the results makes version changes survivable. It is a small discipline that pays years later.
What good API integration looks like
An integration you can explain in one diagram, that knows which side owns each field, that is safe to replay, that tells you when it goes quiet, and that fails in a way a human can understand at eight in the morning.
That is what our system integration work aims at, and it is why the monitoring is part of the build rather than a later phase.
Related reading
- Why internal tools stop being used three months after launch — Internal tools rarely fail technically. They fail because they make someone slower, cannot express the exception, or have nobody who owns them.
- Data migration: the part of every project that gets underestimated — Data migration is never a copy. It is a negotiation with years of accumulated mess. What to plan for, how to rehearse it, and how to know when it is done.
- Specifying rugged mobile devices for warehouse and field work — Consumer phones look cheaper than rugged mobile devices until you count replacements and downtime. What the ratings mean and which specifications matter.