API versioning strategies that do not paint you in a corner
URL versions, header versions, or no versions — what we recommend for SMB APIs and how to evolve them without breaking clients.
The opinion up front
For a public-ish SMB API, put the version in the URL (/v1/...). For a private API consumed only by your own frontend, do not version at all — just evolve it.
Both answers are defensible. Below is the why.
URL versioning
/v1/orders,/v2/orders- Pros: trivial to route, easy to cache, obvious in logs and docs
- Cons: a "version bump" implies you ship two whole APIs in parallel for a while
- Used by: Stripe, GitHub, most of the API ecosystem
This is the safe default for any API consumed by third parties.
Header versioning
Accept: application/vnd.acme.v2+json- Pros: keeps URLs clean, more "RESTful"
- Cons: harder to debug from a browser, harder to cache, hostile to non-engineers reading the docs
- Used by: GitHub's GraphQL, a small set of API purists
We do not recommend it. The marginal cleanliness is not worth the operational pain.
No versioning (for private APIs)
If your frontend and backend deploy together, you do not need versioning. Add fields, deprecate them, remove them in a coordinated release.
This is the right answer for most internal SMB apps. Skipping versioning saves real engineering time.
Evolution rules
Whatever you pick, follow these rules to avoid needing a real version bump:
- Never rename a field. Add a new one and deprecate the old.
- Never change a field's type. Add a new field with the new type.
- Never remove a field on response. Mark it deprecated; remove in a real version bump.
- Adding optional request fields and response fields is always safe.
If you follow these rules, you can stay on v1 for years.
When to actually bump
- Auth model changes (OAuth to OIDC, etc.)
- Pagination model changes
- Response envelope changes
- Removal of fields that real clients use
When you do bump, run v1 and v2 in parallel for at least 6 months. Add deprecation headers to v1 with a sunset date. Communicate early.
What we tell clients
Do not bump versions casually. Every version you maintain is a tax. We have shipped APIs that lived on v1 for 5+ years by following the evolution rules. That is the goal.