Cross-sector

API integration

A pattern for connecting systems that were never designed to agree with each other. It establishes one integration layer, a canonical internal model, and a set of failure semantics — idempotency, retries, reconciliation and traceability — so external dependencies cannot silently corrupt the systems they feed.

Canonical domain model with anti-corruption adapters Signed webhooks with replay protection Idempotency keys on inbound and outbound writes Queues with dead-letter handling and replay tooling
The situation

When this pattern is the right one.

Operational friction is rarely caused by a single system. It is caused by the gaps between them, where data is copied by hand or moved by scripts that nobody owns. Each integration tends to be built once, for one purpose, and then left to run unattended.

01

Systems disagree about identifiers, status values, currencies and time zones

02

Point-to-point connections mean a change to one interface breaks several flows at once

03

A failed sync is often not detected, so the two systems disagree silently

04

API credentials end up in configuration files, chat messages and shared documents

05

There is no reliable way to prove the position in one system matches another

The approach

How the work is done.

All external contact goes through one layer, so mapping, credentials, retries and audit live in a single place rather than being spread across application code. The canonical internal model is defined first, and every partner is adapted into it explicitly, which is where the real translation work actually lives. Failure is treated as the normal case rather than the exception: inbound events are idempotent, outbound calls are retried with backoff and circuit breaking, and every synchronisation can be reconciled and replayed. Consumers are authenticated with scoped, revocable credentials and every call is attributable.

Single integration layer with provider abstraction so vendors can be replaced

Canonical internal model with explicit, versioned mappings per partner

Idempotent inbound handlers keyed on a provider event identifier

Timeouts, exponential backoff, circuit breaking and dead-letter handling

Scheduled reconciliation reports that prove two systems agree

Scoped, revocable credentials with secrets held outside source and never logged

Indicative stack

What this is usually built with.

Chosen per problem rather than run as one stack for everything. The list below is representative, not a commitment.

Representative componentsselected per constraint
Canonical domain model with anti-corruption adapters
Signed webhooks with replay protection
Idempotency keys on inbound and outbound writes
Queues with dead-letter handling and replay tooling
Retry policies with exponential backoff and circuit breakers
OAuth 2.0 / OIDC and scoped service credentials
Contract tests and consumer-driven compatibility checks
Continuous reconciliation between connected systems
What it supports

The outcome this pattern is chosen for.

This pattern is designed to support connected systems that can be trusted to agree with each other, and to make disagreement visible before it becomes a business problem.

01

Removes point-to-point coupling, so one interface change stops being a multi-team event

02

Makes a stalled or failed synchronisation visible rather than silent

03

Allows every integration to be replayed or reconciled on demand

04

Gives each partner the least access it needs, revocable without a redeployment

05

Provides an audit trail from an inbound event to the state change it caused

Watchouts

The parts that tend to go wrong.

Written down because they are the same parts that go wrong everywhere, and knowing them up front is cheaper than discovering them halfway through.

Vendor sandboxes rarely behave like production, so rate limits and failure modes surface late unless tested deliberately

Retries without idempotency guarantee duplicate writes, and duplicates are far harder to remove than to prevent

Retaining every partner quirk inside the mapping layer eventually makes that layer the hardest thing to change

Pagination and incremental sync semantics differ per provider and are the usual cause of incomplete syncs

Integration code that is never monitored becomes an unknown dependency nobody is accountable for

Note

These are solution patterns, not client case studies. Each one describes a reusable engineering approach and the problem shape it addresses. No client is named and no result is claimed.

Note

Nothing here reports a measured outcome. The outcome sections describe what each pattern is designed to support, and what a team should expect to be able to do once it is in place.

Note

Named references, implementation detail and engagement history can be discussed directly on request, subject to client confidentiality.

Note

This page is structured so that verified case studies can be added alongside these patterns without changing the underlying format.

Recognise your situation in this one?

Patterns are general. The engineering decisions are not, and they are worth discussing against your actual constraints.

Start a conversation All patterns