In short
The day you rename one JSON field, every old app on someone's phone can break. Versioning lets you change your API without pulling the rug from under existing users.
Strategies for evolving an API without breaking existing clients — URL versioning (`/v1/`), header versioning, or additive-only changes.

Think of it like this
Old edition, new edition
When a new textbook edition comes out, seniors keep studying from the old one until their exams end. Both editions exist side by side for a while. API versions work the same: /v1 keeps working while new clients move to /v2.
Watch it happen
Two app versions, one API
GET /v1/users/7
1/5An old app version, still installed on someone's phone, calls v1.
The big ideas
What you need to know
Adding is free, changing is not
A new field or a new endpoint breaks nobody. Removing, renaming or retyping a field does.
URL versioning is simplest
/v1/orders is easy to spot in logs, test in a browser and route in a gateway. Most teams start here.
Header versioning is tidier
Some APIs read a header like Accept: application/vnd.myapp.v2+json. Clean URLs, but harder to test by hand.
Retire versions on a schedule
Announce a sunset date, watch who still calls v1, then switch it off. Never surprise people.
See it in code
Walk through the code
1import express from "express";2const app = express();3 4const v1 = express.Router();5v1.get("/users/:id", async (req, res) => {6 const u = await db.users.find(req.params.id);7 res.json({ id: u.id, name: `${u.firstName} ${u.lastName}` });8});9 10const v2 = express.Router();11v2.get("/users/:id", async (req, res) => {12 const u = await db.users.find(req.params.id);13 res.json({ id: u.id, firstName: u.firstName, lastName: u.lastName });14});15 16app.use("/v1", v1).use("/v2", v2);1/3v1 keeps the old shape: one combined name string. Old apps never notice a thing.
Same database, two response shapes. Once v1 traffic drops to zero in your logs, you can delete the v1 router.
Save yourself the pain
Common mistakes
Oops
Renaming a field in place because the frontend team will update anyway.
Do this instead
Old mobile app versions stay installed for months. Add the new field, keep the old one, or ship a new version.
Oops
Creating /v2, /v3, /v4 for every small change.
Do this instead
Only bump the version for breaking changes. New optional fields and new endpoints can go into the current version.
Your mission
Ship a v2 without breaking v1
Quick check
Which change can safely go into the current API version?
Go deeper
- 1Compare URL-based versioning vs header-based versioning trade-offs.
- 2Design how you'd introduce a breaking change to an endpoint without breaking existing clients.
- 3Learn why 'never remove a field, only add' is a common additive-versioning strategy.
More topics at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.