API Versioning Strategies: URL vs Header vs Query Parameter

Every API that lives long enough will need to make breaking changes. How you version your API determines whether those changes are a smooth transition or a painful migration for your consumers. This guide compares the four major versioning strategies with real-world examples from APIs that have been managing versions at massive scale for years.

The Four Versioning Strategies

StrategyExampleUsed By
URL path/v1/users, /v2/usersTwilio, Slack, Google Maps
Custom headerX-GitHub-Api-Version: 2022-11-28GitHub
Date-based headerStripe-Version: 2024-12-18Stripe
Query parameter/users?version=2Google (some APIs), Amazon

URL Path Versioning

How It Works

The version is embedded directly in the URL path. When a breaking change is introduced, a new URL prefix is created:

# Version 1
GET https://api.twilio.com/2010-04-01/Accounts.json

# Google Maps
GET https://maps.googleapis.com/maps/api/geocode/v2/json

# Slack
POST https://slack.com/api/v2/chat.postMessage

Twilio's Approach

Twilio uses a date-based URL path (/2010-04-01/) that has remained stable for over 15 years. Rather than incrementing version numbers, Twilio chose to date-stamp the API at launch and has avoided breaking changes to this day. New functionality is added as new resources under the same version prefix.

Advantages

Disadvantages

Custom Header Versioning

How It Works

The version is specified in a request header, keeping URLs clean and stable:

# GitHub
GET https://api.github.com/repos/octocat/hello-world
X-GitHub-Api-Version: 2022-11-28

# Microsoft Graph
GET https://graph.microsoft.com/users/me
api-version: 1.0

GitHub's Approach

GitHub adopted calendar-based header versioning in late 2022. Each version is identified by a date (e.g., 2022-11-28). When GitHub makes a breaking change, they release a new dated version. The key design decisions:

# GitHub deprecation headers in responses
X-GitHub-Api-Version: 2022-11-28
Deprecation: true
Sunset: 2025-04-01
Link: <https://developer.github.com/changes/>; rel="deprecation"

Advantages

Disadvantages

Date-Based Header Versioning (Stripe's Model)

How It Works

Stripe pioneered what is arguably the most sophisticated API versioning system. Each API key is pinned to the version that was current when the key was created. Changes are then opt-in:

# Stripe pins your account to a version
# Override per-request with a header:
curl https://api.stripe.com/v1/charges \
  -H "Stripe-Version: 2024-12-18" \
  -H "Authorization: Bearer sk_test_..."

What Makes Stripe's Approach Unique

Stripe's secret: Internally, Stripe implements version compatibility as a chain of transformers. The latest code always runs, and response transformers convert the output to match whatever version the client expects. This means Stripe maintains one codebase, not N parallel versions.

Advantages

Disadvantages

Query Parameter Versioning

How It Works

The version is passed as a query parameter:

# Google Cloud APIs (some)
GET https://compute.googleapis.com/compute/v1/projects/my-project?alt=json

# AWS (service-specific)
GET https://ec2.amazonaws.com/?Action=DescribeInstances&Version=2016-11-15

Advantages

Disadvantages

Comparison Matrix

CriteriaURL PathHeaderStripe-styleQuery Param
ExplicitnessHighMediumMediumMedium
URL stabilityPoorExcellentExcellentGood
Cache friendlinessExcellentNeeds configNeeds configVariable
Implementation effortLowMediumVery highLow
Developer experienceGoodGoodExcellentAcceptable
Breaking change safetyLowMediumExcellentLow
API gateway supportUniversalGoodCustomGood

Practical Recommendations

For Most Teams: URL Path Versioning

If you are building an API and do not have the engineering bandwidth for a sophisticated versioning system, URL path versioning is the pragmatic choice. It is simple, explicit, universally understood, and supported by every tool and gateway. Use it with a commitment to minimize breaking changes and provide long deprecation periods.

For Platform APIs: Stripe-Style Date Versioning

If your API is a platform that thousands of developers depend on and you have the engineering resources, Stripe's model is the gold standard. The investment in version transformer infrastructure pays off through dramatically reduced support burden and happier developers who never wake up to broken integrations.

For Internal APIs: Header Versioning

For APIs consumed only by your own services, header versioning keeps URLs clean and gives you granular control. Since you control both client and server, the discoverability disadvantage is irrelevant.

Avoid: Query Parameter Versioning

Unless you have a specific technical reason (such as AWS-style API compatibility), query parameter versioning offers the worst trade-offs. It is neither as explicit as URL versioning nor as clean as header versioning.

The universal rule: Whichever strategy you choose, document it clearly, provide migration guides for every version change, and give developers at least 12 months of deprecation notice before removing any version. The versioning strategy matters far less than how you communicate changes.

The best API versioning strategy is the one your team can maintain consistently over years. Simple and well-communicated beats sophisticated and poorly managed every time.

Further Reading

Recommended books: