API Versioning
Also Known As
REST API versioning
API version strategy
/v1/ API
header versioning
TL;DR
Strategies for evolving an API without breaking existing consumers — URI versioning, header versioning, and content negotiation.
Explanation
URI versioning (/v1/, /v2/) is the most visible and cache-friendly approach. Header versioning (Accept: application/vnd.api+json;version=2) keeps URLs clean but is harder to test in a browser. Content negotiation uses the Accept header's MIME type. Semantic versioning applied to APIs: breaking changes require a major version bump. Deprecation policy: announce deprecation, support both versions for a transition period, then remove. Never silently change a response field — add new fields alongside old ones.
Common Misconception
✗ Adding a field to an API response is non-breaking. Consumers that deserialise into typed objects may fail on unexpected fields. Always version even additive changes in strict environments.
Why It Matters
A breaking API change without versioning forces all consumers to update simultaneously — often impossible in a microservices or public API context. Versioning gives consumers time to migrate.
Common Mistakes
- Not versioning from day one — retrofitting versioning breaks all existing URL references.
- Deprecating a version without announcing a timeline and giving consumers adequate migration time.
- Using dates as version identifiers (2024-01-01) — hard to compare and communicate breaking vs non-breaking changes.
Avoid When
- Do not version internal APIs used by a single team — the overhead outweighs the benefit.
- Avoid creating a new version for every change — only major breaking changes warrant a new version.
When To Use
- Version your API from the first public release — never ship an unversioned public API.
- Use URI versioning for public APIs — it is explicit, cacheable, and easy to route.
Code Examples
✗ Vulnerable
// No versioning — any change breaks consumers
Route::get('/api/users', [UserController::class, 'index']);
// Removing a field or changing a response structure breaks all clients silently
✓ Fixed
// URI versioning — simple, explicit, cache-friendly
// routes/api.php
Route::prefix('v1')->group(function () {
Route::get('/users', [V1\UserController::class, 'index']);
});
Route::prefix('v2')->group(function () {
Route::get('/users', [V2\UserController::class, 'index']);
});
// Add deprecation header on old version
header('Deprecation: version="v1", sunset="2026-12-31"');
References
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
31 Mar 2026
Views
42
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 0
No pings yet today
No pings yesterday
Perplexity 9
Amazonbot 6
Unknown AI 3
SEMrush 3
Google 2
Ahrefs 2
Qwen 1
Also referenced
How they use it
crawler 24
crawler_json 1
pre-tracking 1
Related categories
⚡
DEV INTEL
Tools & Severity
⚙ Fix effort: Medium
⚡ Quick Fix
Add /v1/ prefix to all API routes from day one — retrofitting versioning after launch is significantly more painful
📦 Applies To
web
laravel
symfony
🔗 Prerequisites
🔍 Detection Hints
API routes without version prefix
Auto-detectable:
✗ No
⚠ Related Problems
🤖 AI Agent
Confidence: Low
False Positives: High
✗ Manual fix
Fix: High
Context: File
Tests: Regenerate