REST API Versioning Strategies
Compare URL, header, and content-type versioning for REST APIs. Learn when to bump versions and how to retire old ones without breaking clients.
What you'll learn
- ✓Why versioning matters
- ✓URL vs header vs media-type versioning
- ✓When to bump a version
- ✓Deprecation timelines
- ✓Tips for keeping multiple versions sane
Prerequisites
- •Comfortable building REST endpoints
What and Why
APIs change. Clients do not always change at the same pace. Versioning gives you a contract that lets both sides evolve. The goal is simple: avoid breaking existing clients while still being able to ship new features.
Mental Model
Three popular versioning styles dominate REST.
- URL versioning:
/v1/users,/v2/users. - Header versioning:
Accept-Version: 2or a customX-API-Version. - Media-type versioning:
Accept: application/vnd.acme.v2+json.
All three work. The right pick depends on your audience, tooling, and operational comfort.
URL: GET /v2/users/1
Header: GET /users/1
Accept-Version: 2
Media type: GET /users/1
Accept: application/vnd.acme.v2+json Hands-on Example
URL versioning in FastAPI.
from fastapi import FastAPI, APIRouter
app = FastAPI()
v1 = APIRouter(prefix="/v1")
v2 = APIRouter(prefix="/v2")
@v1.get("/users/{id}")
def get_user_v1(id: int):
return {"id": id, "name": "Ada"}
@v2.get("/users/{id}")
def get_user_v2(id: int):
# adds email field
return {"id": id, "name": "Ada", "email": "ada@x.io"}
app.include_router(v1)
app.include_router(v2)
Header versioning with a dependency.
from fastapi import Header, HTTPException
def api_version(x_api_version: str = Header("1")):
if x_api_version not in {"1", "2"}:
raise HTTPException(400, "Unsupported version")
return x_api_version
@app.get("/users/{id}")
def get_user(id: int, version: str = Depends(api_version)):
if version == "2":
return {"id": id, "name": "Ada", "email": "ada@x.io"}
return {"id": id, "name": "Ada"}
When to bump a version. Use semver-like rules.
- Additive changes (new optional field, new endpoint): no bump.
- Renamed or removed fields, changed types, or new required input: bump major.
- Behavior changes that break assumptions: bump major.
Most teams favor major-only versions in REST and never publish minor versions. New features arrive on the latest major.
Deprecate clearly. Return a Deprecation header and a Sunset header that tells clients when the version goes away.
HTTP/1.1 200 OK
Deprecation: true
Sunset: Wed, 31 Dec 2026 23:59:59 GMT
Link: <https://api.acme.com/v2/users/1>; rel="successor-version"
Common Pitfalls
- Versioning too often. Every change becomes a maintenance burden. Aim for stability.
- Forking the entire codebase per version. Use one code path with version-aware serializers.
- Removing v1 without warning. Clients you never knew existed will break. Use a sunset window of 6 to 12 months.
- Putting business logic in version-specific code. Versions should be a thin shell over a shared core.
Practical Tips
- Default to URL versioning if you have many third-party clients. It is the most cache and tooling friendly.
- Prefer header or media-type versioning when you control all clients and want clean URLs.
- Use response shapes per version with a single transformation layer. The service stays single-source-of-truth.
- Track usage of each version. Sunset is data-driven, not calendar-driven.
- Document the deprecation policy publicly. Predictability earns trust.
Wrap-up
Pick a versioning style that matches your clients and stick with it. Bump only when truly necessary, communicate deprecations long before they hit, and design your code so the shared logic lives in one place. With those habits, you can evolve the API for years without forcing painful migrations on the people who depend on it.
Related articles
- REST APIs REST API Pagination Patterns
Compare offset, cursor, and keyset pagination for REST APIs. Pick the right pattern for your data, scale, and client experience.
- REST APIs REST API Design Best Practices: A Practical Guide
Apply REST design best practices for resources, naming, status codes, pagination, and versioning to build clean, durable APIs.
- REST APIs REST API Error Handling Conventions
Design clear, consistent error responses for REST APIs using HTTP status codes, problem details, and error envelopes that clients can actually handle.
- REST APIs REST API HATEOAS Explained
Understand Hypermedia as the Engine of Application State, why most REST APIs skip it, and when adding hypermedia links actually pays off.