API Design

API Versioning Strategies: URL, Header, and Query Param

How to version your API without breaking existing clients — comparing URL path, custom header, and query parameter approaches.

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 Vary header)

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.

Related Protocols

Related Glossary Terms

More in API Design