API and System Integration
Your product and your systems of record disagree about the same customer. We build the integrations, the data model underneath them, and the reconciliation that keeps the disagreement from returning.
- Who
- Delivered by a senior team assembled for the engagement, against a defined scope.
What you're seeing
- Someone exports two spreadsheets and reconciles them before a board meeting.
- Usually means The systems disagree and a person is the reconciliation layer. This is a modelling failure showing up as manual work, and a sync job on top of it moves the failure rather than removing it.
- The CRM, the billing system and the product each hold a different version of an account.
- Usually means Nothing has been declared the owner of each field, so the last write wins and which write is last depends on timing. It is not a data quality problem, it is an unwritten contract.
- An enterprise customer wants your product connected to something they already run.
- Usually means The integration is now a revenue dependency with a customer's timeline on it. That changes what is acceptable — a script somebody maintains in their spare time will not survive the first renewal conversation.
- Records go missing occasionally and nobody can say which ones.
- Usually means Webhook deliveries are failing without a dead-letter path. The loss is invisible by construction, which is why it is usually discovered by a customer rather than by monitoring.
- Every new connection takes as long as the first one did.
- Usually means There is no shared model to connect to, so each integration re-implements identity, retries and error handling from scratch. The cost is linear in connections when it should flatten.
The symptom
Someone exports two spreadsheets and reconciles them before a board meeting.
That is the visible form. The underlying problem is that no one has written down which system owns each field, so the answer to “how many active accounts do we have” depends on which system you ask and when. Adding a sync job on top moves the disagreement to a schedule; it does not resolve it, and it usually makes it harder to see.
The second common form is quieter. Records go missing occasionally, in small enough numbers that nobody notices a pattern, because a webhook delivery failed and nothing was watching. That one is discovered by a customer.
The model comes first
Before any connector is written, four things get settled and written down.
Identity. How the same customer is recognised in both systems. Almost never a shared key, usually a rule with exceptions, and the exceptions are where the duplicates come from.
Ownership. Which system is authoritative for each field. Not each record — each field. Billing owns the plan; the product owns last-seen; the CRM owns the account owner. Ownership at record level is what produces the arguments.
Precedence. What happens when both sides change the same field between syncs. Last-write-wins is a decision, not a default, and it should be made deliberately rather than inherited from whichever library was convenient.
Failure. What happens when a call does not return, when a delivery is repeated, and when a record cannot be matched. Each of those needs an answer before there is a connector, because retrofitting them across live integrations is significantly more expensive than designing them in.
This is roughly a week of work and it is the part clients are most tempted to skip, because nothing visibly moves while it happens.
What gets built
An agreed data model, connectors that are safe to call twice and retried when they fail, and a reconciliation report that names what did not match rather than resolving it silently.
The reconciliation output is the piece that tends to be missing elsewhere and the one that earns its place fastest. It is a short list, most days empty, of records the rules could not resolve. Somebody looks at it. That is what stops the slow drift back to two spreadsheets, and it is why an integration that surfaces its own uncertainty is worth more than one that appears to have none.
Everything ships as code in your repository, with tests and a runbook for the failure modes we know about, because an integration that only its author can change is the point-to-point script again with better tooling.
Where it sits
Where the integration is one part of a larger build — a product surface, a backend, and the systems of record behind them — it runs inside Software Development rather than as its own engagement, because splitting the data model across two contracts reproduces the problem the work exists to solve.
Where the reason integrations are painful is that every one takes as long as the first — no shared model, no reusable retry and identity layer, each connection re-implemented — the constraint is delivery capability rather than integration knowledge, and Engineering Velocity is the diagnosis that fits.
What this covers
Each of these is a capability with its own page, its own order of work and its own outputs.
| Capability | What it means |
|---|---|
| CRM & Product Integration | Product usage and revenue systems agreeing about the same customer. Identity resolved, ownership per field decided, and reconciliation that reports what it could not match. |
| Backend & API | Server-side systems and the interfaces other things depend on. Built with the contract written first, because an API is a promise and changing one after it has callers is expensive. |
| Database & Data Modeling | The schema the rest of the system is built on. Ownership, constraints and a migration path, decided before the model has a hundred callers and becomes expensive to change. |
How we decide
The data model is settled before any connector is written
Costs It front-loads a week of unglamorous work before anything visibly moves, which is uncomfortable when the manual reconciliation is happening weekly.
Most integration work fails as a modelling problem wearing a plumbing disguise. Two systems that disagree about what an account is will keep disagreeing however reliably records move between them. Identity, field ownership and precedence are the actual deliverable; the HTTP calls after that are the straightforward part.
Handlers are idempotent and every delivery is retried
Costs It costs more to build than the direct version, and the direct version works in testing.
Every webhook provider redelivers, every network partition duplicates, and every deploy replays something. A handler that is only correct when called once is a data corruption incident waiting for its trigger. Making it safe to call twice costs a design decision at the start and is expensive to retrofit across live integrations.
Unresolved records are reported, never guessed
Costs It produces a queue somebody has to look at, which reads as unfinished work.
A matching rule that silently merges two records it is unsure about creates a corruption that is very hard to reverse, because the evidence of the merge is gone. A visible gap is cheap to fix; an invisible bad merge surfaces months later in a customer's invoice.
Where an iPaaS is right, we say so
Costs It ends the engagement, or shrinks it to the modelling work.
A platform genuinely earns its cost when there are many low-complexity connections maintained by people who do not write code. Building those by hand is an expensive way to be busy. What a platform handles badly is logic that is genuinely yours, because that logic then lives somewhere your engineers cannot test or review.
Four ways to connect two systems
The choice is usually made on build time and paid for on maintenance. These are the trade-offs the second year exposes.
| Approach | What it costs to run | Who can change it | Where it breaks |
|---|---|---|---|
| Custom integration against a shared model | Engineering time, mostly at the start; the second connection is cheaper than the first | Your engineers, through review and tests like any other code | Nowhere quietly — failures land in the same alerting as everything else |
| Integration platform (iPaaS) | A licence that scales with volume or connections | Anyone with access, which is the point and the risk | When the logic outgrows the canvas and lives somewhere untestable |
| The vendor's own connector | Usually bundled | Nobody — it does what it does | At the first field the vendor did not anticipate |
| Point-to-point scripts | Nothing, until the person who wrote them is unavailable | One person, from memory | Silently, and you find out from a customer |
Row four is where most companies actually are, and it is not irrational — it was the fastest thing that worked. It stops being viable at the point where a customer contract depends on the data being right.
Is this you?
- Revenue and product data have to be reconciled by hand before a board meeting
- A CRM, a billing system and the product each hold a different version of an account
- An enterprise customer needs your product connected to something they already run
- Marketing automation as the primary goal — that is a different discipline
- One-off data loads with no ongoing relationship between the systems
- Companies wanting a workflow tool configured without a data model behind it
How we run it
The data model comes before the connector
Most integration work fails as a modelling problem wearing a plumbing disguise. Two systems that disagree about what an account is will keep disagreeing however reliably you move records between them. We settle identity, ownership and precedence first; the connector after that is the straightforward part.
Where this has run
Frequently Asked Questions
Sources
- OpenAPI Specificationspec.openapis.org
- Semantic Versioning 2.0.0semver.org
- Salesforce — integrating with the APIhelp.salesforce.com
- HubSpot — API referencedevelopers.hubspot.com
Page reviewed

