Guide · deployment

How to Depend on an API You Do Not Control

The other half of an integration is somebody else's product, and it will change, expire and go down on its own schedule. How to build a connector that degrades instead of corrupting, and finds out before your customers do.

By stackzen-desk · Editorial reviews deskLast updated September 1, 2026

The half of the integration nobody on your team owns

An integration has two halves and you write one of them. The other is a product with its own roadmap, its own incidents, its own idea of what counts as a breaking change, and no obligation to consult you. Most of the effort goes into the half you control; most of the failures arrive from the half you do not.

This is not about swapping one model provider for another, which has a known answer: put the provider behind one door. It is about the ordinary systems a product connects to — the CRM, the help desk, the billing system — where you cannot abstract the dependency away, because the whole point is that specific system.

Read tolerantly, write strictly

The most common way an integration breaks is that the other side added something. A parser configured to reject unknown fields turns every ordinary addition upstream into an outage on your side, and the provider did nothing wrong. Read the fields you use, ignore the rest, and treat enumerated values as open — code that switches on a status and throws on anything unfamiliar fails the first day a new status ships. Hold the unrecognised record for a person to look at rather than mapping it quietly to a default, because a wrong default is worse than a crash: nothing tells you it happened.

Tolerance has a cost worth naming. A reader that shrugs at everything unfamiliar also shrugs at the change you needed to know about, so record unknown fields and unrecognised values in your own logs. That log line is how most teams find out a provider shipped something. Writing is the opposite discipline: send only the fields you mean to set, since echoing the whole object back writes over parts you never understood, and attach an idempotency key so a retry does not become a second record.

Pin what you can and version your own connector

Where the provider offers explicit API versions, choose one and state it on every call rather than letting requests float onto whatever is current. Floating is comfortable until the morning it is not. Where there is nothing to pin, the substitute is to keep every call to that provider behind one module in your own code: one place to change when the shape moves, and one place to read to find out what you depend on.

Give that module a version of its own and record which version handled each record you wrote. Three weeks later the question is always which code produced this, and an integration that cannot answer turns a small fix into archaeology. The same record allows a staged rollout — one customer, one queue, one percent of traffic — before it is everybody's problem.

Assume the deprecation notice will not reach you

Providers do announce changes: in a changelog nobody subscribed to, in an email to whoever opened the account four years ago, and in a banner inside a dashboard your team stopped opening. Subscribe to everything on offer, then build as though none of it will arrive.

Concretely that means a small, boring canary — a scheduled call to each endpoint you depend on, with a known input and an assertion about the shape of the response, that raises an alarm when the answer changes. An hour to write, and the difference between finding out on a Tuesday morning and finding out from a customer. Watch the responses themselves too, since many providers flag a retirement in a header long before they switch anything off. And treat the notice period as the least reliable number in the arrangement: it runs from when they published, not from when you noticed.

Their outage is yours unless you decide otherwise

A status page is the provider's own account of their own availability, published by the team responsible for it, and it lags. Use it to confirm a suspicion you already have, never as the thing that tells you; the real signal is your own error rate against that provider.

What your product does while the other side is unreachable should be decided rather than discovered. Reads can usually serve something stale with an honest mark saying so. Writes are the dangerous half: retry with an idempotency key, queue what cannot go now, and cap the queue so a long outage does not become a stampede the moment service returns. The failure to design out is the half-finished write — a record created on their side, an error returned on yours, and nothing that brings the two back together.

Credentials expire on somebody else's schedule

Access to a third-party system usually belongs to a customer rather than to you, and it can be withdrawn without anyone telling you: a token revoked, a permission removed by an administrator, the account the connection was made under deleted. Permissions also narrow without ever raising an error, because what a connection can do is the intersection of what your app asked for, what the customer approved and what that person's own role allows — and the last two change without reference to you.

Two habits make it survivable. Distinguish in your own code between an empty result and a refusal, since a permissions error handled as "no records found" produces a screen saying everything is fine while the integration quietly does nothing. And tell the right person: the user staring at the empty screen cannot repair a revoked grant, while the administrator who can does not know. An integration that fails politely to the wrong audience fails permanently.

Have a plan for the day it is switched off

Endpoints are retired, free tiers close, products are acquired and folded into something else, and terms change in ways that put your use case outside them. Over a few years that is close to a certainty for at least one dependency.

Preparing does not mean building an abstraction for a replacement you cannot name. It means knowing which of your features stop working, keeping your own copy of the data you would need in order to keep serving, and being honest about undocumented endpoints: a call you found by watching your own browser works right up until it does not, and carries no notice period at all. Write down, for each provider, what breaks and who has to be told — an afternoon of work, and the only part of this that is easier before the announcement than after it.

More guides