Governance
The lifecycle of an API: telling a compatible change from a breaking change, running a deprecation through to retirement, and making the rules executable.
An API outlives the project that created it. Governance means deciding, before the need arises, how it will change and how it will be retired. Everything else, conventions, reviews, tooling, follows from those two decisions.
The lifecycle
Design. The contract is written before the implementation, reviewed, published as a draft. Consumers can develop against a mock while the service is being written.
Publication. The API enters production with a version, documentation and an announced service level.
Evolution. Compatible changes accumulate. This is the longest phase and the one where the expensive decisions are taken.
Deprecation. The API still works but must no longer be adopted. A retirement date is announced. This is a stage with an end, not a lasting state, and letting it drag on amounts to operating two versions indefinitely.
Retirement. The API no longer answers, preferably with an explicit 410 Gone for a
few weeks rather than silence.
Compatible or not
A change is compatible if it breaks no consumer that respects the contract. The split is made line by line, not by intuition.
| Compatible | Breaking |
|---|---|
| Adding an optional field to a response | Removing or renaming a field |
| Adding an operation | Changing the type of a field |
| Adding an enum value on input | Adding an enum value in a response |
| Widening an accepted range | Narrowing an accepted range |
| Adding a documented error code | Changing the meaning of an existing code |
Two rows in this table surprise people. An enum widened in a response breaks the consumers that handle values exhaustively. The contract has to say whether the list is open. And an “addition only” field ends up breaking a consumer that validates unknown properties strictly. The validation policy is part of the contract.
The check is tooled: a contract differ in the integration pipeline classifies every modification and blocks unacknowledged breaking changes. It is the textbook example of an executable rule.
How to handle versioning
The question comes in three parts: where to carry the version, when to create one, and how many to serve at a time.
Where. Three locations exist, and the choice is made once for the whole platform.
| Location | Example | What it is worth |
|---|---|---|
| URL path | /v2/clients | Readable, testable from a browser, routable by the gateway without reading headers. The most widespread |
| Header | Accept: application/vnd.example.v2+json | Purist, invisible in logs and traces, poorly supported by consumer tooling |
| Parameter | ?version=2 | Best avoided: easily omitted by clients, invisible to routing rules |
The path wins in practice for an operational reason: the version shows up in metrics, logs and routing rules with no special handling. Finding out who still calls v1 becomes a query instead of a project.
When. A major version is created only for a breaking change, never to mark new functionality. The reverse rule is more useful still: the question to ask is not “do we need a v2” but “is this change really breaking”, and the table above answers it. A good share of published v2s could have been additions.
Minor versions are not exposed in the URL. They are documented in the changelog and signalled, where needed, by an informational response header.
How many. One major version added at a time, and never more than two served in parallel. Every version in production costs operations, support and attack surface. A third simultaneous version is not a choice: it is the symptom of a deprecation that was never seen through.
The case of internal APIs. Versioning is expensive and is justified by the impossibility of coordinating consumers. Internally, when the callers are known and reachable, a negotiated change often costs less than one more version to maintain. The exposure regime decides, see internal and external.
Deprecation, the genuinely hard step
Retiring an API means knowing who still calls it, and this is where governance meets observability: without per-consumer metrics, deprecation is done blind.
The sequence that works: announce with the retirement date, mark responses with the
Deprecation and Sunset headers, contact the remaining consumers by name from the
metrics, progressively tighten the quotas, retire. Every step is dated and public. The
difficulty is holding the schedule when a large consumer asks for an extension, and that
is a management decision, not a platform one.
Executable rules
A governance rule that lives in a document applies for the first six weeks. The rules that hold are the ones the pipeline checks: naming conventions, presence of examples and error descriptions, compatibility of changes, contract quality thresholds. The document explains the why, the pipeline enforces the what.
This shift also changes the role of the governance team: it no longer reviews every API in committee, it maintains the rules and their exceptions. Architecture boards keep the new cases, not conformance checking.
Updated August 2026.