API v1 to v2 Migration Guide
January 15, 2024 32174b4 Edit this page

API v1 to v2 Migration Guide 🗄️ Archived

Complete guide for migrating from deprecated API v1 to current API v2

This guide helps you migrate from the deprecated API v1 to the current API v2.

Quick Migration Checklist

  • Update base URL
  • Change authentication method
  • Update response parsing
  • Implement new error handling
  • Update pagination logic
  • Test all endpoints
  • Deploy to production

Step 1: Update Base URL

Before (v1):

BASE_URL = "https://api.example.com/api"

After (v2):

BASE_URL = "https://api.example.com/v1"

Step 2: Update Authentication

v1 Authentication

headers = {
    "X-Auth-Token": "your_token"
}

v2 Authentication

headers = {
    "Authorization": "Bearer your_token"
}

You’ll need to exchange your v1 token for a v2 token:

curl -X POST https://api.example.com/v1/auth/migrate \
  -H "X-Auth-Token: your_v1_token"

Step 3: Update Response Parsing

v1 Response

{
  "result": {...},
  "status": "success"
}
# v1 parsing
response = requests.get(url, headers=headers)
data = response.json()
if data['status'] == 'success':
    resource = data['result']

v2 Response

{
  "data": {...}
}
# v2 parsing
response = requests.get(url, headers=headers)
response.raise_for_status()  # Raises exception for 4xx/5xx
data = response.json()
resource = data['data']

Step 4: Update Error Handling

v1 Errors

{
  "status": "error",
  "message": "Something went wrong"
}

v2 Errors

{
  "error": {
    "code": "validation_error",
    "message": "Invalid input",
    "details": [...]
  }
}
# v2 error handling
try:
    response = requests.get(url, headers=headers)
    response.raise_for_status()
except requests.HTTPError as e:
    error_data = e.response.json()
    print(f"Error: {error_data['error']['message']}")

Step 5: Update Pagination

v1 Pagination

GET /api/resources?offset=20&limit=10
{
  "result": [...],
  "count": 10,
  "total": 100
}

v2 Pagination

GET /v1/resources?page=3&per_page=10
{
  "data": [...],
  "meta": {
    "page": 3,
    "per_page": 10,
    "total": 100,
    "total_pages": 10
  }
}

Step 6: Field Name Changes

Many fields were renamed for consistency:

v1 Fieldv2 Field
id (integer)id (string with prefix)
createdcreated_at
updatedupdated_at
deleteddeleted_at
type (integer)type (string)

Step 7: ID Format Changes

v1 IDs

{
  "id": 12345
}

v2 IDs

{
  "id": "res_abc123xyz"
}

Update your database schema and code to handle string IDs.

Example: Complete Migration

Before (v1)

import requests

BASE_URL = "https://api.example.com/api"
HEADERS = {"X-Auth-Token": "old_token"}

def get_resources():
    response = requests.get(f"{BASE_URL}/resources", headers=HEADERS)
    data = response.json()
    
    if data['status'] == 'success':
        return data['result']
    else:
        raise Exception(data['message'])

def create_resource(name):
    response = requests.post(
        f"{BASE_URL}/resources",
        headers=HEADERS,
        json={"resource": {"name": name, "type": 1}}
    )
    data = response.json()
    
    if data['status'] == 'success':
        return data['result']
    else:
        raise Exception(data['message'])

After (v2)

import requests

BASE_URL = "https://api.example.com/v1"
HEADERS = {"Authorization": "Bearer new_token"}

def get_resources():
    response = requests.get(f"{BASE_URL}/resources", headers=HEADERS)
    response.raise_for_status()
    data = response.json()
    return data['data']

def create_resource(name):
    response = requests.post(
        f"{BASE_URL}/resources",
        headers=HEADERS,
        json={"name": name, "type": "standard"}
    )
    response.raise_for_status()
    data = response.json()
    return data['data']

Testing Your Migration

  1. Set up a test environment
  2. Run both v1 and v2 code in parallel
  3. Compare results
  4. Fix any discrepancies
  5. Gradually roll out v2 to production

Common Issues

Issue: Token Migration Failed

Solution: Generate a new token using login endpoint

curl -X POST https://api.example.com/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": "...", "password": "..."}'

Issue: Integer IDs Breaking Database Relations

Solution: Add a migration to update ID columns to varchar

ALTER TABLE resources 
MODIFY COLUMN id VARCHAR(50);

Issue: Type Constants Changed

Solution: Create a mapping dictionary

TYPE_MAPPING = {
    1: "standard",
    2: "premium",
    3: "enterprise"
}

Getting Help

If you encounter issues during migration:

Rollback Plan

If you need to rollback:

  1. Keep v1 code in a separate branch
  2. Have v1 tokens backed up
  3. Document any database schema changes
  4. Test rollback procedure before production migration