intermediate 2 min answer

Twilio's core REST API still answers under the path /2010-04-01 and its resources carry an api_version field whose documented values include 2008-08-01. Sixteen years on, that date is the documented base URL rather than a legacy alias. What kind of decision was putting a date in the path, and what should a team take from how it played out?

twilioapi versioningone-way doorreversibilitydeprecation
Show the full answer Hide the answer

The situation

Twilio's documentation gives the REST base URL as api.twilio.com/2010-04-01, and the date in the path is the version identifier. Resource payloads carry an api_version property; the applications documentation shows 2010-04-01 and the older 2008-08-01 as values, and phone numbers default to 2010-04-01. Newer product APIs live on a different shape entirely - product-specific hosts with /v1 or /v2 - and return JSON only, while the 2010 API returns XML by default.

What actually became irreversible

Not the string. The copies. A version in a path is cheap to choose and expensive to retire, because within months it exists in places the vendor does not control:

  • Every customer's client code, including code at companies that no longer employ the author.
  • Stored configuration: callback URLs and application records persisted by customers years ago.
  • Snippets in third-party tutorials, Stack Overflow answers and SDKs with their own release cadence.

A decision whose reversal requires other people to deploy is a one-way door, whatever the changelog says. The platform cannot migrate its customers; it can only ask, and asking an installed base of hundreds of thousands of accounts has a response rate well under one.

How they escaped anyway

The interesting move is that they did not migrate the old surface - they grew beside it. New products got new hosts and a new version scheme, leaving the 2010 path in place for the resources that have always been there. The old surface keeps its semantics, including its default content type, and the new one is free to be different.

That is the reusable lesson: when a contract is held by other people, the cheap path forward is an additional surface, not a changed one. Adding costs you a second code path to maintain. Changing costs you a multi-year deprecation programme with a long tail you cannot close.

The decision rule

Before shipping anything that goes in a URL path, a payload field name, a webhook body or a stored identifier format, ask: who has to deploy for us to undo this? If the answer includes anyone outside the company, treat it as a one-way door - spend the extra day on the shape now, and design the surface so a second version can sit next to the first rather than replace it.

Where copying it would be a mistake - and when the reverse is the wrong answer

Do not read this as "never put versions in paths". For an internal API with three consumers, a path version is clear, trivially greppable, and reversible in one sprint because you can deploy all three consumers. The cost is entirely a function of who holds copies.

Nor should a small platform conclude that every old version lives forever. With a few hundred customers and contractual deprecation rights, sunsetting a version in twelve to eighteen months is routine - the number of parties, not the technique, decides. The expensive case is a self-serve developer platform where you cannot even enumerate your callers, and that is exactly the case where teams are most tempted to ship a quick path version on day one.