The first partner arrives with a reasonable request. A distributor wants to follow the progress of the cases it brings in, rather than phoning a case handler with every question. The service already exists: it feeds the customer portal and the advisers’ tool. The team puts it behind the gateway, issues a key, writes a documentation page. The partner is connected within a few weeks. It is a success, and it is quoted in committee as proof that the organisation knows how to open up.

Two years later, the internal team wants to replace a case status that has become ambiguous. Internally, the routine is well known: list the consumers, set a date, arbitrate. Outside, none of it works. One partner has built the status into the app it distributes to its own customers, and has no control over when they will update it. Another handed its integration to a contractor whose engagement has ended. A third does not reply. And while working out who calls what, the team finds a key that is still active, belonging to a partner whose commercial relationship ended the previous year. The change, which would have taken a few weeks between teams, will not happen.

Nothing was done badly in the technical sense. The gateway works, the documentation is current, the key is properly protected. What was missing lies elsewhere. An internal interface is an agreement between teams that share an arbiter; an external interface is a commitment made to organisations over which you have no authority. Everything that is settled by coordination inside must, outside, have been written down in advance — in the design of the interface, in the published policy, and in the contract. Opening an API is not plugging in a connector: it is taking on a series of commitments, most of which are written down nowhere.

What the organisational boundary takes away

We have described elsewhere what an interface contract contains: an owner, semantics, delivery guarantees, a lifecycle. All of that still holds for an external API. But the governance of internal interfaces rests on three unstated conditions, and they disappear the moment the consumer no longer belongs to the organisation.

The common arbiter. Internally, two teams that disagree about a change eventually escalate to someone who decides: a domain lead, a committee, a director. The migration date can be imposed, and its cost reallocated. With a partner, there is no shared hierarchy. Its roadmap, its budget and its priorities are its own. You can negotiate, incentivise, invoke a clause — you cannot decide on its behalf.

Knowledge of use. An internal team can be asked, its processing read, its code examined. A partner exposes nothing of what it does with the data: what decision it draws from it, which field it considers indispensable, which undocumented behaviour it has come to treat as guaranteed. And behind it there are often other parties — its customers, its integrators, its own partners — whose very existence is unknown to you.

The freedom to retire. An internal interface is retired once its consumers have migrated, which is a matter of scheduling. An external interface is retired on the terms set out in the contract, with a notice period, sometimes under a regulator’s eye, and with a commercial risk: the slowest partner is rarely the least important one.

The same interface consumed inside and outside the organisation Internal consumers Producer same organisation Team A Team B Team C A common arbiter sets the migration date. Versions coexist only briefly. Partner consumers Producer other organisations Partner A Partner B Partner C boundary Nobody can impose a migration date. The producer alone carries the coexistence.
Figure 1 On the left, consumers belong to the same organisation as the producer: a disagreement goes up to a common arbiter, and migration is planned together. On the right, each partner is a separate organisation, with its own calendar and its own priorities. No authority crosses the boundary; whatever was not written down before the connection can no longer be imposed after it.

The consequence fits in one sentence: the producer of an external API alone carries the cost of coexistence. Every breaking change it introduces, it must run alongside the previous version until the notice period expires, since it has no means of forcing anyone to follow. That cost, not the gateway set-up, is what sets the real price of opening up.

Re-exposing the internal API: the shortcut that exports the coupling

The fastest way to open up is the one in the opening scenario: take an internal service that works and make it reachable from outside. It looks economical. In reality it hands third parties a lasting say over choices that were never designed to be shown.

The principle that forbids exposing your internal model already applies between teams. Outside, it changes in nature, because every internal detail made visible becomes a promise that can no longer be renegotiated. Four leaks are especially common.

Identifiers. A case’s technical identifier, specific to one database, ends up stored at the partner’s end. The day the system is replaced or merged with another, that identifier has to survive the migration — or every partner has to rework its data. An external identifier, stable and independent of the system that hosts it, is decided at opening. It is almost impossible to introduce afterwards.

Statuses. An internal service naturally exposes the states of the process as it is tooled today, some of which only mean something to the back office. The partner needs to know where the case stands from its own point of view, which often comes down to a handful of situations. Exposing every internal state makes it build its logic on how the processing is organised, and prevents you from reorganising that processing without telling it.

Limits. Maximum page size, response time, behaviour under load: in an internal service these are properties of the implementation. Exposed as they are, they become the de facto contract, and partners calibrate their processing around them.

Errors. An internal error message often says too much: a table name, a stack trace, a code that gives away the technology or the structure. That is a security problem. It is also a contract leak: as soon as a partner tests that message to decide whether to retry, it depends on it.

The answer is not to rewrite every service, but to put in place an exposure layer with an existence of its own: its own contract, vocabulary, owner and pace of change. It translates between what the partner needs to do and the way the information system does it today. Its granularity is that of use — follow a case, submit a document, be notified of a decision — not that of tables. Above all, it lets the two cadences stay separate: internal services evolve at the teams’ pace, the exposure layer at the pace the contract allows.

This layer has a cost that should not be understated: one more mapping, a responsibility to assign, tests to maintain. But the choice is not between paying that cost and avoiding it. It is between a translation maintained by the producer, in a place it controls, and a translation scattered across every partner, in the form of dependencies on internal details that nobody can move any more.

Knowing who is calling, for whom, and until when

An API key is usually thought of as a secret: something to protect. It is first of all an identity, and that is the angle from which it is governed. An external call raises four distinct questions, which access mechanisms all too often collapse into one.

Who is calling? A specific application, in a specific environment — not “the partner” in general. An identifier shared between test and production, or between two applications of the same partner, makes it impossible to cut one off without the other, and impossible to tell which one is behind abnormal behaviour.

On whose account? The contracting organisation, the one that signed and answers for the use made. It is not always the one that built the integration: an integrator, an aggregation platform or a contractor may sit in between. The chain has to be known, because responsibility does not pass to the last link.

On whose behalf? When the call concerns an end customer’s data, the question becomes one of that customer’s consent or mandate: is the partner authorised to access this case, for this customer, now? That is a decision separate from the authorisation granted to the partner, and the customer must be able to withdraw it without the partner relationship being broken. Regulatory frameworks that mandate opening certain data — as several jurisdictions do for payment account data — make the distinction compulsory. It is just as relevant where nothing mandates it.

To do what? A scope: the operations and data this partner may access, for this use. Opening everything to every partner because it is simpler means exposing tomorrow, to the whole ecosystem, every operation added for just one of them.

That leaves the dimension missing from the opening scenario: the end. What holds for all access — a right only becomes revocable at the moment it is granted, as we argued about entitlement models — applies here with particular sharpness. A partner identifier must be tied to the contractual relationship that justifies it, and disappear with it. That requires a register linking each identifier to a contract, a named contact at the partner, an owner at the producer, and a scope. Without that register, the end of a commercial contract is an event the information system never receives.

Evolving what you cannot coordinate

Internally, a breaking change is handled through coordination. Externally, it is handled through a policy published before the first partner, which answers once and for all the questions every change will raise.

First, what counts as a compatible change. The usual rule — adding is allowed, removing is not — is no longer enough, because it assumes tolerant consumers. A partner whose code rejects any unknown field will break on the first addition. A partner that treats a list of values as closed will break on the first status added. The policy must therefore state explicitly what the consumer is required to accept: new fields are ignored, unknown values fall through to a default case, element order is not guaranteed. Written into the terms of use, that tolerance becomes an obligation on the consumer. Left unwritten, it remains an assumption on the producer’s side.

Next, how many versions coexist, and for how long. The notice period is not calibrated on the time the producer would need, but on the slowest cycle it considers reasonable to support. And that cycle is not always the partner’s: when the integration is embedded in an app installed by the partner’s own customers, migration depends on how quickly those users update — which the partner controls no more than the producer does.

Finally, how retirement is announced: through which channel, to which contact, with which signals in the interface itself, such as an indication in every response that the version is deprecated and of the date it will stop being served. Some organisations deliberately schedule announced interruptions of the old version before its final retirement, to surface the consumers who have read no notification at all. The technique is blunt, but it has one virtue: it reveals the problem during the notice period rather than on the day of the cut-off.

Retiring an API version: one notice period, three partners, three outcomes version 1 version 2 notice announced at publication V2 published V1 retired time Partner A dedicated team Migrates within the notice period. Partner B app installed by its customers new release of its app Its users stay on the old version. Partner C no team assigned cut off Retirement becomes a contractual matter.
Figure 2 The axis carries no scale. The retirement date of version 1 is set on the day version 2 is published, and the notice period runs for every partner at once. A well-equipped partner migrates. A partner whose app is installed by its customers ships on time, but has no control over how quickly its users follow. A partner with no team does not migrate. None of these three cases is resolved by technology.

The figure shows the limit of any policy: there will always be a partner that has not migrated. At that point, retirement stops being a technical decision. Cutting off, granting an exceptional extension, charging for keeping an obsolete version alive: these are commercial and contractual decisions, and they are all the easier to take when their terms were written down before they were needed.

One last point is often overlooked: the test environment provided to partners is part of the contract. A partner that built against a sandbox whose behaviour diverges from production — data that is too clean, errors never simulated, a version ahead or behind — has been misled by the producer itself. Keeping the two environments consistent belongs to the same discipline as versioning.

Protecting the information system from those you invited in

Opening an API means letting programmes you do not control generate load on systems that were not sized for them. The most common risk is not an attack: it is the perfectly legitimate partner whose nightly batch queries every case, one at a time, to find out whether anything has changed.

Three design decisions protect against it.

Quotas per partner, not global ones. A global limit protects the system, but lets a single consumer exhaust everyone else’s capacity. A limit per identifier, aligned with the volume set out in the contract, makes each partner’s behaviour predictable — and turns an incident into a commercial conversation.

Isolation between channels. External load must not be able to degrade the customer portal or internal tools. That requires the resources consumed by the exposure layer to be separate, or at least bounded, and frequent lookups to be served from a projection or a cache rather than from the system of record. It is a direct application of resilience by design: the failure or excess of one consumer must not spread to the others.

Notifications rather than repeated polling. A partner that wants to know when a case changes state has only two options: ask regularly, or be told. If the producer does not offer the second, it will suffer the first, at whatever frequency each partner chooses. An outbound notification mechanism — a call made to the partner when an event occurs — is then a contract in its own right: it must specify the retry policy, the signature that lets the partner verify where the message came from, the key that lets it recognise a duplicate, and what happens when the partner is unavailable for several hours.

Data minimisation belongs to the same family of decisions. A partner receives only what its use requires, and the response is built for it rather than filtered after the fact. A field someone forgot to mask in a generic response is a disclosure, and it will not show up in any functional test.

The partner that carries weight

One failure mode specific to external APIs deserves a name, because it is commercial before it is technical. An important partner asks for an extra field, a particular filter, a slightly different behaviour. The request is legitimate, the partner matters, the deadline is short. A variant is added for it.

Each variant is reasonable. Their accumulation produces an interface that is no longer one: a set of individual contracts sharing an address, each with its own implicit lifecycle, which no general change can pass through any more without case-by-case review. It is the drift of configuration that turns into custom code, transposed to exposure.

One rule contains it: every change requested by a partner is designed as if it were meant for all of them. If it makes sense for consumers as a whole, it enters the common contract, with its version and its documentation. If it does not, it becomes an explicitly individual extension, with an owner, a review date and, where appropriate, a cost borne by whoever asked for it. What is ruled out is the third way — the quiet variant — because it is the only one whose end nobody ever decides.

What architecture has to hold

External exposure is not a gateway topic. The gateway is necessary, but it executes decisions that must have been taken elsewhere. The role of architecture comes down to five things.

Deciding what can be exposed. Not every capability lends itself to opening up, and the choice should not depend on whichever partner shows up first. The business capability map is the natural place to work it through: a stable capability with an established vocabulary exposes well; a capability being redesigned should not be exposed until it has found its shape.

Giving exposure an owner. Neither the team that runs the gateway, nor the one that builds the internal service, but someone responsible for the interface offering as a whole: the person who arbitrates partner requests, holds the evolution policy and answers for the consistency of the whole.

Publishing the policy before the first partner: compatibility rules, tolerance obligations, number of supported versions, notice period, notification channel, quotas, error format. It costs little to write while nobody is connected. After that, it is negotiated partner by partner.

Keeping the consumer register, which links identifier, application, contract, contact, owner, scope and end date — and making sure the end of a commercial contract produces an event in the information system.

Feeding the legal contract. Service levels, retirement notice, liabilities in case of non-compliant use, exit terms: these clauses are drafted by lawyers and negotiated by commercial teams. If architecture does not contribute to them, they promise what the system cannot deliver, or leave out what should have been promised.

The indicators follow the same logic. The number of published APIs or connected partners measures activity, not health. What actually tells you something: how many active identifiers are tied to no current contract; how many calls still target a version whose retirement has been announced; how many individual variants exist, and how many have a review date; what share of external calls reach a system of record synchronously; and, for each deprecated version, how many partners have never acknowledged the notification.

Opening up is making a promise

An internal API is a convenience the organisation provides to itself. An external API becomes part of someone else’s product: a component of its customer journeys, of its applications, sometimes of its commitments to its own customers. From then on, the producer’s ability to change its system no longer depends on its own teams alone, but on the promises it made — and on the ones it allowed others to assume.

That is why what matters most happens before the first connection. An exposed vocabulary designed around use, a stable identifier, an evolution policy, a register, exit clauses: none of it is expensive while nobody yet depends on the interface. Introducing it afterwards means renegotiating with every partner what could have been set once for all of them. The exposure technology itself will be replaced several times over the life of those commitments. It is the commitments that last.