API Versioning Strategies: URL, Header, or Content Negotiation?
API Versioning Strategies: URL, Header, or Content Negotiation?
Versioning is unavoidable once an API has external consumers. Here are the four strategies in production use today.
1. URL versioning — /v1/users
Used by Twitter, Twilio, Slack, most public APIs.
✅ Easiest to discover, easiest to cache, easiest to log. ❌ Couples versions to routing; you cannot evolve a single endpoint independently.
2. Header versioning — Accept-Version: 2025-04-01
Used by GitHub (X-GitHub-Api-Version).
✅ Cleaner URLs, encourages thinking of the contract as the version. ❌ Harder to test in a browser, easy to forget, breaks naive caching.
3. Content negotiation — Accept: application/vnd.myapi.v2+json
Used by some HATEOAS purists.
✅ Aligned with HTTP semantics. ❌ Verbose, poor tooling support, almost no one writes clients that handle it correctly.
4. Date-based versioning — Stripe-Version: 2024-10-28
Used by Stripe, OpenAI, Plaid.
✅ Granular control over breaking changes; clients pin a date. ❌ Server must maintain transformations between adjacent versions.
Recommendations
- Public APIs with many partners → date-based versioning + sensible default.
- Internal microservices → header versioning + auto-generated clients.
- Public APIs with few endpoints → URL versioning is fine and simplest.
Universal rules
- Never break a published version. Add new versions; deprecate slowly.
- Document the deprecation timeline in
SunsetandDeprecationheaders (RFC 8594, RFC 9745). - Log version usage so you know who is on what.
- Provide a migration guide with diffs, not just changelogs.
Found this helpful? Try our free tools!
Explore Our Tools →