Skip to content
View2 min read

An API you cannot version is a dead end

The decision about how you change an API is made once, early, and never revisited. Getting it wrong costs a rewrite. Here is the version I default to.

Team Quorix Digital

The engineers and strategists who do the work

  • api
  • architecture
Diagram: three API versioning schemes compared, and a deprecation timeline showing versions running in parallel.
Version in the path, because it survives logs, proxies and a URL pasted into a ticket. And run the old version longer than feels necessary.

Every API team eventually gets the question from a client: can we change this? The answer depends entirely on a decision made before anyone asked, usually by omission.

If nothing was decided, the answer is no, and it stays no forever.

The only three questions that matter

Can a client tell which version it is calling? If version is inferred from headers, behaviour or a feature flag rather than stated, then no client can prove what it depends on, and no client can safely be told to move.

Can you add a field without asking anyone? If yes, additive change is safe and that covers most evolution. If adding a field requires a conversation, you have a version problem masquerading as a policy.

Can you remove a field? This is the one that finds out. A field cannot be removed while anything might use it, and "anything might use it" includes every client, every script, and the person who exported it to a spreadsheet in 2023.

What I default to

Version in the path: /v2/orders. Explicit, obvious in logs, trivial to route at the edge, and impossible to misread.

Not in the header. A header is easy to forget, easy to get dropped by a proxy, and invisible in a URL someone pasted into a ticket. Being invisible is the problem.

Not a floating "latest". A version that moves is not a version. You cannot tell anyone "we will never remove this" if "it" can change underneath them.

The bit people argue about

Run both versions in parallel. Almost always, for longer than feels necessary, and clients get a date, not a conversation. A client on a deprecated version is a client who has not finished, not a client who is being difficult.

The alternative — cutting a version when the usage graph looks quiet — is how you find out that some enterprise customer's nightly sync reads a field you deleted in March.

What makes this expensive when you get it wrong

Changing the versioning scheme later means running two mechanisms at once, forever, or breaking every client you have.

That is usually the moment an API stops being an interface and becomes a liability: teams start shipping changes with a support ticket open, because nobody can safely remove anything.

The cheapest possible mitigation

If you do nothing else, log which clients are calling which endpoints, with enough identity to tell them apart, and review it monthly.

That single chart is what lets you answer the question honestly. Without it, every change is a negotiation with everybody, because nobody can be shown they are unaffected. With it, most changes are obviously safe and the rest are a conversation with two named clients rather than a broadcast to the entire base.

A note on GraphQL

GraphQL is often sold as solving this by letting clients ask for the fields they want. It does help with over-fetching. It makes versioning harder, because a client can depend on any field in the schema, and you cannot add a deprecated field without leaving it there.

Not a reason to avoid it. A reason to decide your deprecation policy at the same time you decide to adopt it, rather than after the first client has depended on a field you wanted to remove.

If this sounds like your problem

Review how your API changes

If nobody on your team can say how you would remove a field from your API without breaking a client, that is the conversation. A call is usually enough to tell you whether it is a real risk or a theoretical one.

No pitch deck. A 30-minute call, and we will tell you if we are the wrong studio for this.

Was this worth your time?

One tap. We read every answer and it changes what we write next.

Book a call now