Why Version Your API?
APIs evolve. You need to add fields, remove endpoints, and change behavior. Without versioning, any change risks breaking existing clients. A good versioning strategy lets you evolve while maintaining backward compatibility.
Strategy 1: URL Path Versioning
Include the version in the URL path.
GET /v1/users/42
GET /v2/users/42
Pros:
- Most visible and intuitive
- Easy to route in load balancers and API gateways
- Simple to test (just change the URL)
- Cache-friendly (different URLs = different cache entries)
Cons:
- Pollutes the URL space
- Purists argue versions aren't part of the resource identity
- Client code must update URLs on version change
Used by: Stripe, GitHub, Google, Twitter
Strategy 2: Custom Header Versioning
Use a custom request header.
GET /users/42
Accept: application/vnd.myapi.v2+json
Or a simpler approach:
GET /users/42
X-API-Version: 2
Pros:
- Clean URLs
- Version is metadata, not part of the resource path
Cons:
- Harder to test (need to set headers, can't just paste a URL)
- Less discoverable
- May cause CDN/proxy caching issues (must add
Varyheader)
Used by: GitHub (Accept header), Azure
Strategy 3: Query Parameter
Pass the version as a query parameter.
GET /users/42?version=2
GET /users/42?api-version=2024-01-15
Pros:
- Easy to add without changing URL structure
- Simple default handling (omit param = latest version)
Cons:
- Mixes versioning with business query parameters
- Can be accidentally cached without version in cache key
Used by: Google Cloud, AWS
Date-Based Versioning
Instead of v1/v2, use dates:
Stripe-Version: 2024-06-20
This allows gradual, pinned evolution. Clients opt into new behavior by updating their version date. Stripe pioneered this approach.
Recommendation
For most APIs, URL path versioning (/v1/) is the best default. It's simple, visible, and well-understood. Use date-based versioning if you make frequent, incremental changes.