Writing

Public APIs are almost forever

Jun 4, 2026

I once wrote a set of API design guidelines for a team, and if I had to compress the whole thing into one sentence it would be this: you can always add to an API, but you can almost never remove from one. Versioning feels like an escape hatch, and it is a real tool, but it does not let you strip functionality out from under a customer who depends on it. Once someone is consuming your endpoint, you are married to it until you run a deprecation that they actually act on, which is to say, a long time.

That reframes API design from “ship the thing” to “ship the thing you can live with for years.” It’s a one-way door wearing a two-way door’s clothes.

Design for the consumer, because someone is consuming it

You don’t build an API unless something is meant to call it, so the entire job is making it easy to call. A few principles that earned their place:

  • Don’t violate the law of least surprise. The behavior should be what a reasonable consumer expects. Clever is the enemy here. Boring and predictable is the goal.
  • Keep the parameter list short and the names memorable. Every parameter is a thing someone has to learn, remember, and get wrong at 2am.
  • Let consumers be specific, not more general than you designed for. Give them precision where you planned for it, and don’t accidentally expose a query shape you can’t support at scale.
  • Return the valid parameters in your error responses. When someone passes a bad parameter, telling them what the good ones are turns a frustrating dead end into a self-service fix.

Plan for iteration, because the corner cases are coming

No matter how carefully you design, customers will find the edges you didn’t. They’ll use the API in ways you didn’t imagine, and a few of those ways will be load-bearing for their business before you even notice. So design assuming iteration: leave room in your URI structure, your endpoints, and your tests for the cases you haven’t met yet. The first version is a hypothesis. Real usage is the experiment.

And keep the language consistent. A word should mean the same thing everywhere in the API. The moment “id” means three different things in three endpoints, you’ve added a tax that every consumer pays forever.

The takeaway

Good API design outlives any one language, framework, or implementation, because the contract is the part that sticks. Treat a public endpoint like the long-term commitment it is: design for the consumer, keep it predictable, leave room to grow, and remember that “we’ll just remove it later” is usually a promise you can’t keep. The afternoon you save by skipping the design is borrowed against years of everyone downstream paying it back.