← All postsHow-to

API versioning: changing an interface other people depend on

API versioning is a promise about what will not break. Which changes are safe, how to version without forking your codebase, and how to deprecate without stranding integrations.

How-toA

The moment somebody integrates with your API, you have made a promise you did not write down. API versioning is how that promise gets stated: which changes you may make without warning, which require a new version, and how long the old one keeps working. The hard part is not the mechanism — it is deciding the policy and then being bound by it when the policy is inconvenient.

Which changes are safe

  • Adding a new endpoint — safe, as long as it does not change the behaviour of existing ones.
  • Adding an optional field to a response — safe only if clients are told to ignore unknown fields, which has to be documented from day one.
  • Adding an optional request parameter with a default matching today's behaviour — safe.
  • Removing or renaming a field, tightening validation, changing a default, changing an error code, changing pagination — all breaking, however small they look.
  • Changing the meaning of an existing field while keeping its name — the worst kind, because nothing fails loudly and the data is quietly wrong.

Where API versioning lives: path or header

In the path is the common choice because it is visible, cacheable and trivial to route; a header is cleaner in principle and harder for integrators to debug by eye. Either works. What does not work is versioning per endpoint, which produces a matrix nobody can reason about, or a version that is really a date on each client's account, which moves the complexity to your side and surfaces as support tickets you cannot reproduce. Pick one axis, apply it uniformly, and document which parts of the surface it covers.

Version the interface, not the implementation. If you find yourself maintaining two codebases, the versioning scheme is wrong — most of a new version should be a translation layer over the same internals, and when that becomes impossible it is usually a signal the old version should be retired rather than preserved.

Deprecating without stranding anybody

  1. Publish the policy before you need it: how long a version is supported, and what notice you give.
  2. Announce the deprecation with a date rather than "soon", and repeat it in the response headers of the old version.
  3. Measure who is still calling it. Deprecation without usage data is guesswork, and the biggest caller is often somebody you did not know existed.
  4. Contact the remaining callers directly once the number is small enough to count.
  5. Brown-out before you switch off: short, announced outages of the old version find the clients that ignored every email.
  6. Keep the dates you published, including when it is awkward. A missed sunset teaches integrators that your deadlines are negotiable.

What to write down

The support window, the notice period, what counts as a breaking change in your definition, and how changes are announced. That last one matters more than it sounds: an integrator who has to watch a changelog they were never told about will find out about your change from a failing job at two in the morning. Where the interface is also exposed to agents through tools, the same discipline applies — a tool definition is an interface with the same promises attached.

The Ettex Api portal documents the endpoints and the authentication model in one place, and the specification is what both human integrators and generated clients read. Keeping that specification honest is most of versioning in practice: a published contract that matches behaviour makes a breaking change obvious before it ships rather than after.

Frequently asked

Is adding a field a breaking change?

Not if clients were told from the start to ignore unknown fields, and that instruction is in your documentation. If it was never stated, assume somebody is parsing strictly and treat it as breaking.

Path or header versioning?

Either, applied consistently. Path versions are easier to debug and cache; header versions keep URLs stable. The failure mode to avoid is versioning per endpoint.

How long should an old version be supported?

Long enough that a client on a quarterly release cycle can act — six to twelve months is common. What matters most is publishing the number in advance and then honouring it.

MI
Written by Maria I.

Part of the Ettex team — writing about product, engineering and the future of work.

More posts
Get the best of the Ettex blogProduct news, guides and tips — straight to your inbox, no spam.