AgentSkillsCN

Deprecation Notices

全面梳理API弃用流程、停服时间表、沟通策略与平滑迁移路径

SKILL.md
--- frontmatter
name: Deprecation Notices
description: Comprehensive guide to API deprecation processes, sunset timelines, communication strategies, and graceful migration paths

Deprecation Notices

What is Deprecation?

Definition: Announcing end-of-life for an API/feature with time for users to migrate before eventual removal.

Lifecycle

code
Active → Deprecated → Sunset → Removed

Active: Fully supported
Deprecated: Still works, but discouraged (6-12 months)
Sunset: Stops working
Removed: Code deleted

Example

code
Jan 2024: API v1 active
Jun 2024: API v1 deprecated (announce v2)
Dec 2024: API v1 sunset (stops working)
Jan 2025: API v1 code removed

Why Proper Deprecation Matters

1. Avoid Breaking Users Without Warning

Bad:

code
Deploy new version
→ Old endpoint removed
→ Users break immediately
→ Angry customers
→ Emergency rollback

Good:

code
Announce deprecation (6 months notice)
→ Users migrate gradually
→ Sunset date arrives
→ No surprises

2. Maintain Trust

Trust Built By:

  • Advance notice (6-12 months)
  • Clear migration path
  • Support during migration
  • No surprises

Trust Broken By:

  • Sudden changes
  • No warning
  • Unclear migration
  • Breaking without notice

3. Smooth Migration

Gradual Migration:

code
Month 0: Announce deprecation
Month 3: 25% migrated
Month 6: 50% migrated
Month 9: 75% migrated
Month 12: 100% migrated, sunset

4. Legal Compliance (If Contractual)

Contracts May Require:

  • Minimum notice period (e.g., 12 months)
  • Migration support
  • No breaking changes without notice

Check Contracts Before Deprecating!


Deprecation Timeline

Typical: 6-12 Months for APIs

Timeline:

code
Month 0: Announce deprecation
Month 3: Reminder + usage stats
Month 6: Final warning
Month 9: Reach out to remaining users
Month 12: Sunset

Critical Systems: 12-24 Months

Examples:

  • Banking APIs
  • Healthcare systems
  • Government integrations

Why Longer:

  • Longer approval processes
  • More stakeholders
  • Higher risk

Internal APIs: 3-6 Months

Why Shorter:

  • Control both sides
  • Faster coordination
  • Lower risk

Consider: Contract Terms, User Base Size

Factors:

  • Contract terms: May require 12+ months
  • User base size: More users = longer timeline
  • Criticality: Mission-critical = longer timeline
  • Complexity: Complex migration = longer timeline

Deprecation Process

Step 1: Mark as Deprecated (Code, Docs)

Code (JavaScript):

javascript
/**
 * @deprecated Use getUser() instead. Will be removed in v2.0.0.
 * @see getUser
 */
function getUserProfile(id) {
  console.warn('getUserProfile is deprecated. Use getUser() instead.');
  return getUser(id);
}

Code (Python):

python
import warnings

def get_user_profile(id):
    """
    .. deprecated:: 1.5.0
       Use :func:`get_user` instead.
    """
    warnings.warn(
        "get_user_profile is deprecated. Use get_user() instead.",
        DeprecationWarning,
        stacklevel=2
    )
    return get_user(id)

Docs:

markdown
## GET /users/:id/profile

**⚠️ DEPRECATED:** This endpoint is deprecated and will be removed on December 31, 2024.

**Use instead:** `GET /users/:id`

**Migration guide:** https://docs.example.com/migration/profile-to-user

Step 2: Announce (Email, Blog, Changelog)

Email:

code
Subject: Deprecation Notice: /users/:id/profile endpoint

Hi developers,

We're deprecating the /users/:id/profile endpoint.

What's changing:
- Endpoint: GET /users/:id/profile
- Sunset date: December 31, 2024
- Replacement: GET /users/:id

Why:
- Consolidating user endpoints for simplicity
- New endpoint provides more data

Action required:
- Update your integration by December 31, 2024
- See migration guide: https://docs.example.com/migration

Need help?
- Reply to this email
- Join office hours: Fridays 2-3pm PT

Thank you,
API Team

Blog Post:

markdown
# Deprecation Notice: /users/:id/profile Endpoint

**Date:** June 1, 2024
**Sunset Date:** December 31, 2024

We're deprecating the `/users/:id/profile` endpoint in favor of the consolidated `/users/:id` endpoint.

## What's Changing
The `/users/:id/profile` endpoint will stop working on December 31, 2024.

## Why
We're consolidating user endpoints to simplify our API and provide a better developer experience.

## What to Use Instead
Use `GET /users/:id` instead. It returns the same data plus additional fields.

## Migration Guide
See our [migration guide](https://docs.example.com/migration) for step-by-step instructions.

## Timeline
- **June 1, 2024:** Deprecation announced
- **September 1, 2024:** Reminder email sent
- **December 1, 2024:** Final warning
- **December 31, 2024:** Endpoint stops working

## Need Help?
Contact us at api@example.com or join our office hours.

Changelog:

markdown
# Changelog

## v1.5.0 (2024-06-01)

### Deprecated
- **GET /users/:id/profile** - Use GET /users/:id instead. Will be removed on 2024-12-31.

### Added
- **GET /users/:id** - New consolidated user endpoint

Step 3: Monitor Usage

Track Metrics:

javascript
app.get('/users/:id/profile', (req, res) => {
  // Track usage
  metrics.increment('deprecated.users_profile.calls', {
    client: req.headers['user-agent'],
    clientId: req.user?.clientId
  });
  
  // Return response
  res.json(profile);
});

Dashboard:

code
Deprecated Endpoint: /users/:id/profile
Sunset Date: 2024-12-31 (6 months remaining)

Usage:
- Total calls/day: 1,000 (down from 5,000 last month)
- Unique clients: 50 (down from 200)

Top Clients:
1. mobile-app: 500 calls/day
2. web-app: 300 calls/day
3. partner-api: 200 calls/day

Trend: ↓ Declining (good!)

Step 4: Reach Out to Active Users

Email Top Users:

code
Subject: Action Required: Migrate from /users/:id/profile

Hi [Client],

We noticed you're still using the deprecated /users/:id/profile endpoint (500 calls/day).

This endpoint will stop working on December 31, 2024 (3 months remaining).

Action required:
- Migrate to GET /users/:id
- See migration guide: https://docs.example.com/migration

Need help?
- Reply to this email
- Schedule a call: https://calendly.com/api-team

Thank you,
API Team

Step 5: Sunset (Stop Working)

Return 410 Gone:

javascript
app.get('/users/:id/profile', (req, res) => {
  res.status(410).json({
    error: 'This endpoint has been removed',
    message: 'GET /users/:id/profile was removed on 2024-12-31',
    replacement: 'Use GET /users/:id instead',
    migrationGuide: 'https://docs.example.com/migration'
  });
});

Step 6: Remove Code

After Sunset:

code
1. Sunset date reached (Dec 31, 2024)
2. Monitor for errors (1 month)
3. If no issues, remove code (Jan 31, 2025)

Deprecation Headers (HTTP)

Deprecation: true (Draft RFC)

Header:

code
HTTP/1.1 200 OK
Deprecation: true

Spec: https://datatracker.ietf.org/doc/html/draft-dalal-deprecation-header

Sunset: Date (RFC 8594)

Header:

code
HTTP/1.1 200 OK
Sunset: Sat, 31 Dec 2024 23:59:59 GMT

Spec: https://datatracker.ietf.org/doc/html/rfc8594

Link: Migration Guide

Header:

code
HTTP/1.1 200 OK
Link: <https://docs.example.com/migration>; rel="sunset"

Warning: Message (RFC 7234)

Header:

code
HTTP/1.1 200 OK
Warning: 299 - "This endpoint is deprecated. Use /v2/users instead. See https://docs.example.com/migration"

All Together

Example:

code
HTTP/1.1 200 OK
Deprecation: true
Sunset: Sat, 31 Dec 2024 23:59:59 GMT
Link: <https://docs.example.com/migration>; rel="sunset"
Warning: 299 - "This endpoint is deprecated and will be removed on 2024-12-31. Use /v2/users instead."
Content-Type: application/json

{
  "id": "123",
  "name": "John Doe"
}

Middleware (Express):

javascript
function deprecationHeaders(sunsetDate, migrationUrl, message) {
  return (req, res, next) => {
    res.set('Deprecation', 'true');
    res.set('Sunset', sunsetDate);
    res.set('Link', `<${migrationUrl}>; rel="sunset"`);
    res.set('Warning', `299 - "${message}"`);
    next();
  };
}

app.get('/users/:id/profile',
  deprecationHeaders(
    'Sat, 31 Dec 2024 23:59:59 GMT',
    'https://docs.example.com/migration',
    'This endpoint is deprecated. Use /v2/users instead.'
  ),
  (req, res) => {
    res.json(profile);
  }
);

OpenAPI Deprecation

deprecated: true

Example:

yaml
paths:
  /users/{id}/profile:
    get:
      deprecated: true
      summary: Get user profile (DEPRECATED)
      description: |
        **DEPRECATED:** This endpoint is deprecated and will be removed on 2024-12-31.
        
        **Use instead:** GET /users/{id}
        
        **Migration guide:** https://docs.example.com/migration
      responses:
        '200':
          description: User profile

Swagger UI:

code
GET /users/{id}/profile (DEPRECATED)

⚠️ Deprecated
This endpoint is deprecated and will be removed on 2024-12-31.
Use GET /users/{id} instead.

GraphQL Deprecation

@deprecated Directive

Example:

graphql
type User {
  id: ID!
  name: String! @deprecated(reason: "Use firstName and lastName instead")
  firstName: String!
  lastName: String!
}

Query:

graphql
{
  user(id: "123") {
    id
    name  # Warning: Field 'name' is deprecated. Use firstName and lastName instead.
  }
}

Code Deprecation

@deprecated Annotation (Java)

java
/**
 * @deprecated Use getUser() instead. Will be removed in v2.0.0.
 */
@Deprecated
public User getUserProfile(String id) {
    return getUser(id);
}

@deprecated JSDoc (JavaScript)

javascript
/**
 * @deprecated Use getUser() instead. Will be removed in v2.0.0.
 * @see getUser
 */
function getUserProfile(id) {
  console.warn('getUserProfile is deprecated');
  return getUser(id);
}

warnings.warn (Python)

python
import warnings

def get_user_profile(id):
    warnings.warn(
        "get_user_profile is deprecated. Use get_user() instead.",
        DeprecationWarning,
        stacklevel=2
    )
    return get_user(id)

Communication Channels

In-App Notifications (For Logged-In Users)

Example:

code
Banner:
⚠️ You're using a deprecated API endpoint (/users/:id/profile).
It will stop working on Dec 31, 2024.
[Migrate Now] [Learn More]

Email Campaigns (To All API Users)

See "Step 2: Announce" above

Blog Post (Public Announcement)

See "Step 2: Announce" above

Changelog (Detailed Info)

See "Step 2: Announce" above

Status Page Updates

Example:

code
Status: Scheduled Maintenance

API v1 Sunset
Date: December 31, 2024
Impact: API v1 endpoints will stop working
Action: Migrate to API v2
Guide: https://docs.example.com/migration

Release Notes

Example:

code
# Release Notes - v1.5.0

## Deprecations
- GET /users/:id/profile (sunset: 2024-12-31)
  - Use: GET /users/:id
  - Guide: https://docs.example.com/migration

Migration Guide

Why Deprecating (Reason)

Example:

markdown
## Why We're Deprecating /users/:id/profile

We're consolidating user endpoints to:
1. Simplify our API (fewer endpoints to learn)
2. Improve performance (single endpoint, less overhead)
3. Provide more data (new endpoint returns additional fields)

What to Use Instead (Alternative)

Example:

markdown
## What to Use Instead

Use `GET /users/:id` instead of `GET /users/:id/profile`.

The new endpoint returns all profile data plus additional fields.

How to Migrate (Step-by-Step)

Example:

markdown
## How to Migrate

### Step 1: Update API Call

**Before:**
```javascript
const profile = await fetch('/api/users/123/profile');

After:

javascript
const user = await fetch('/api/users/123');

Step 2: Update Response Handling

Before:

javascript
const { bio, avatar, location } = profile;

After:

javascript
const { bio, avatar, location } = user;
// Same fields, no changes needed

Step 3: Test

Test your integration in staging before deploying to production.

Step 4: Deploy

Deploy your changes before December 31, 2024.

code

### Code Examples (Before/After)

See above

### Timeline (When It Stops Working)

**Example:**
```markdown
## Timeline

- **June 1, 2024:** Deprecation announced
- **September 1, 2024:** Reminder email
- **December 1, 2024:** Final warning
- **December 31, 2024:** Endpoint stops working (410 Gone)

Support Contact (If Help Needed)

Example:

markdown
## Need Help?

- **Email:** api@example.com
- **Office Hours:** Fridays 2-3pm PT (https://meet.google.com/xxx)
- **Slack:** #api-support
- **Schedule Call:** https://calendly.com/api-team

Monitoring Deprecated Usage

Track API Calls to Deprecated Endpoints

See "Step 3: Monitor Usage" above

Identify Top Users

Query:

sql
SELECT
  client_id,
  COUNT(*) as call_count
FROM api_logs
WHERE endpoint = '/users/:id/profile'
  AND date >= CURRENT_DATE - INTERVAL '7 days'
GROUP BY client_id
ORDER BY call_count DESC
LIMIT 10;

Usage Trends (Is It Declining?)

Chart:

code
Calls/Day to /users/:id/profile

5000 |     ●
4000 |   ●
3000 | ●
2000 |       ●
1000 |         ●
   0 |___________●___
     Jun Jul Aug Sep Oct Nov

Trend: ↓ Declining (good!)

Alert When Usage Spikes

Alert:

code
Alert: Deprecated endpoint usage spike
Endpoint: /users/:id/profile
Current: 5,000 calls/day
Previous: 1,000 calls/day
Change: +400%

Action: Investigate (new client using deprecated endpoint?)

Outreach to Users

Email Top Users (Direct Outreach)

See "Step 4: Reach Out to Active Users" above

Offer Migration Support

Email:

code
Need help migrating?

We offer:
- 1-on-1 migration support calls
- Code review of your migration
- Extended sunset date (if needed)

Schedule a call: https://calendly.com/api-team

Schedule Calls with Major Customers

Process:

code
1. Identify major customers (high usage)
2. Email to schedule call
3. Call: Explain deprecation, offer help
4. Follow up: Check migration progress

Provide Early Access to New Version

Email:

code
Early Access: API v2

As a valued customer, we're offering early access to API v2.

Benefits:
- Test v2 before v1 sunset
- Provide feedback
- Smooth migration

Sign up: https://example.com/v2-early-access

Handling Non-Compliant Users

Repeated Notices

Timeline:

code
Month 0: Initial announcement
Month 3: Reminder email
Month 6: Second reminder
Month 9: Final warning
Month 11: Last chance email
Month 12: Sunset

Escalation (Account Manager)

Process:

code
1. Email from API team (no response)
2. Email from account manager
3. Phone call from account manager
4. Executive escalation (if major customer)

Final Warning (1 Month Before)

Email:

code
Subject: URGENT: Action Required - API v1 Sunset in 30 Days

Hi [Client],

This is a final warning that API v1 will stop working in 30 days (December 31, 2024).

We noticed you're still using:
- GET /users/:id/profile (500 calls/day)

Action required:
- Migrate to GET /users/:id immediately
- See migration guide: https://docs.example.com/migration

If you don't migrate, your integration will break on December 31.

Need help? Reply to this email ASAP.

Thank you,
API Team

Hard Cutoff (Stop Working)

Process:

code
1. Sunset date reached
2. Return 410 Gone
3. Monitor for errors
4. Reach out to affected users

Graceful Degradation

Return 410 Gone (After Sunset)

See "Step 5: Sunset" above

Helpful Error Message (Link to Guide)

Example:

json
HTTP/1.1 410 Gone
Content-Type: application/json

{
  "error": "Endpoint Removed",
  "message": "GET /users/:id/profile was removed on 2024-12-31",
  "sunsetDate": "2024-12-31",
  "replacement": {
    "endpoint": "GET /users/:id",
    "documentation": "https://docs.example.com/api/users"
  },
  "migrationGuide": "https://docs.example.com/migration/profile-to-user",
  "support": "api@example.com"
}

Optional: Temporary Disable (Test Waters)

Process:

code
1. Disable endpoint for 1 hour
2. Monitor errors
3. Identify affected users
4. Reach out
5. Re-enable
6. Give more time to migrate

Versioning and Deprecation

v1 Deprecated → Use v2

Timeline:

code
2024-06: Launch v2
2024-06: Deprecate v1 (12 month notice)
2025-06: Sunset v1

Maintain v1 During Transition

Support:

code
v2: Active development
v1: Maintenance mode (bug fixes only, no new features)

Eventually Remove v1

Process:

code
1. Sunset v1 (stop working)
2. Monitor for 1 month
3. Remove v1 code
4. Celebrate! 🎉

Database Schema Deprecation

Multi-Step Migration

See Backward Compatibility Rules skill

Stop Writing to Old Column

Step 1:

sql
-- Stop writing to 'name' column
-- Write to 'full_name' instead

Stop Reading (Use New Column)

Step 2:

sql
-- Stop reading from 'name' column
-- Read from 'full_name' instead

Drop Old Column

Step 3:

sql
-- After all code migrated
ALTER TABLE users DROP COLUMN name;

Feature Flag Deprecation

Mark Feature as Deprecated

Code:

javascript
if (featureFlags.isEnabled('old-feature')) {
  console.warn('old-feature flag is deprecated. Will be removed in v2.0.0.');
  // Old feature code
}

Monitor Usage

Dashboard:

code
Feature Flag: old-feature
Status: Deprecated
Sunset: 2024-12-31

Usage:
- Enabled for 10 users (down from 100)
- Last enabled: 2024-11-15

Reach Out to Enabled Users

Email:

code
Subject: Feature Flag Deprecation: old-feature

Hi,

We noticed you have the 'old-feature' flag enabled.

This feature is deprecated and will be removed on 2024-12-31.

Action: Disable 'old-feature' flag and use 'new-feature' instead.

Need help? Reply to this email.

Force Disable

Process:

code
1. Sunset date reached
2. Force disable flag for all users
3. Monitor for errors
4. Remove feature code

Remove Code

After Sunset:

javascript
// Remove old feature code
// Remove feature flag

Real Deprecation Examples

Twitter API v1 → v2

Timeline:

  • 2020: v2 launched
  • 2021: v1.1 deprecated
  • 2023: v1.1 sunset (3 years notice!)

Communication:

  • Blog posts
  • Email campaigns
  • Developer forums
  • Migration guides

GitHub API v3 Deprecations

Process:

  • Announce deprecation in changelog
  • Add deprecation headers
  • Provide migration guide
  • 12+ months notice
  • Sunset

Heroku Free Tier Sunset

Timeline:

  • Aug 2022: Announced
  • Nov 2022: Sunset (3 months notice)

Controversy:

  • Short notice (3 months)
  • No free alternative
  • Many affected users

Lesson: Give more notice for major changes


Templates

Deprecation Announcement (Email)

See "Step 2: Announce" above

Deprecation Announcement (Blog)

See "Step 2: Announce" above

Migration Guide

See "Migration Guide" section above

API Response Headers

See "Deprecation Headers" section above


Summary

Quick Reference

Deprecation: Announcing end-of-life with time to migrate

Timeline:

  • APIs: 6-12 months
  • Critical systems: 12-24 months
  • Internal APIs: 3-6 months

Process:

  1. Mark as deprecated (code, docs)
  2. Announce (email, blog, changelog)
  3. Monitor usage
  4. Reach out to active users
  5. Sunset (stop working)
  6. Remove code

Headers:

  • Deprecation: true
  • Sunset: Date
  • Link: Migration guide
  • Warning: Message

OpenAPI:

yaml
deprecated: true
description: Migration guide

GraphQL:

graphql
@deprecated(reason: "Use X instead")

Communication:

  • In-app notifications
  • Email campaigns
  • Blog post
  • Changelog
  • Status page
  • Release notes

Migration Guide:

  • Why deprecating
  • What to use instead
  • How to migrate (step-by-step)
  • Code examples (before/after)
  • Timeline
  • Support contact

Monitoring:

  • Track usage
  • Identify top users
  • Usage trends
  • Alert on spikes

Outreach:

  • Email top users
  • Offer migration support
  • Schedule calls
  • Early access to new version

Non-Compliant:

  • Repeated notices
  • Escalation
  • Final warning
  • Hard cutoff

Graceful Degradation:

  • 410 Gone
  • Helpful error message
  • Link to migration guide

Versioning:

  • v1 deprecated → v2
  • Maintain v1 during transition
  • Eventually remove v1

Overview

Deprecation Notices is the practice of announcing end-of-life for an API/feature with time for users to migrate before eventual removal.

Lifecycle

code
Active → Deprecated → Sunset → Removed
Month 0:  Fully supported
Month 3: Deprecated (6-12 months notice)
Month 6: Final warning
Month 12: Sunset (stops working)

Example

code
Jan 2024: API v1 active
Jun 2024: API v1 deprecated (announce v2)
Dec 2024: API v1 sunset (stops working)
Jan 2025: API v1 code removed

Why Proper Deprecation Matters

1. Avoid Breaking Users Without Warning

Without Deprecation:

code
Deploy new version
→ All clients break immediately
→ Emergency rollback
→ Coordinate with all clients to update
→ Big bang migration (risky!)

With Deprecation:

code
Deploy new version
→ Old clients continue working
→ Clients migrate gradually
→ No coordination needed

2. Maintain Trust

Trust Built By:

  • Advance notice (6-12 months)
  • Clear migration path
  • Support during migration
  • No surprises

Trust Broken By:

  • Sudden changes
  • No warning
  • Unclear migration
  • Breaking without notice
code

### 3. Smooth Migration

**Gradual Migration:**

Month 0: Deploy v2 (backward compatible) Month 1: 20% of clients migrated Month 3: 50% of clients migrated Month 6: 80% of clients migrated Month 12: 100% migrated, deprecate v1

code

### 4. Reduce Coordination Overhead

**Without:**
- Coordinate deployment with all clients
- Schedule maintenance window
- Rollback plan if issues

**With:**
- Deploy anytime
- Clients migrate when ready
- No coordination needed

5. Customer Trust (Stable APIs)

Trust:

  • "This API won't break my integration"
  • "I can upgrade when I'm ready"
  • "No surprises"

Deprecation Timeline

Typical: 6-12 Months for APIs

Timeline:

code
Month 0: Announce deprecation
Month 3: Reminder + usage stats
Month 6: Final warning
Month 12: Sunset

Critical Systems: 12-24 Months

Examples:

  • Banking APIs
  • Healthcare systems
  • Government integrations

Why Longer:

  • Longer approval processes
  • More stakeholders
  • Higher risk

Internal APIs: 3-6 Months

Why Shorter:

  • Control both sides
  • Faster coordination
  • Lower risk

Factors:

  • Contract terms: May require 12+ months
  • User base size: More users = longer timeline
  • Criticality: Mission-critical = longer timeline
  • Complexity: Complex migration = longer timeline

Deprecation Process

Step 1: Mark as Deprecated (Code, Docs)

Code (JavaScript):

javascript
/**
 * @deprecated Use getUser() instead. Will be removed in v2.0.0.
 * @see getUser
 */
function getUserProfile(id) {
  console.warn('getUserProfile is deprecated. Use getUser() instead.');
  return getUser(id);
}

Code (Python):

python
import warnings

def get_user_profile(id):
    """
    .. deprecated:: 1.5.0
       Use :func:`get_user` instead.
    """
    warnings.warn(
        "get_user_profile is deprecated. Use get_user() instead.",
        DeprecationWarning,
        stacklevel=2
    )
    return get_user(id)

Docs:

markdown
## GET /users/:id/profile

**⚠️ DEPRECATED:** This endpoint is deprecated and will be removed on December 31, 2024.

**Use instead:** `GET /users/:id`

**Migration guide:** https://docs.example.com/migration

Step 2: Announce (Email, Blog, Changelog)

Email:

code
Subject: Deprecation Notice: /users/:id/profile endpoint

Hi developers,

We're deprecating the `/users/:id/profile` endpoint.

What's changing:
- Endpoint: GET /users/:id/profile
- Sunset date: December 31, 2024

Why:
- Consolidating user endpoints for simplicity
- New endpoint provides more data

Action required:
- Update your integration by December 31, 2024
- See migration guide: https://docs.example.com/migration

Need help?
- Reply to this email
- Schedule a call: https://calendly.com/api-team

Thank you,
API Team

Blog Post:

markdown
# Deprecation Notice: /users/:id/profile Endpoint

**Date:** June 1, 2024

**Sunset Date:** December 31, 2024

We're deprecating the `/users/:id/profile` endpoint in favor of the consolidated `/users/:id` endpoint.

What's Changing
The `/users/:id/profile` endpoint will stop working on December 31, 2024.

Why
Consolidating user endpoints to simplify our API and provide a better developer experience.
The new endpoint returns all profile data plus additional fields.

Migration Guide
See our [migration guide](https://docs.example.com/migration) for step-by-step instructions.

Step 3: Monitor Usage

Track Deprecated Endpoint Usage:

javascript
app.get('/users/:id/profile', (req, res) => {
  // Track usage
  metrics.increment('deprecated.users_profile.calls', {
    client: req.headers['user-agent'],
    clientId: req.user?.clientId
  });

  // Return response with deprecation headers
  res.set('Deprecation', 'true');
  res.set('Sunset', 'Sat, 31 Dec 2024 23:59:59 GMT');
  res.set('Link', '<https://docs.example.com/migration>; rel="deprecation"');
  res.set('Warning', '299 - "This endpoint is deprecated. Use /users/:id instead. See https://docs.example.com/migration"');
  res.json(profile);
});

Dashboard:

code
Deprecated Endpoint: /users/:id/profile
Sunset Date: 2024-12-31 (6 months remaining)
Usage:
- Total calls/day: 1,000 (down from 5,000 last month)
- Top clients: mobile-app (500), web-app (300), partner-api (200)

Deprecation Headers

Sunset Header (RFC 8594):

code
HTTP/1.1 200 OK
Sunset: Sat, 31 Dec 2024 23:59:59 GMT
Link: <https://docs.example.com/migration>; rel="sunset"

Deprecation Header:

code
HTTP/1.1 200 OK
Deprecation: true
Link: <https://docs.example.com/migration>; rel="deprecation"

Warning Header:

code
HTTP/1.1 200 OK
Warning: 299 - "This endpoint is deprecated. Use /v2/users instead. See https://docs.example.com/migration"

Deprecation Policy (6-12 Months Notice)

Timeline:

code
Month 0: Announce deprecation
Month 3: Reminder + usage stats
Month 6: Final warning
Month 12: Sunset

OpenAPI Deprecation

deprecated: true

yaml
paths:
  /users/{id}/profile:
    get:
      deprecated: true
      summary: Get user profile (DEPRECATED)
      description: |
        **DEPRECATED:** This endpoint is deprecated and will be removed on 2024-12-31.
        
        **Use instead:** GET /users/{id}
code

---

## GraphQL Deprecation

**@deprecated Directive:**
```graphql
type User {
  id: ID!
  name: String! @deprecated(reason: "Use firstName and lastName instead")
  firstName: String!
  lastName: String!
}

Code Deprecation

@deprecated Annotation (Java):

java
/**
 * @deprecated Use getUser() instead. Will be removed in v2.0.0.
 * @see getUser
 */
@Deprecated
public User getUserProfile(String id) {
    return getUser(id);
}

@deprecated JSDoc (JavaScript):

javascript
/**
 * @deprecated Use getUser() instead. Will be removed in v2.0.0.
 * @see getUser
 */
/**
 * @deprecated Use getUser() instead. Will be removed in v2.0.0.
 */
function getUserProfile(id) {
  console.warn('getUserProfile is deprecated. Use getUser() instead.');
  return getUser(id);
}

warnings.warn (Python):

python
import warnings

def get_user_profile(id):
    """
    .. deprecated:: 1.5.0
       Use :func:`get_user` instead.
    """
    warnings.warn(
        "get_user_profile is deprecated. Use get_user() instead.",
        DeprecationWarning,
        stacklevel=2
    )
    return get_user(id)

Monitoring Deprecated Usage

Track Metrics:

  • Total calls/day
  • Unique clients
  • Top clients
  • Trend (declining = good!)

Reach Out to Active Users

Email Top Users:

code
Subject: Action Required: Migrate from /users/:id/profile

Hi [Client],

We noticed you're still using the deprecated /users/:id/profile endpoint (500 calls/day).

This endpoint will stop working on December 31, 2024 (3 months remaining).

Action required:
- Migrate to GET /users/:id immediately
- See migration guide: https://docs.example.com/migration

Need help?
- Reply to this email
- Schedule a call: https://calendly.com/api-team
- Schedule a call: https://calendly.com/api-team

Thank you,
API Team

Graceful Degradation

Optional: Temporary Disable

Process:

code
1. Disable endpoint for 1 hour
2. Monitor errors
3. Identify affected users
4. Reach out
5. Re-enable
6. Give more time to migrate

Helpful Error Message

410 Gone Response:

code
HTTP/1.1 410 Gone
Content-Type: application/json

{
  "error": "This endpoint has been removed. Use /v2/users instead.",
  "migrationGuide": "https://docs.example.com/migration",
  "support": "api@example.com"
}

Feature Flag Deprecation

Mark Feature as Deprecated

Code:

javascript
if (featureFlags.isEnabled('old-feature')) {
  console.warn('old-feature flag is deprecated. Will be removed in v2.0.0.');
}

Database Schema Deprecation

Multi-Step Migration

Step 1: Stop Writing to Old Column

sql
-- Stop writing to 'name' column
-- Write to 'full_name' instead

Step 2: Stop Reading (Use New Column)

sql
-- Stop reading from 'name' column
-- Read from 'full_name' instead

Step 3: Drop Old Column

sql
-- After all code migrated
ALTER TABLE users DROP COLUMN name;

Real Deprecation Examples

Stripe API Evolution

Characteristics:

  • Excellent consistency
  • Comprehensive docs
  • Versioning via headers
  • Extensive examples
  • Idempotency keys
  • Webhooks (event-driven)

Learn From:

  • Error format (detailed, helpful)
  • Pagination (cursor-based)
  • Deprecation notices
  • Comprehensive SDKs

GitHub API

Characteristics:

  • RESTful design
  • GraphQL alternative
  • Deprecation notices
  • Rate limiting

Learn From:

  • Deprecation headers
  • Preview features (opt-in)
  • Comprehensive documentation

Internal API Gateway Patterns

Pattern:

  • All APIs go through API gateway → Gateway enforces governance → Rate limiting, auth, logging → Consistent experience

Implementation

Migration Guide

Example:

markdown
## How to Migrate

### What's Changing
The `/users/:id/profile` endpoint is deprecated. Use `/users/:id` instead.

### Why
We're consolidating user endpoints to simplify our API and provide a better developer experience.

### How to Migrate

### Before
```javascript
const profile = await fetch('/api/users/123/profile');

After

javascript
const user = await fetch('/api/users/123');

Timeline

  • June 1, 2024: Deprecation announced
  • September 1, 2024: Reminder email
  • December 1, 2024: Final warning
  • December 31, 2024: Endpoint stops working (410 Gone)
code

---

## Templates

### Deprecation Announcement (Email)

See "Step 2: Announce" section above

### Deprecation Announcement (Blog)

See "Step 2: Announce" section above

---

## Best Practices

### Communication
- [ ] Communicate changes early
- [ ] Provide migration guides
- [ ] Hold breaking change meetings
- [ ] Create data contracts with consumers
- [ ] Document breaking changes clearly
- [ ] Document breaking changes with dates
- [ ] Set appropriate notice period (6-12 months minimum)
- [ ] Monitor deprecated endpoint usage
- [ ] Track consumer adoption
- [ ] Reach out to active users
- [ ] Provide support during migration
- [ ] Send reminders at key milestones
- [ ]

### Documentation
- [ ] Document all breaking changes with dates
- [ ] Document breaking changes clearly
- [ ] Provide migration guides for consumers
- [ ] Document version compatibility
- [ ] Document migration timeline
- [ ] Document sunset dates
- [ ] Keep documentation in sync with code
- [ ] Use consistent deprecation headers
- [ ] Use appropriate deprecation headers
- [ ] Include migration guide links
- [ ] Document breaking changes in changelog
- [ ] Document examples in documentation
- [ ] Document breaking changes in API docs
- [ ] Document breaking changes in README
- [ ] Document breaking changes in Swagger UI
- [ ] Document breaking changes in ReDoc
- [ ]

### Migration
- [ ] Use zero-downtime migration pattern
- [ ] Use multi-step migrations for breaking changes
- [ ] Backfill data before removing old columns
- [ ] Test migrations in staging environment
- [ ] Provide rollback procedures
- [ ] Monitor migration progress
- [ ] Support consumers during migration
- [ ] Use feature flags for gradual rollout
- [ ] Maintain backward compatibility during migration
- [ ] Use canary deployments for testing
- [ ]

### Monitoring
- [ ] Track deprecated endpoint usage
- [ ] Monitor breaking change impacts
- [ ] Track consumer adoption of new schema
- [ ] Set up dashboards for API health
- [ ] Alert on high usage of deprecated endpoints
- [ ] Monitor migration success rates
- [ ] Track time to sunset
- [ ]

### Testing
- [ ] Test backward compatibility
- [ ] Test with production-like data
- [ ] Test migration scripts thoroughly
- [ ] Test graceful degradation scenarios
- [ ] Monitor test coverage
- [ ]

### Prevention
- [ ] Use data contracts for all shared data
- [ ] Enforce schema validation at source
- [ ] [ ] Implement CI/CD schema checks
- [ ]

### Version Control
- [ ] Use semantic versioning
- [ ] Tag all releases with version numbers
- [ ] Document version compatibility matrix
- [ ] Maintain backward compatibility
- [ ] Use @deprecated directive for breaking changes
- [ ]

### Legal Compliance
- [ ] Follow contract terms if applicable
- [ ] Provide minimum notice period
- [ ] Ensure migration support
- [ ] Document breaking changes clearly
- [ ] Provide migration guides
- [ ] Maintain deprecation records

### Checklist
- [ ] Define deprecation process
- [ ] Set appropriate notice period
- [ ] Document breaking changes clearly
- [ ] Provide migration guides
- [ ] Monitor deprecated endpoint usage
- [ ] Track consumer adoption
- [ ] Set up dashboards for API health
- [ ] Track migration success rates
- [ ] Test backward compatibility
- [ ] Test with production-like data
- [ ] Monitor test coverage
- [ ] Optimize deprecation headers
- [ ] Use feature flags for gradual rollout
- [ ] Use zero-downtime migrations
- [ ] Backfill data before removing old columns
- [ ] Test migrations in staging environment
- [ ] Have rollback procedures ready
- [ ] Monitor schema drift metrics
- [ ] Track breaking change impacts
- [ ] Track consumer adoption of new schema
- [ ] Set up change notifications
- [ ] Test with production-like data
- [ ] Monitor test coverage
- [ ] Optimize schema validation overhead
- [ ] Cache schema definitions
- [ ] Use efficient validation libraries
- [ ] Monitor schema performance impact
- [ ] Establish schema ownership
- [ ] Create schema review process
- [ ] Define schema lifecycle
- [ ] Plan schema deprecation strategy
- [ ] Set up incident response for violations
- [ ] Test schema validation logic
- [ ] Train team on deprecation best practices