Changelog and Deprecation — Communicating API Changes Clearly
In this tutorial, you will learn about Changelog and Deprecation. We cover key concepts, practical examples, and best practices to help you master this topic.
A changelog documents all notable changes to an API over time, including new features, improvements, bug fixes, deprecations, and breaking changes with Migration guidance.
In this tutorial, you will learn how to write clear changelogs, communicate deprecations effectively, implement deprecation headers, and manage API sunset processes.
What You'll Learn
You will learn changelog best practices, deprecation communication strategies, HTTP deprecation headers, sunset planning, and how to keep developers informed through the API lifecycle.
Why It Matters
Poorly communicated changes erode developer trust. Developers who discover breaking changes at runtime lose confidence in the API. Clear changelogs and deprecation notices show that you respect your developers time and integrations.
Real-World Use
DodaTech publishes a changelog with every API release. Deprecated features receive Deprecation and Sunset headers for 6 months before removal. A migration guide is published at least 3 months before breaking changes take effect.
flowchart LR A[API Change] --> B[Changelog Entry] B --> C[Deprecation Notice] C --> D[Migration Guide] D --> E[Sunset Date] E --> F[Version Removal] B:::current classDef current fill:#f90,color:#fff,stroke:#333,stroke-width:2px
Changelog Structure
Follow the Keep a Changelog convention:
# Changelog
## [2.1.0] - 2026-06-28
### Added
- Batch user creation endpoint POST /users/batch
- Full-text search on GET /users with `search` parameter
- Rate limit headers (X-RateLimit-Remaining, X-RateLimit-Reset)
### Changed
- Increased rate limit from 100 to 200 requests per minute
- Improved error messages for validation failures
### Deprecated
- GET /users?page_size is deprecated, use GET /users?limit instead
- X-Legacy-API-Version header deprecated, will be removed in v3
### Fixed
- Fixed incorrect total count in pagination responses
- Fixed memory leak in file upload endpoint
### Security
- Updated TLS minimum version to 1.3
- API keys now expire after 12 months by default
## [2.0.0] - 2026-03-15
### Breaking Changes
- Removed GET /api/v1/users (use GET /api/v2/users)
- Changed response format: `data.users` is now `data`
- Required fields now include `role` in user creation
Automating Changelogs
Generate changelogs from commit history:
# Generate changelog from conventional commits
git log --oneline --decorate v2.0.0..v2.1.0 \
| grep -E "^(feat|fix|docs|perf|refactor)" \
> changelog-pending.md
# Categorize by type
echo "## Added" >> CHANGELOG.md
git log --oneline --grep="^feat" v2.0.0..v2.1.0 >> CHANGELOG.md
echo "## Fixed" >> CHANGELOG.md
git log --oneline --grep="^fix" v2.0.0..v2.1.0 >> CHANGELOG.md
Deprecation Headers
Use HTTP headers to communicate deprecation in real time:
// Server-side deprecation headers
app.get("/api/v1/users", (req, res) => {
// Mark version 1 as deprecated
res.set("Deprecation", "true");
res.set("Sunset", "Sat, 31 Dec 2026 23:59:59 GMT");
res.set("Link", '</api/v2/users>; rel="successor-version"');
res.json({ data: usersV1 });
});
# OpenAPI deprecation annotation
paths:
/api/v1/users:
get:
deprecated: true
description: |
Deprecated: Use /api/v2/users instead.
This endpoint will be removed on December 31, 2026.
See the [migration guide](/docs/migration-v1-to-v2) for details.
Sunset Planning
Create a sunset timeline for each deprecated version:
const sunsetSchedule = {
v1: {
deprecationDate: "2026-06-28",
sunsetDate: "2026-12-31",
status: "deprecated",
migrationGuide: "/docs/migration-v1-to-v2",
breakingChanges: [
"Response format changed from camelCase to snake_case",
"Authentication now requires Bearer token instead of API key",
"File upload endpoint moved from POST /files to POST /files/upload"
]
}
};
// Log deprecation warnings for analytics
function logDeprecationUsage(req, version) {
console.warn(
`Deprecated API version ${version} used by client ${req.ip}`
);
// Send to analytics
analytics.track("api.deprecation", {
version,
clientIp: req.ip,
userAgent: req.headers["user-agent"],
endpoint: req.path,
timestamp: new Date().toISOString()
});
}
Migration Guides
Write a migration guide for every breaking change:
# Migrating from API v1 to v2
## Summary
This guide helps you migrate from API v1 to v2 before December 31, 2026.
## Key Changes
### 1. Base URL
- Old: https://api.dodatech.com/v1/
- New: https://api.dodatech.com/v2/
### 2. Authentication
Old: X-API-Key header
New: Authorization: Bearer <token>
### 3. Response Format
Old: { "data": { "users": [...] } }
New: { "data": [...] }
### 4. Pagination
Old: { "page": 1, "per_page": 20 }
New: { "page": 1, "limit": 20 }
## Timeline
- Now: v2 available alongside v1
- October 2026: v1 enters maintenance mode
- December 31, 2026: v1 sunset (no longer available)
## Code Migration Example
Before (v1):
```python
response = requests.get(
"https://api.dodatech.com/v1/users",
headers={"X-API-Key": API_KEY}
)
data = response.json()["data"]["users"]
After (v2):
response = requests.get(
"https://api.dodatech.com/v2/users",
headers={"Authorization": f"Bearer {TOKEN}"}
)
data = response.json()["data"]
## Common Mistakes
1. **No notice before breaking changes** — Removing features without warning. Provide at least 6 months notice before breaking changes. Use Deprecation and Sunset headers.
2. **Burying deprecation notices** — Hiding deprecation information in changelogs that nobody reads. Add visible banners to deprecated endpoint documentation.
3. **No migration guide** — Telling developers an endpoint is deprecated but not showing them the replacement. Every deprecation needs a migration path.
4. **Inconsistent changelog format** — Changing the changelog format between releases. Follow a standard format like Keep a Changelog.
5. **No sunset date** — Deprecating features without specifying when they will be removed. Every deprecated feature needs a clear sunset date.
## Practice Questions
1. What sections should a changelog include?
2. What HTTP headers communicate deprecation to clients?
3. How much notice should you give before removing a deprecated feature?
4. What should a migration guide include?
5. How do you automate changelog generation?
## Challenge
Create a complete deprecation plan for an API that is migrating from API key to OAuth2 authentication. Write the deprecation notice, implement Deprecation and Sunset headers, create a migration guide with before/after code examples in three languages, and set a realistic sunset timeline with milestones.
## FAQ
<details style="margin-bottom:12px;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden"><summary style="cursor:pointer;padding:14px 18px;font-weight:600;font-size:1.05rem;background:#f8fafc;border-bottom:1px solid #e2e8f0;color:#1e293b">How often should I publish a changelog?</summary><div style="padding:14px 18px;color:#475569;line-height:1.7;background:#fff"><p>Publish a changelog with every release, even if there are no user-facing changes. Note maintenance updates as internal changes only.</p>
</div></details><details style="margin-bottom:12px;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden"><summary style="cursor:pointer;padding:14px 18px;font-weight:600;font-size:1.05rem;background:#f8fafc;border-bottom:1px solid #e2e8f0;color:#1e293b">Should I include internal changes in the changelog?</summary><div style="padding:14px 18px;color:#475569;line-height:1.7;background:#fff"><p>Include only changes that affect API consumers. Internal Refactoring, database changes, and infrastructure updates belong in internal release notes.</p>
</div></details><details style="margin-bottom:12px;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden"><summary style="cursor:pointer;padding:14px 18px;font-weight:600;font-size:1.05rem;background:#f8fafc;border-bottom:1px solid #e2e8f0;color:#1e293b">How do I handle emergency breaking changes?</summary><div style="padding:14px 18px;color:#475569;line-height:1.7;background:#fff"><p>Emergency breaking changes should be extremely rare. When necessary, communicate immediately through the changelog, deprecation headers, and direct email to affected developers.</p>
</div></details><details style="margin-bottom:12px;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden"><summary style="cursor:pointer;padding:14px 18px;font-weight:600;font-size:1.05rem;background:#f8fafc;border-bottom:1px solid #e2e8f0;color:#1e293b">What is the difference between deprecated and sunset?</summary><div style="padding:14px 18px;color:#475569;line-height:1.7;background:#fff"><p>Deprecated means the feature still works but should not be used for new integrations. Sunset means the feature has been removed and no longer works.</p>
</div></details><details style="margin-bottom:12px;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden"><summary style="cursor:pointer;padding:14px 18px;font-weight:600;font-size:1.05rem;background:#f8fafc;border-bottom:1px solid #e2e8f0;color:#1e293b">Can I skip a version number in the changelog?</summary><div style="padding:14px 18px;color:#475569;line-height:1.7;background:#fff"><p>Version numbers should be sequential. If you skip a version (v1 to v3 without v2), justify it in the changelog.</p>
</div></details>
## Mini Project
Write a changelog for a hypothetical API that includes three releases: a minor release with new features and bug fixes, a major release with breaking changes and a migration guide, and a patch release with security fixes. Include deprecation notices, sunset dates, and links to migration guides.
## What's Next
In the next lesson, you will learn how to create an API style guide that ensures consistent documentation across your organization.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro