Skip to main content
API versioning is like having different editions of a software library. Each version represents a snapshot of the API at a specific point in time, with its own set of features, bug fixes, and behaviors. Unlike traditional software where you choose which version to install, with APIs you specify which “edition” you want to use with each request.

How API Versioning Works

Think of API versioning like a library with multiple editions of the same book:
  1. Version Selection: You specify which edition (version) you want to read with each request
  2. Compatibility: Each version maintains its behavior, even as newer versions are released
  3. Deprecation: Older editions eventually go out of print (get deprecated)
  4. Sunset: Eventually, very old editions are removed from the library entirely
The API uses your version header to determine which set of behaviors, response formats, and business logic to apply to your request.

Version Lifecycle Management

Every API version goes through a predictable lifecycle:
  • Active: Current version, fully supported with new features
  • Deprecated: Still works but marked for future removal
  • Sunset: No longer available, returns 410 Gone

Understanding Deprecation Headers

When you use a deprecated API version, the response includes detailed information about the deprecation timeline:

Response Headers

Deprecation
RFC 8594 standard header indicating when the version was officially deprecated.
Deprecation: Wed, 11 Nov 2024 23:59:59 GMT
Sunset
RFC 8594 standard header indicating when the version will stop working.
Sunset: Wed, 11 Nov 2025 23:59:59 GMT
X-Fanvue-API-Next-Version
Fanvue-specific header recommending which version to migrate to.
X-Fanvue-API-Next-Version: 2025-06-26

Example Response with Deprecation

Here’s what you’ll see when using a deprecated version:
HTTP/1.1 200 OK
Deprecation: Wed, 11 Nov 2024 23:59:59 GMT
Sunset: Wed, 11 Nov 2025 23:59:59 GMT
X-Fanvue-API-Next-Version: 2025-06-26
Content-Type: application/json

{
  "uuid": "123e4567-e89b-12d3-a456-426614174000",
  "email": "user@example.com",
  "handle": "creator123"
}
This response tells you:
  • The version was deprecated on November 11, 2024
  • It will stop working on November 11, 2025
  • You should migrate to version 2025-06-26
  • Your request still works for now

Version Error Responses

Unsupported Version (400)

When you request a version that was never supported:
HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "error": "Unsupported API version",
  "message": "API version '2024-01-01' is not supported"
}

Sunset Version (410)

When you request a version that has been permanently removed:
HTTP/1.1 410 Gone
Content-Type: application/json

{
  "error": "API version no longer supported",
  "message": "API version '2024-01-01' was sunset on 2024-12-31T00:00:00.000Z",
  "nextVersion": "2025-06-26"
}

Building Version-Aware Applications

Version Header Management

Always include the version header in your API client configuration:
class FanvueAPIClient {
  constructor(accessToken, version) {
    this.accessToken = accessToken;
    this.version = version;
    this.baseURL = "https://api.fanvue.com";
  }

  async request(endpoint, options = {}) {
    const response = await fetch(`${this.baseURL}${endpoint}`, {
      ...options,
      headers: {
        Authorization: `Bearer ${this.accessToken}`,
        "X-Fanvue-API-Version": this.version,
        "Content-Type": "application/json",
        ...options.headers,
      },
    });

    // Check for deprecation warnings
    this.handleDeprecationHeaders(response);

    return this.handleResponse(response);
  }

  handleDeprecationHeaders(response) {
    const deprecation = response.headers.get("Deprecation");
    const sunset = response.headers.get("Sunset");
    const nextVersion = response.headers.get("X-Fanvue-API-Next-Version");

    if (deprecation) {
      console.warn(`API version ${this.version} is deprecated as of ${deprecation}`);
      if (sunset) {
        console.warn(`Version will stop working on ${sunset}`);
      }
      if (nextVersion) {
        console.warn(`Consider upgrading to version ${nextVersion}`);
      }
    }
  }
}

Version Error Handling

Implement robust error handling for version-related failures:
async function handleResponse(response) {
  if (response.status === 400) {
    const error = await response.json();
    if (error.error === "Unsupported API version") {
      throw new UnsupportedVersionError(error.message);
    }
  }

  if (response.status === 410) {
    const error = await response.json();
    if (error.error === "API version no longer supported") {
      throw new SunsetVersionError(error.message, error.nextVersion);
    }
  }

  if (!response.ok) {
    throw new APIError(`HTTP ${response.status}: ${response.statusText}`);
  }

  return response.json();
}

class UnsupportedVersionError extends Error {
  constructor(message) {
    super(message);
    this.name = "UnsupportedVersionError";
  }
}

class SunsetVersionError extends Error {
  constructor(message, nextVersion) {
    super(message);
    this.name = "SunsetVersionError";
    this.nextVersion = nextVersion;
  }
}

Python Implementation

import requests
import logging
from datetime import datetime
from typing import Optional

class FanvueClient:
    def __init__(self, access_token: str, version: str):
        self.access_token = access_token
        self.version = version
        self.base_url = "https://api.fanvue.com"
        self.session = requests.Session()
        self.session.headers.update({
            'Authorization': f'Bearer {access_token}',
            'X-Fanvue-API-Version': version,
            'Content-Type': 'application/json'
        })

    def request(self, method: str, endpoint: str, **kwargs):
        response = self.session.request(method, f"{self.base_url}{endpoint}", **kwargs)

        # Monitor deprecation status
        self._check_deprecation_headers(response)

        # Handle version errors
        if response.status_code == 400:
            error_data = response.json()
            if "Unsupported API version" in error_data.get("error", ""):
                raise UnsupportedVersionError(error_data["message"])

        if response.status_code == 410:
            error_data = response.json()
            if "API version no longer supported" in error_data.get("error", ""):
                raise SunsetVersionError(
                    error_data["message"],
                    error_data.get("nextVersion")
                )

        response.raise_for_status()
        return response.json()

    def _check_deprecation_headers(self, response):
        deprecation = response.headers.get('Deprecation')
        sunset = response.headers.get('Sunset')
        next_version = response.headers.get('X-Fanvue-API-Next-Version')

        if deprecation:
            logging.warning(f"API version {self.version} deprecated as of {deprecation}")
            if sunset:
                sunset_date = datetime.strptime(sunset, '%a, %d %b %Y %H:%M:%S %Z')
                logging.warning(f"Version sunset scheduled for {sunset_date}")
            if next_version:
                logging.warning(f"Recommended migration to version {next_version}")

class UnsupportedVersionError(Exception):
    pass

class SunsetVersionError(Exception):
    def __init__(self, message: str, next_version: Optional[str] = None):
        super().__init__(message)
        self.next_version = next_version

Advanced Version Management Strategies

Version Pinning

Pin to specific versions in production to ensure predictable behavior:
// Good: Explicit version pinning
const client = new FanvueAPIClient(accessToken, "2025-06-26");

// Avoid: Dynamic version selection in production
const client = new FanvueAPIClient(accessToken, getLatestVersion());

Graceful Migration Patterns

Implement gradual migration with fallback logic:
class VersionMigrationClient extends FanvueAPIClient {
  constructor(accessToken, primaryVersion, fallbackVersion) {
    super(accessToken, primaryVersion);
    this.fallbackVersion = fallbackVersion;
  }

  async requestWithFallback(endpoint, options = {}) {
    try {
      return await this.request(endpoint, options);
    } catch (error) {
      if (error instanceof SunsetVersionError) {
        console.warn(`Primary version sunset, falling back to ${this.fallbackVersion}`);
        // Create temporary client with fallback version
        const fallbackClient = new FanvueAPIClient(this.accessToken, this.fallbackVersion);
        return await fallbackClient.request(endpoint, options);
      }
      throw error;
    }
  }
}

Monitoring and Alerting

Set up monitoring for deprecation warnings:
class MonitoredAPIClient extends FanvueAPIClient {
  constructor(accessToken, version, metricsCollector) {
    super(accessToken, version);
    this.metrics = metricsCollector;
  }

  handleDeprecationHeaders(response) {
    const deprecation = response.headers.get("Deprecation");
    const sunset = response.headers.get("Sunset");

    if (deprecation) {
      this.metrics.increment("api.version.deprecated", {
        version: this.version,
        deprecation_date: deprecation,
        sunset_date: sunset,
      });

      // Alert if sunset is approaching
      if (sunset) {
        const sunsetDate = new Date(sunset);
        const daysUntilSunset = (sunsetDate - new Date()) / (1000 * 60 * 60 * 24);

        if (daysUntilSunset <= 30) {
          this.metrics.alert("api.version.sunset_approaching", {
            version: this.version,
            days_remaining: Math.floor(daysUntilSunset),
          });
        }
      }
    }
  }
}

Best Practices for Production

Configuration Management

  • Store API versions in environment variables or configuration files
  • Use the same version across all environments (dev, staging, production)
  • Document which version each deployment uses

Testing Strategy

  • Test version migration in staging environments first
  • Implement integration tests for each supported API version
  • Validate that deprecated versions still work as expected

Deployment Planning

  • Plan version migrations during maintenance windows
  • Implement feature flags for gradual version rollouts
  • Monitor error rates closely after version changes

Team Coordination

  • Establish clear policies for when to upgrade API versions
  • Create alerts for deprecation warnings in production
  • Document migration procedures for your team