Integration

Integration That Survives Real Life: Contracts, Observability and Failure Paths

Why durable systems integration depends on clear API contracts, observability and well-designed failure paths far more than on the integration tool you choose.

Integration · · Stefan Amann

Integration is judged on the bad days, not the good ones

Durable integration is built on three things: explicit contracts, real observability and deliberate failure paths. None of them is the integration tool. Almost every integration works on the day it ships, when the network is calm, both sides are healthy and the data is clean. It is six months later, when a downstream service is slow, a payload arrives malformed and nobody remembers who owns the flow, that you discover whether it was actually engineered. That is the bar that matters, and it has very little to do with which platform moved the message.

Tool choice consumes a surprising share of integration discussions. It is the least important of the decisions in front of you.

Contracts: the part everyone underestimates

A contract is the agreement between two systems about what they exchange: the shape of the data, what each field means, which fields are required, and how the interface changes over time. It is the single most valuable artefact in an integration, and the most commonly skipped.

When there is no real contract, integrations couple to implementation instead of to an agreement. A consumer starts depending on a field that was never promised; a producer changes something it considered internal; and a flow that “worked fine for a year” breaks with no warning. The failure is blamed on the change, but the real fault was the absence of a contract that said what was safe to rely on.

Good contract discipline means:

  • The contract is explicit and versioned. Written down, owned, and changed deliberately, not inferred from whatever the endpoint happened to return last Tuesday.
  • Compatibility is a rule, not a hope. Additive changes are safe; removing or repurposing a field is a breaking change and is treated as one, with a versioning and migration path.
  • Contracts are tested from both sides. The producer proves it still honours the contract; the consumer proves it only depends on what the contract promises. This is what stops a routine deployment from quietly breaking three teams downstream.

This is the foundation of how we approach systems integration: connect systems through clean, observable contracts so the landscape behaves like one system rather than ten coincidentally adjacent ones.

Observability: you cannot fix what you cannot see

When an integration misbehaves in production, the first question is always the same: what actually happened? If the honest answer is “we are not sure”, the integration is not finished, regardless of how well it runs.

Observability for integration is more than uptime monitoring. It means being able to answer, after the fact and without guessing:

  • Did this message arrive, and when?
  • Was it accepted, rejected or retried, and why?
  • Where is it now, and how long did each hop take?
  • If it failed, what was the payload and the error?

In practice that requires correlation: a trace or identifier that follows a transaction across every system it touches, so you can reconstruct one business event end to end rather than staring at four separate logs and hoping the timestamps line up. It requires meaningful metrics: throughput, latency, error and retry rates per flow, not just per server. And it requires enough context in errors to act on them, captured in a way that respects the sensitivity of the data being moved.

Without this, every incident becomes an archaeology project, and the time to resolve is measured in hours of log-grepping rather than minutes of reading a trace.

Failure paths: design for when, not if

The defining assumption of integration is that the systems are independent and will, eventually, fail independently. A downstream service will be down for maintenance. A message will be malformed. A network call will time out. The question is never whether this happens. It is whether the system was designed for it or merely hopes to avoid it.

Designing failure paths deliberately means deciding, in advance:

  • Retries with backoff for transient failures, but bounded, so a struggling downstream is not hammered into a deeper outage by well-meaning retries.
  • Idempotency, so that a retried or duplicated message does not create a second order, a double charge or a duplicate record. This is the difference between a safe retry and a corrupted dataset.
  • Dead-letter handling, so a message that cannot be processed is parked somewhere visible and recoverable, rather than silently dropped or blocking everything behind it.
  • Backpressure and isolation, so that one slow or failing integration cannot exhaust shared resources and drag healthy flows down with it.
  • Graceful degradation, so that when a non-critical dependency is unavailable, the core business function continues instead of failing wholesale.

The systems that survive real life are the ones where someone sat down before launch and asked, for each dependency, “what do we do when this is down?”, then wrote the answer into the design rather than leaving it to a 2 a.m. discovery.

What this looks like in the field

A manufacturing client called us because their order system was “slow.” It was not slow. It was wrong, and three people spent the first hour of every workday cleaning up after it. Orders lived in an old ERP. Production scheduling lived in a tool someone bought in 2019. A nightly export tried to reconcile the two and failed often. When it failed, staff patched the gap by hand and trusted their gut over the screen. By the time we arrived the workaround was the process: nobody believed either system, they believed a spreadsheet a shift lead kept on her own laptop.

We scoped it tight: one domain (order state), not the whole ERP. Three moves. First, pick a single source of truth: the ERP, because that is what finance and the customer see. Obvious on paper; it still cost a week of meetings, because the floor had real reasons to trust the newer tool’s timestamps. Second, replace the nightly export with an event-driven sync that retries on transient failures and, when two records genuinely conflict, drops them into a manual-review queue instead of silently picking a winner. Third, move the reconciliation logic into code, with tests.

The first version made things worse: it resolved toward the wrong system, finance caught a mismatch within two days, and the spreadsheet came back out for a week. We flipped the source of truth, kept the review queue, and it settled. That is the honest shape of integration work: not a clean arc, but a contract you correct under real traffic until it holds.

The numbers, openly estimated: roughly 750 person-hours a year re-typing figures two systems should have agreed on, plus the two or three mis-shipped orders a month that each cost a re-pick, a re-ship and an irritated customer. The integration was the easy layer. The root cause was that nobody owned order state on the org chart. Until someone does, by name rather than by diagram, another tool gets bought in a few years that also wants to own orders, and the spreadsheet comes straight back.

So where does tool choice fit?

It matters, but it is downstream of the principles above. A capable integration platform makes contracts, observability and failure handling easier to implement well, but it cannot supply the thinking. A team that has not defined its contracts or designed its failure paths will build fragile integrations on the most sophisticated platform available. A team that has done that thinking will build resilient ones on modest tooling.

Choose the tool to fit the patterns you have decided on: message volumes, latency needs, the operational maturity of the team. Do not let the tool choose the patterns for you.

The takeaway

Integration is not the act of connecting two systems. It is the discipline of keeping them working together while they each change, fail and recover on their own schedules. Contracts make change safe, observability makes failure diagnosable, and deliberate failure paths make recovery routine. Master those, and the tool becomes an implementation detail.

If you are wiring together CRMs, ERPs, billing and data platforms, and want flows that hold up on the bad days, talk to TrueForge. We design integration around the contracts and failure paths first, and pick the tooling to match.

If this maps to a system you own, we can talk it through.

Modernisation is a conversation before it's a project.