v2 to v3 Migration Guide

Step-by-step guide for migrating from Dual API v2 to v3, covering authentication, endpoint renames, pagination, and error handling.

Step-by-step guide for migrating from Dual API v2 to v3. Covers authentication, endpoint renames, pagination, and error handling changes with before/after code examples.

Note:

Deprecation Timeline: v2 endpoints return 301 redirects to their v3 equivalents. This compatibility layer will be removed in June 2026. Migrate before then to avoid breaking changes.

Changes at a Glance

1. Authentication

v2 used static App-Id and App-Secret headers. v3 supports API keys (sent via the x-api-key header for server-to-server) and JWT bearer tokens (sent via the Authorization header for user sessions).

v2, App-Id / App-Secret

bash
curl https://api.dual.io/user/profile \
-H "App-Id: YOUR_APP_ID" \
-H "App-Secret: YOUR_APP_SECRET"

v3, API Key or Bearer JWT

bash
# Option 1: API key (recommended for server-to-server)
curl https://api-testnet.dual.network/wallets/me \
-H "x-api-key: sk_live_1a2b3c4d5e6f7g8h"
# Option 2: JWT bearer token (for user sessions)
curl -X POST https://api-testnet.dual.network/wallets/login \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "password": "password"}'
# Use the JWT in subsequent requests
curl https://api-testnet.dual.network/wallets/me \
-H "Authorization: Bearer eyJhbGciOiJIUzI1..."

2. Error Handling

v3 errors return a structured envelope with an error object containing a numeric code, human-readable message, and an optional details array, plus a request ID for support tracing.

v2 Error

json
{
"message": "Not found"
}

v3 Error

json
{
"error": {
"code": 404,
"message": "Object obj_123 not found",
"details": [
{ "field": "objectId", "reason": "No object with this ID exists" }
]
},
"x_request_id": "req_abc123def456"
}

3. Pagination

v3 uses cursor-based pagination for consistent results. Offset pagination is deprecated and will be removed in v4.

v2 Offset

javascript
// v2: Offset pagination
GET /vatoms?offset=20&limit=10
// Response
{
"items": [...],
"total": 150,
"offset": 20,
"limit": 10
}

v3 Cursor

javascript
// v3: Cursor pagination
GET /objects?limit=10&next=eyJpZCI6Im9ial8xMjMifQ
// Response
{
"items": [...],
"next": "eyJpZCI6Im9ial8xMzMifQ",
"has_more": true
}

4. Endpoint Renames

5. Automated Codemod

Run this bash script from your project root to automatically rename endpoints and update headers. Always review the diff before committing.

bash
#!/bin/bash
# Run from your project root
find src -name "*.ts" -o -name "*.js" | xargs sed -i '' \
-e 's|api.dual.io|api-testnet.dual.network|g' \
-e 's|/user/profile|/wallets/me|g' \
-e 's|/user/login|/wallets/login|g' \
-e 's|/user/register|/wallets/register|g' \
-e 's|/vatoms|/objects|g' \
-e 's|App-Id: "|x-api-key: "|g' \
-e 's|App-Secret: "[^"]*"||g' \
-e 's|/activity|/ebus/actions|g' \
-e 's|/user/token/refresh|/wallets/token/refresh|g'
echo "Migration complete, review changes with: git diff"

Need help migrating? Open a support ticket or ask in the Discord.