Version Lifetime and Sunset Policy — Managing API Version End-of-Life
DodaTech
Updated 2026-06-28
1 min read
In this tutorial, you'll learn about Sunset Policy. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
A sunset policy defines the lifecycle of each API version from release to retirement, ensuring consumers have clear timelines and expectations for version availability.
What You'll Learn
By the end of this lesson, you will define version lifecycle stages, implement sunset policies with timelines, automate consumer notification, enforce sunset dates, and handle emergency extensions.
| Stage | Description | Consumer Action |
|---|---|---|
| Preview | Early access, may change | Testing only |
| Stable | Fully supported | Production use |
| Deprecated | Will be removed | Plan Migration |
| Sunset | No longer available | Migrate immediately |
Version Lifecycle Manager
Track version lifecycle stages and enforce transitions.
from datetime import datetime, timedelta
from typing import Dict, Optional, List
from enum import Enum
class VersionStage(Enum):
PREVIEW = "preview"
STABLE = "stable"
DEPRECATED = "deprecated"
SUNSET = "sunset"
class VersionLifecycle:
def __init__(self, version_id: str):
self.version_id = version_id
self.stage = VersionStage.PREVIEW
self.release_date: Optional[datetime] = None
self.deprecation_date: Optional[datetime] = None
self.sunset_date: Optional[datetime] = None
def promote_to_stable(self):
self.stage = VersionStage.STABLE
self.release_date = datetime.utcnow()
def schedule_deprecation(self, days_from_now: int = 365):
self.deprecation_date = datetime.utcnow() + timedelta(days=days_from_now)
self.stage = VersionStage.DEPRECATED
def schedule_sunset(self, days_from_now: int = 180):
self.sunset_date = datetime.utcnow() + timedelta(days=days_from_now)
def days_remaining(self) -> int:
if self.sunset_date:
delta = self.sunset_date - datetime.utcnow()
return max(0, delta.days)
return -1
def status_summary(self) -> Dict:
return {
"version": self.version_id,
"stage": self.stage.value,
"release": self.release_date.isoformat() if self.release_date else None,
"deprecation": self.deprecation_date.isoformat() if self.deprecation_date else None,
"sunset": self.sunset_date.isoformat() if self.sunset_date else None,
"days_remaining": self.days_remaining(),
}
lifecycle = VersionLifecycle("v1")
lifecycle.promote_to_stable()
lifecycle.schedule_deprecation(365)
lifecycle.schedule_sunset(180)
print(lifecycle.status_summary())
Sunset Enforcement
Enforce sunset dates by blocking requests.
class SunsetEnforcer:
def __init__(self):
self.sunset_versions: Dict[str, datetime] = {}
self.grace_clients: set = set()
def schedule_sunset(self, version: str, sunset_date: datetime):
self.sunset_versions[version] = sunset_date
def add_grace_client(self, client_id: str):
self.grace_clients.add(client_id)
def check_request(self, version: str, client_id: str) -> bool:
sunset = self.sunset_versions.get(version)
if not sunset:
return True
if datetime.utcnow() < sunset:
return True
if client_id in self.grace_clients:
return True
return False
def enforce(self, version: str, client_id: str) -> Dict:
if self.check_request(version, client_id):
return {"allowed": True}
return {"allowed": False, "status": 410,
"body": {"error": "Version sunset",
"message": f"Version {version} is no longer available",
"upgrade_url": "/api/v2"}}
enforcer = SunsetEnforcer()
enforcer.schedule_sunset("v1", datetime(2026, 12, 31))
result = enforcer.enforce("v1", "partner-1")
print(f"Allowed: {result['allowed']}")
← Previous
Calendar Versioning (CalVer) for APIs — Date-Based Release Strategy
Next →
API Versioning Strategy Comparison — URI vs Header vs Content Negotiation
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro