Api Designer Examples

Externalized from the agent definition per the few-shot-examples rule (#1587).

API Designer — Worked Examples

Externalized from the agent definition per the few-shot-examples rule (#1587).

Few-Shot Examples

Example 1: Simple - REST Endpoint Specification

Input:

"Design a REST API endpoint for retrieving a single user by ID. Include OpenAPI specification with response schema, error codes, and security requirements."

Output:

openapi: 3.1.0
info:
  title: User Management API
  version: 1.0.0
  description: API for managing user accounts

paths:
  /api/users/{userId}:
    get:
      summary: Get user by ID
      description: Retrieves a single user account by unique identifier
      operationId: getUserById
      tags:
        - users
      security:
        - bearerAuth: []
      parameters:
        - name: userId
          in: path
          required: true
          description: Unique identifier for the user
          schema:
            type: string
            format: uuid
            example: "550e8400-e29b-41d4-a716-446655440000"
      responses:
        '200':
          description: User retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
              examples:
                success:
                  value:
                    id: "550e8400-e29b-41d4-a716-446655440000"
                    email: "[email protected]"
                    firstName: "John"
                    lastName: "Doe"
                    role: "user"
                    isActive: true
                    createdAt: "2024-01-15T10:30:00Z"
                    updatedAt: "2024-01-20T14:45:00Z"
        '401':
          description: Authentication required
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
              examples:
                unauthorized:
                  value:
                    type: "https://api.example.com/errors/unauthorized"
                    title: "Unauthorized"
                    status: 401
                    detail: "Valid authentication token required"
                    instance: "/api/users/550e8400-e29b-41d4-a716-446655440000"
        '403':
          description: Insufficient permissions
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
              examples:
                forbidden:
                  value:
                    type: "https://api.example.com/errors/forbidden"
                    title: "Forbidden"
                    status: 403
                    detail: "Insufficient permissions to access this resource"
                    instance: "/api/users/550e8400-e29b-41d4-a716-446655440000"
        '404':
          description: User not found
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
              examples:
                notFound:
                  value:
                    type: "https://api.example.com/errors/not-found"
                    title: "Not Found"
                    status: 404
                    detail: "User with ID '550e8400-e29b-41d4-a716-446655440000' not found"
                    instance: "/api/users/550e8400-e29b-41d4-a716-446655440000"
        '500':
          description: Internal server error
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'

components:
  schemas:
    User:
      type: object
      required:
        - id
        - email
        - firstName
        - lastName
        - role
        - isActive
        - createdAt
        - updatedAt
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier for the user
        email:
          type: string
          format: email
          description: User's email address
        firstName:
          type: string
          minLength: 1
          maxLength: 100
          description: User's first name
        lastName:
          type: string
          minLength: 1
          maxLength: 100
          description: User's last name
        role:
          type: string
          enum: [admin, user, guest]
          description: User's role in the system
        isActive:
          type: boolean
          description: Whether the user account is active
        createdAt:
          type: string
          format: date-time
          description: Timestamp when user was created
        updatedAt:
          type: string
          format: date-time
          description: Timestamp when user was last updated

    ProblemDetails:
      type: object
      required:
        - type
        - title
        - status
      properties:
        type:
          type: string
          format: uri
          description: URI reference identifying the problem type
        title:
          type: string
          description: Short, human-readable summary of the problem
        status:
          type: integer
          format: int32
          description: HTTP status code
        detail:
          type: string
          description: Human-readable explanation specific to this occurrence
        instance:
          type: string
          format: uri
          description: URI reference identifying the specific occurrence

  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT token obtained from /api/auth/login

Why This Is Good:

  • Complete OpenAPI specification: Uses OpenAPI 3.1.0 standard with all required fields and proper structure
  • Rich error handling: Defines 401, 403, 404, 500 responses with RFC 7807 Problem Details format for consistency
  • Detailed schema definitions: User schema includes validation constraints (min/max length, enum values, format specifications)
  • Security-first: Explicit bearer authentication requirement with JWT format specification
  • Concrete examples: Includes example values for both success and error responses to guide implementation
  • Clear documentation: Every field has a description, making the API self-documenting

Example 2: Moderate - Payment API Error Handling

Input:

"Design comprehensive error handling for a payment processing API. Cover validation errors (400), authentication failures (401), authorization issues (403), and internal errors (500). Use RFC 7807 Problem Details format with extension fields for payment-specific context."

Output:

openapi: 3.1.0
info:
  title: Payment Processing API
  version: 1.0.0
  description: Secure payment processing with comprehensive error handling

paths:
  /api/payments:
    post:
      summary: Process payment
      description: Processes a payment transaction
      operationId: processPayment
      tags:
        - payments
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PaymentRequest'
      responses:
        '201':
          description: Payment processed successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaymentResponse'
        '400':
          description: Validation error
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/PaymentValidationProblem'
              examples:
                invalidAmount:
                  value:
                    type: "https://api.example.com/payments/errors/validation"
                    title: "Validation Error"
                    status: 400
                    detail: "Payment validation failed"
                    instance: "/api/payments"
                    errors:
                      - field: "amount"
                        code: "AMOUNT_TOO_SMALL"
                        message: "Amount must be at least 0.01"
                        rejectedValue: 0
                      - field: "currency"
                        code: "UNSUPPORTED_CURRENCY"
                        message: "Currency 'XYZ' is not supported"
                        rejectedValue: "XYZ"
                        supportedValues: ["USD", "EUR", "GBP"]
                invalidCard:
                  value:
                    type: "https://api.example.com/payments/errors/validation"
                    title: "Validation Error"
                    status: 400
                    detail: "Payment method validation failed"
                    instance: "/api/payments"
                    errors:
                      - field: "paymentMethod.cardNumber"
                        code: "INVALID_CARD_NUMBER"
                        message: "Card number fails Luhn check"
                        rejectedValue: "****1234"
                      - field: "paymentMethod.expiryDate"
                        code: "CARD_EXPIRED"
                        message: "Card expired on 2023-12"
                        rejectedValue: "2023-12"
        '401':
          description: Authentication required
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/PaymentAuthenticationProblem'
              examples:
                missingToken:
                  value:
                    type: "https://api.example.com/payments/errors/authentication"
                    title: "Authentication Required"
                    status: 401
                    detail: "Valid bearer token required for payment processing"
                    instance: "/api/payments"
                    authenticationScheme: "Bearer"
                    realm: "payment-api"
                expiredToken:
                  value:
                    type: "https://api.example.com/payments/errors/authentication"
                    title: "Token Expired"
                    status: 401
                    detail: "Authentication token expired at 2024-01-20T15:30:00Z"
                    instance: "/api/payments"
                    expiredAt: "2024-01-20T15:30:00Z"
                    authenticationScheme: "Bearer"
        '403':
          description: Insufficient permissions or payment declined
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/PaymentAuthorizationProblem'
              examples:
                insufficientPermissions:
                  value:
                    type: "https://api.example.com/payments/errors/forbidden"
                    title: "Insufficient Permissions"
                    status: 403
                    detail: "User lacks permission to process payments"
                    instance: "/api/payments"
                    requiredPermission: "payments:create"
                    userPermissions: ["payments:read"]
                paymentDeclined:
                  value:
                    type: "https://api.example.com/payments/errors/declined"
                    title: "Payment Declined"
                    status: 403
                    detail: "Payment declined by payment processor"
                    instance: "/api/payments"
                    declineReason: "INSUFFICIENT_FUNDS"
                    declineCode: "51"
                    canRetry: false
                    merchantMessage: "Insufficient funds - request alternate payment method"
                fraudSuspected:
                  value:
                    type: "https://api.example.com/payments/errors/declined"
                    title: "Payment Declined"
                    status: 403
                    detail: "Payment declined due to fraud detection"
                    instance: "/api/payments"
                    declineReason: "FRAUD_SUSPECTED"
                    declineCode: "59"
                    canRetry: false
                    merchantMessage: "Suspected fraud - contact issuer"
                    riskScore: 0.92
        '429':
          description: Rate limit exceeded
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/PaymentRateLimitProblem'
              examples:
                rateLimited:
                  value:
                    type: "https://api.example.com/payments/errors/rate-limit"
                    title: "Rate Limit Exceeded"
                    status: 429
                    detail: "Payment processing rate limit exceeded"
                    instance: "/api/payments"
                    rateLimit:
                      limit: 100
                      remaining: 0
                      resetAt: "2024-01-20T16:00:00Z"
        '500':
          description: Internal server error
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/PaymentInternalErrorProblem'
              examples:
                processorTimeout:
                  value:
                    type: "https://api.example.com/payments/errors/internal"
                    title: "Payment Processor Timeout"
                    status: 500
                    detail: "Payment processor did not respond within timeout period"
                    instance: "/api/payments"
                    errorId: "err_1234567890abcdef"
                    canRetry: true
                    retryAfter: 30
                    supportContact: "[email protected]"
                databaseError:
                  value:
                    type: "https://api.example.com/payments/errors/internal"
                    title: "Internal Server Error"
                    status: 500
                    detail: "An unexpected error occurred while processing payment"
                    instance: "/api/payments"
                    errorId: "err_fedcba0987654321"
                    canRetry: true
                    retryAfter: 60
                    supportContact: "[email protected]"

components:
  schemas:
    PaymentRequest:
      type: object
      required:
        - amount
        - currency
        - paymentMethod
      properties:
        amount:
          type: number
          format: decimal
          minimum: 0.01
          description: Payment amount
        currency:
          type: string
          enum: [USD, EUR, GBP]
          description: Three-letter currency code
        paymentMethod:
          $ref: '#/components/schemas/PaymentMethod'

    PaymentMethod:
      type: object
      required:
        - type
        - cardNumber
        - expiryDate
        - cvv
      properties:
        type:
          type: string
          enum: [card]
        cardNumber:
          type: string
          pattern: '^[0-9]{13,19}$'
        expiryDate:
          type: string
          pattern: '^[0-9]{4}-[0-9]{2}$'
          description: Format YYYY-MM
        cvv:
          type: string
          pattern: '^[0-9]{3,4}$'

    PaymentResponse:
      type: object
      required:
        - id
        - status
        - amount
        - currency
      properties:
        id:
          type: string
          format: uuid
        status:
          type: string
          enum: [succeeded, processing]
        amount:
          type: number
        currency:
          type: string

    PaymentValidationProblem:
      allOf:
        - $ref: '#/components/schemas/BaseProblemDetails'
        - type: object
          required:
            - errors
          properties:
            errors:
              type: array
              description: Detailed validation errors
              items:
                type: object
                required:
                  - field
                  - code
                  - message
                properties:
                  field:
                    type: string
                    description: JSON path to the invalid field
                  code:
                    type: string
                    description: Machine-readable error code
                  message:
                    type: string
                    description: Human-readable error message
                  rejectedValue:
                    description: The value that was rejected
                  supportedValues:
                    type: array
                    description: List of supported values (if applicable)

    PaymentAuthenticationProblem:
      allOf:
        - $ref: '#/components/schemas/BaseProblemDetails'
        - type: object
          properties:
            authenticationScheme:
              type: string
              description: Expected authentication scheme
            realm:
              type: string
              description: Authentication realm
            expiredAt:
              type: string
              format: date-time
              description: When the token expired (if applicable)

    PaymentAuthorizationProblem:
      allOf:
        - $ref: '#/components/schemas/BaseProblemDetails'
        - type: object
          properties:
            requiredPermission:
              type: string
              description: Permission required for this operation
            userPermissions:
              type: array
              items:
                type: string
              description: Permissions the user currently has
            declineReason:
              type: string
              description: Reason payment was declined
            declineCode:
              type: string
              description: Processor-specific decline code
            canRetry:
              type: boolean
              description: Whether retrying might succeed
            merchantMessage:
              type: string
              description: Message to display to merchant
            riskScore:
              type: number
              format: float
              minimum: 0
              maximum: 1
              description: Fraud risk score (if applicable)

    PaymentRateLimitProblem:
      allOf:
        - $ref: '#/components/schemas/BaseProblemDetails'
        - type: object
          required:
            - rateLimit
          properties:
            rateLimit:
              type: object
              required:
                - limit
                - remaining
                - resetAt
              properties:
                limit:
                  type: integer
                  description: Maximum requests allowed
                remaining:
                  type: integer
                  description: Requests remaining in window
                resetAt:
                  type: string
                  format: date-time
                  description: When the rate limit resets

    PaymentInternalErrorProblem:
      allOf:
        - $ref: '#/components/schemas/BaseProblemDetails'
        - type: object
          required:
            - errorId
          properties:
            errorId:
              type: string
              description: Unique error identifier for support tracking
            canRetry:
              type: boolean
              description: Whether retrying the request might succeed
            retryAfter:
              type: integer
              description: Suggested retry delay in seconds
            supportContact:
              type: string
              description: Contact information for support

    BaseProblemDetails:
      type: object
      required:
        - type
        - title
        - status
      properties:
        type:
          type: string
          format: uri
        title:
          type: string
        status:
          type: integer
        detail:
          type: string
        instance:
          type: string
          format: uri

  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

Why This Is Good:

  • RFC 7807 compliance: Uses standard Problem Details format for all errors, ensuring consistency
  • Payment-specific extensions: Adds domain-specific fields like `declineReason`, `declineCode`, `canRetry`, `riskScore` for actionable error handling
  • Comprehensive error scenarios: Covers validation, authentication, authorization, rate limiting, and internal errors with realistic examples
  • Merchant-friendly messages: Includes `merchantMessage` field with user-facing guidance on how to resolve issues
  • Retry guidance: Explicit `canRetry` and `retryAfter` fields help clients implement smart retry logic
  • Detailed validation errors: Array of field-level errors with machine-readable codes and human-readable messages
  • Support tracking: Error IDs and support contact information enable effective troubleshooting

Example 3: Complex - API Versioning Strategy

Input:

"Design an API versioning strategy for migrating from v1 to v2 of a user management API. The v2 API changes the user model structure and adds new required fields. Include deprecation headers, sunset policy, backward compatibility approach, and migration guide."

Output:

# API Versioning Strategy: User Management API v1 → v2

## Executive Summary

This document defines the versioning strategy for migrating the User Management API from v1 to v2. Version 2 introduces breaking changes to the user model structure and adds new required fields for enhanced security and compliance.

## Version Comparison

### v1 User Model (Current)

{

"id": "550e8400-e29b-41d4-a716-446655440000",

"email": "[email protected]",

"name": "John Doe",

"role": "user",

"createdAt": "2024-01-15T10:30:00Z"

}


### v2 User Model (Target)

{

"id": "550e8400-e29b-41d4-a716-446655440000",

"email": "[email protected]",

"profile": {

"firstName": "John",

"lastName": "Doe",

"displayName": "John Doe"

},

"role": "user",

"security": {

"mfaEnabled": true,

"lastPasswordChange": "2024-01-20T14:00:00Z"

},

"metadata": {

"createdAt": "2024-01-15T10:30:00Z",

"updatedAt": "2024-01-20T14:00:00Z",

"version": 2

}

}


### Breaking Changes

| Change | Impact | Migration Required |
|--------|--------|-------------------|
| `name` → `profile.firstName` + `profile.lastName` | HIGH | Clients must split name field |
| New required field: `security.mfaEnabled` | HIGH | Clients must handle new field |
| New required field: `security.lastPasswordChange` | MEDIUM | Clients must handle new field |
| `createdAt` → `metadata.createdAt` | MEDIUM | Clients must update field path |
| Added `metadata.version` | LOW | Informational only |

## Versioning Approach

### URL-Based Versioning

v1: https://api.example.com/v1/users/{userId}

v2: https://api.example.com/v2/users/{userId}


**Rationale**: URL-based versioning provides clear separation, simplifies routing, and allows independent evolution of each version.

### Deprecation Timeline

| Date | Milestone | Action |
|------|-----------|--------|
| 2024-02-01 | v2 Release | v2 API goes live, v1 continues working |
| 2024-02-01 | Deprecation Notice | v1 endpoints return `Deprecation` and `Sunset` headers |
| 2024-05-01 | Warning Phase | v1 endpoints return `410 Gone` for new clients |
| 2024-08-01 | Sunset | v1 endpoints removed from production |

**Deprecation Period**: 6 months from v2 release to v1 sunset

### Deprecation Headers (v1 Endpoints)

All v1 endpoints will return the following headers:

HTTP/1.1 200 OK

Deprecation: true

Sunset: Wed, 01 Aug 2024 00:00:00 GMT

Link: <https://api.example.com/docs/v1-to-v2-migration>; rel="deprecation"

X-API-Version: v1

X-API-Latest-Version: v2

X-API-Deprecation-Reason: "Version 1 is deprecated. Please migrate to v2."


### Backward Compatibility Strategy

#### Option 1: Dual-Mode Server (Recommended)

Both v1 and v2 endpoints exist simultaneously during the deprecation period.

**v1 Endpoint** (`/v1/users/{userId}`):
- Returns legacy format
- Internally transforms v2 data to v1 format
- Includes deprecation headers

**v2 Endpoint** (`/v2/users/{userId}`):
- Returns new format
- Native v2 data structure

**Implementation**:

Internal data transformation layer

v1_response:

name: "{{ user.profile.firstName }} {{ user.profile.lastName }}"

email: "{{ user.email }}"

role: "{{ user.role }}"

createdAt: "{{ user.metadata.createdAt }}"

v2_response:

profile:

firstName: "{{ user.profile.firstName }}"

lastName: "{{ user.profile.lastName }}"

displayName: "{{ user.profile.firstName }} {{ user.profile.lastName }}"

email: "{{ user.email }}"

role: "{{ user.role }}"

security:

mfaEnabled: "{{ user.security.mfaEnabled }}"

lastPasswordChange: "{{ user.security.lastPasswordChange }}"

metadata:

createdAt: "{{ user.metadata.createdAt }}"

updatedAt: "{{ user.metadata.updatedAt }}"

version: 2


#### Option 2: Accept-Version Header

Single URL with version negotiation via header:

GET /api/users/550e8400-e29b-41d4-a716-446655440000 HTTP/1.1

Accept: application/json

Accept-Version: v2


**Not Recommended**: Adds complexity, harder to route, caching issues.

## Migration Guide

### For API Consumers

#### Step 1: Test v2 in Development (Week 1-2)

Update base URL

OLD: https://api.example.com/v1/users

NEW: https://api.example.com/v2/users

Test v2 endpoint

curl -H "Authorization: Bearer TOKEN" \

https://api.example.com/v2/users/550e8400-e29b-41d4-a716-446655440000


#### Step 2: Update Code to Handle v2 Response (Week 3-4)

**Before (v1)**:

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

console.log(user.name); // "John Doe"


**After (v2)**:

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

console.log(user.profile.firstName); // "John"

console.log(user.profile.lastName); // "Doe"

console.log(user.profile.displayName); // "John Doe"


#### Step 3: Update POST/PUT Requests (Week 5)

**Before (v1)**:

POST /v1/users

{

"email": "[email protected]",

"name": "New User",

"role": "user"

}


**After (v2)**:

POST /v2/users

{

"email": "[email protected]",

"profile": {

"firstName": "New",

"lastName": "User"

},

"role": "user",

"security": {

"mfaEnabled": false

}

}


#### Step 4: Deploy to Production (Week 6)

- Gradual rollout with feature flags
- Monitor error rates
- Rollback plan ready

### Code Migration Examples

#### JavaScript/TypeScript

// Helper function for backward compatibility

function normalizeUser(user: any, apiVersion: 'v1' | 'v2') {

if (apiVersion === 'v1') {

return {

id: user.id,

email: user.email,

firstName: user.name.split(' ')[0],

lastName: user.name.split(' ').slice(1).join(' '),

role: user.role,

mfaEnabled: false, // v1 doesn't have this

createdAt: user.createdAt,

};

} else {

return {

id: user.id,

email: user.email,

firstName: user.profile.firstName,

lastName: user.profile.lastName,

role: user.role,

mfaEnabled: user.security.mfaEnabled,

createdAt: user.metadata.createdAt,

};

}

}

// Usage

const user = await getUserById('123', 'v2');

const normalized = normalizeUser(user, 'v2');


#### Python

def normalize_user(user: dict, api_version: str) -> dict:

"""Normalize user data across API versions."""

if api_version == 'v1':

name_parts = user['name'].split(' ', 1)

return {

'id': user['id'],

'email': user['email'],

'first_name': name_parts[0],

'last_name': name_parts[1] if len(name_parts) > 1 else '',

'role': user['role'],

'mfa_enabled': False,

'created_at': user['createdAt'],

}

else: # v2

return {

'id': user['id'],

'email': user['email'],

'first_name': user['profile']['firstName'],

'last_name': user['profile']['lastName'],

'role': user['role'],

'mfa_enabled': user['security']['mfaEnabled'],

'created_at': user['metadata']['createdAt'],

}


## Monitoring & Observability

### Metrics to Track

| Metric | Purpose | Alert Threshold |
|--------|---------|-----------------|
| `api.requests.v1.count` | v1 usage trends | N/A (informational) |
| `api.requests.v2.count` | v2 adoption rate | <10% after 2 months |
| `api.errors.v1.rate` | v1 error rate | >5% |
| `api.errors.v2.rate` | v2 error rate | >2% |
| `api.latency.v1.p95` | v1 performance | >500ms |
| `api.latency.v2.p95` | v2 performance | >500ms |

### Client Migration Dashboard

Track migration progress by client:

SELECT

client_id,

SUM(CASE WHEN api_version = 'v1' THEN 1 ELSE 0 END) as v1_requests,

SUM(CASE WHEN api_version = 'v2' THEN 1 ELSE 0 END) as v2_requests,

(v2_requests / (v1_requests + v2_requests)) * 100 as migration_percentage

FROM api_requests

WHERE timestamp > NOW() - INTERVAL '7 days'

GROUP BY client_id

ORDER BY migration_percentage ASC;


## Rollback Plan

If critical issues arise in v2:

1. **Immediate**: Extend sunset date by 3 months
2. **Week 1**: Fix v2 issues
3. **Week 2**: Deploy fixes to v2
4. **Week 3**: Resume migration communications
5. **Month 2**: Resume deprecation timeline

## Communication Plan

### Announcement Schedule

| Date | Channel | Message |
|------|---------|---------|
| 2024-01-15 | Email, Blog | v2 preview announcement |
| 2024-02-01 | Email, Blog, In-App | v2 released, v1 deprecation notice |
| 2024-03-01 | Email | 5 months until v1 sunset |
| 2024-05-01 | Email, In-App | 3 months until v1 sunset, warning phase starts |
| 2024-07-01 | Email, In-App | 1 month until v1 sunset, final warning |
| 2024-08-01 | Email | v1 sunset complete |

### Stakeholder Communication

**For Product Teams**:
- Migration guide: https://api.example.com/docs/v1-to-v2-migration
- Breaking changes: https://api.example.com/docs/v2-breaking-changes
- Support channel: #api-migration-support

**For Management**:
- Migration dashboard: https://dashboard.example.com/api-migration
- Risk assessment: [Link to risk document]
- Cost analysis: [Link to cost document]

## Success Criteria

| Criterion | Target | Measurement |
|-----------|--------|-------------|
| v2 adoption rate | >90% by Month 4 | % of requests to v2 endpoints |
| v1 error rate | <1% during deprecation | Error rate on v1 endpoints |
| v2 error rate | <2% after launch | Error rate on v2 endpoints |
| Migration support tickets | <50 total | Support ticket count |
| Client satisfaction | >4.0/5.0 | Post-migration survey |

## OpenAPI Specifications

### v1 Endpoint

/v1/users/{userId}:

get:

deprecated: true

x-sunset-date: "2024-08-01T00:00:00Z"

responses:

'200':

description: User retrieved (DEPRECATED)

headers:

Deprecation:

schema:

type: boolean

example: true

Sunset:

schema:

type: string

format: date-time

example: "Wed, 01 Aug 2024 00:00:00 GMT"

Link:

schema:

type: string

example: '<https://api.example.com/docs/v1-to-v2-migration>; rel="deprecation"'


### v2 Endpoint

/v2/users/{userId}:

get:

summary: Get user by ID

responses:

'200':

description: User retrieved successfully

content:

application/json:

schema:

$ref: '#/components/schemas/UserV2'


## References

- RFC 8594: Sunset HTTP Header
- Semantic Versioning 2.0.0
- [Internal] API Governance Policy
- [Internal] Deprecation Process Guidelines

Why This Is Good:

  • Comprehensive strategy: Covers technical, communication, monitoring, and rollback aspects of API versioning
  • Clear migration path: Provides concrete examples in multiple languages showing before/after code patterns
  • Deprecation best practices: Uses standard HTTP headers (Deprecation, Sunset, Link) per RFC 8594
  • Realistic timeline: 6-month deprecation period with clear milestones and stakeholder communication plan
  • Measurable success: Defines specific metrics and success criteria to track migration progress
  • Backward compatibility: Dual-mode server approach allows gradual migration without breaking existing clients
  • Risk mitigation: Includes rollback plan, monitoring dashboard, and support communication channels