API Versioning
The Powerverse Platform API uses versioning to introduce new features while maintaining backward compatibility. This guide explains our versioning strategy and how to migrate between versions.
Versioning Strategy
We use URL path versioning for major versions and date-based headers for minor changes.
Current Version
| Version | Status | End of Life |
|---|---|---|
v1 | Current | - |
v2 | Beta | - |
Version in URL
# Version 1 (current)
https://platform.powerverse.com/v1/inventory-service/sites
# Version 2 (beta)
https://platform.powerverse.com/v2/inventory-service/sites
API Version Header
For fine-grained version control within a major version:
curl -X GET "https://platform.powerverse.com/v1/inventory-service/sites" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-API-Version: 2024-01-15"
Backward Compatibility
What We Consider Breaking
These changes require a new major version:
- ❌ Removing an endpoint
- ❌ Removing a required field from responses
- ❌ Changing field types
- ❌ Changing authentication methods
- ❌ Changing error response structure
What We Consider Non-Breaking
These changes may happen without a version bump:
- ✅ Adding new endpoints
- ✅ Adding optional request parameters
- ✅ Adding new fields to responses
- ✅ Adding new enum values
- ✅ Relaxing validation rules
- ✅ Adding new error codes
Defensive Coding
Handle unknown fields gracefully:
# ✅ Good: Ignore unknown fields
def parse_site(data):
return Site(
id=data['id'],
name=data['name'],
location=data.get('location') # Optional field
)
# ❌ Bad: Strict parsing that breaks on new fields
def parse_site(data):
if set(data.keys()) != {'id', 'name', 'location'}:
raise ValueError("Unexpected fields")
Version Lifecycle
┌─────────┐ ┌─────────┐ ┌────────────┐ ┌────────────┐
│ Beta │ -> │ Current │ -> │ Deprecated │ -> │ Sunset │
└─────────┘ └─────────┘ └────────────┘ └────────────┘
3-6 mo 24+ mo 12 mo Removed
Beta
- New features for testing
- May change based on feedback
- Not recommended for production
Current
- Stable and fully supported
- Bug fixes and security updates
- New non-breaking features added
Deprecated
- Still functional but discouraged
- No new features
- Security fixes only
- Migration warnings in responses
Sunset
- Version is removed
- Requests return
410 Gone
Deprecation Notices
In Response Headers
HTTP/1.1 200 OK
Deprecation: true
Sunset: Sat, 31 Dec 2025 23:59:59 GMT
Link: <https://platform.powerverse.com/v2/inventory-service/sites>; rel="successor-version"
In Response Body
{
"data": { ... },
"meta": {
"deprecation": {
"message": "This endpoint is deprecated",
"sunset_date": "2025-12-31",
"migration_guide": "https://docs.powerverse.com/migration/v1-to-v2"
}
}
}
Webhook Notifications
Subscribe to deprecation notifications:
curl -X POST "https://platform.powerverse.com/webhooks" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"url": "https://yourapp.com/webhooks",
"events": ["api.deprecation", "api.sunset_warning"]
}'
Migration Guide: v1 to v2
Breaking Changes in v2
| Change | v1 | v2 |
|---|---|---|
| Resource ID format | sit_abc123 / ast_abc123 | UUID 550e8400-e29b-... |
| Pagination | Offset-based | Cursor-based |
| Error format | { "error": "message" } | { "error": { "code": "...", "message": "..." } } |
| Date format | Unix timestamp | ISO 8601 |
Migrating Resource IDs
# v1 response
{"id": "sit_abc123", "name": "London Charging Hub"}
# v2 response
{"id": "550e8400-e29b-41d4-a716-446655440000", "name": "London Charging Hub"}
# Migration: Store both during transition
class Site:
def __init__(self, data, api_version):
if api_version == 'v1':
self.legacy_id = data['id']
self.id = None # Fetch from mapping
else:
self.id = data['id']
self.legacy_id = data.get('legacy_id')
Migrating Pagination
# v1: Offset-based
def fetch_all_v1(api):
page = 1
while True:
response = api.get('/v1/inventory-service/sites', params={'page': page})
yield from response['data']
if not response['pagination']['has_next']:
break
page += 1
# v2: Cursor-based
def fetch_all_v2(api):
cursor = None
while True:
params = {'cursor': cursor} if cursor else {}
response = api.get('/v2/inventory-service/sites', params=params)
yield from response['data']
if not response['pagination']['has_next']:
break
cursor = response['pagination']['next_cursor']
Migrating Error Handling
# v1 error handling
try:
response = api_v1.create_site(data)
except APIError as e:
message = e.response.json().get('error', 'Unknown error')
# v2 error handling
try:
response = api_v2.create_site(data)
except APIError as e:
error = e.response.json().get('error', {})
code = error.get('code')
message = error.get('message')
details = error.get('details')
Version Detection
Check API Version Support
curl -X GET "https://platform.powerverse.com/versions" \
-H "Authorization: Bearer YOUR_TOKEN"
{
"versions": [
{
"version": "v1",
"status": "current",
"released": "2023-01-01",
"sunset": null
},
{
"version": "v2",
"status": "beta",
"released": "2024-06-01",
"sunset": null
}
],
"current": "v1",
"latest": "v2"
}
Best Practices
1. Pin to a Specific Version
API_VERSION = 'v1'
BASE_URL = f'https://platform.powerverse.com/{API_VERSION}'
2. Monitor Deprecation Headers
function checkDeprecation(response) {
if (response.headers.get('Deprecation')) {
const sunset = response.headers.get('Sunset');
console.warn(`API deprecated! Sunset date: ${sunset}`);
// Alert your team
notifyTeam('API deprecation warning', { sunset });
}
}
3. Test Against Beta Versions
# CI/CD: Test against both versions
jobs:
test:
strategy:
matrix:
api_version: [v1, v2]
steps:
- run: npm test
env:
API_VERSION: ${{ matrix.api_version }}
4. Plan Migration Early
- Subscribe to deprecation webhooks
- Allocate time for migration in roadmap
- Test thoroughly before switching
Next Steps
- API Reference - Endpoint reference
- Getting Started - Setup and basics
- Error Handling - Handle version errors