OP

openrouter-upgrade-migration

Upgrade or migrate your codebase to use OpenRouter with minimal friction using standardized upgrade patterns.

Install

mkdir -p .claude/skills/openrouter-upgrade-migration && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/8513" && unzip -o skill.zip -d .claude/skills/openrouter-upgrade-migration && rm skill.zip

Installs to .claude/skills/openrouter-upgrade-migration

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Migrate to OpenRouter from direct provider APIs or upgrade between SDK/model
76 charsno explicit “when” trigger
Intermediate

Key capabilities

  • Migrate direct provider SDKs to OpenRouter
  • Update model configuration and provider prefixes
  • Execute comparison tests for latency and output quality
  • Implement feature flags for gradual traffic migration
  • Standardize SDK initialization across projects

How it works

The skill provides a migration path by updating the SDK base URL and headers while mapping model IDs to provider-prefixed formats. It includes a checklist and comparison script to validate performance and output parity.

Inputs & outputs

You give it
Existing provider SDK configuration
You get back
Migrated code with OpenRouter base URL and headers

When to use openrouter-upgrade-migration

  • Migrating from OpenAI to OpenRouter
  • Updating project SDK dependencies
  • Standardizing model configuration
  • Safely switching provider APIs

About this skill

OpenRouter Upgrade & Migration

Current State

!npm list openai 2>/dev/null | head -5 !pip show openai 2>/dev/null | head -5

Overview

Migrating to OpenRouter from a direct provider API (OpenAI, Anthropic) is minimal: change base_url and api_key, add two headers. The OpenAI SDK works natively with OpenRouter. This skill covers migrating from direct APIs, switching between models, upgrading SDK versions, and running comparison tests.

Prerequisites

  • An existing direct OpenAI or Anthropic integration to migrate — the Current State block above checks your installed openai SDK via npm list openai / pip show openai
  • An OpenRouter API key (sk-or-v1-...) exported as OPENROUTER_API_KEY — see the openrouter-install-auth skill for setup
  • Python 3.8+ or Node.js 18+ with the OpenAI SDK (Anthropic SDK users switch to the OpenAI SDK as part of the migration)
  • The old provider key (OPENAI_API_KEY / ANTHROPIC_API_KEY) kept active during migration for comparison tests and quick rollback

Instructions

  1. Confirm your installed SDK versions from the Current State output at the top of this skill.
  2. Apply the 3-line change per Migration from Direct OpenAI, Migration from Direct Anthropic, or TypeScript Migration: swap base_url to https://openrouter.ai/api/v1, switch to OPENROUTER_API_KEY, and add the HTTP-Referer / X-Title headers. Anthropic migrations also change response parsing to .choices[0].message.content.
  3. Prefix every model ID with its provider per the Model ID Migration Map (e.g. gpt-4oopenai/gpt-4o).
  4. Work through the Migration Checklist — config, code, testing, and operations items — before flipping traffic.
  5. Run the Comparison Test Script on your critical prompts (temperature=0) to compare content, tokens, and latency against the old backend.
  6. Roll out gradually with the Feature Flag Migration pattern (USE_OPENROUTER env var plus get_model_id mapping), moving 10% → 50% → 100%.
  7. Watch for post-migration failures (401, model_not_found, response-format drift, +50–100ms latency) per the Error Handling table.

Migration from Direct OpenAI

# BEFORE: Direct OpenAI
from openai import OpenAI
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Hello"}],
    max_tokens=200,
)

# AFTER: Via OpenRouter (3 lines changed)
from openai import OpenAI
client = OpenAI(
    base_url="https://openrouter.ai/api/v1",     # ← Changed
    api_key=os.environ["OPENROUTER_API_KEY"],     # ← Changed
    default_headers={                              # ← Added
        "HTTP-Referer": "https://my-app.com",
        "X-Title": "my-app",
    },
)
response = client.chat.completions.create(
    model="openai/gpt-4o",  # ← Add provider prefix
    messages=[{"role": "user", "content": "Hello"}],
    max_tokens=200,
)

Migration from Direct Anthropic

# BEFORE: Direct Anthropic SDK
import anthropic
client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
response = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=200,
    messages=[{"role": "user", "content": "Hello"}],
)
content = response.content[0].text

# AFTER: Via OpenRouter (using OpenAI SDK instead of Anthropic SDK)
from openai import OpenAI
client = OpenAI(
    base_url="https://openrouter.ai/api/v1",
    api_key=os.environ["OPENROUTER_API_KEY"],
    default_headers={
        "HTTP-Referer": "https://my-app.com",
        "X-Title": "my-app",
    },
)
response = client.chat.completions.create(
    model="anthropic/claude-3.5-sonnet",  # OpenRouter model ID
    messages=[{"role": "user", "content": "Hello"}],
    max_tokens=200,
)
content = response.choices[0].message.content  # OpenAI response format

TypeScript Migration

// BEFORE: Direct OpenAI
import OpenAI from "openai";
const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

// AFTER: Via OpenRouter
const client = new OpenAI({
  baseURL: "https://openrouter.ai/api/v1",
  apiKey: process.env.OPENROUTER_API_KEY,
  defaultHeaders: {
    "HTTP-Referer": "https://my-app.com",
    "X-Title": "my-app",
  },
});
// Change model from "gpt-4o" to "openai/gpt-4o"

Migration Checklist

MIGRATION_CHECKLIST = {
    "config": [
        "base_url changed to https://openrouter.ai/api/v1",
        "API key changed to OPENROUTER_API_KEY (sk-or-v1-...)",
        "HTTP-Referer and X-Title headers added",
        "Model IDs prefixed with provider/ (e.g., openai/gpt-4o)",
    ],
    "code": [
        "All client initialization updated",
        "Model IDs updated in all routes/configs",
        "Error handling covers OpenRouter-specific codes (402, 408)",
        "Streaming still works with new endpoint",
        "Tool/function calling still works",
    ],
    "testing": [
        "Same prompts produce comparable quality output",
        "Latency within acceptable range (expect +50-100ms)",
        "Token counts match expectations",
        "Cost tracking updated for OpenRouter pricing",
        "Fallback chain tested",
    ],
    "operations": [
        "Credit balance sufficient for expected usage",
        "Per-key credit limits configured",
        "Monitoring updated to track OpenRouter metrics",
        "Alerting on new error codes (402, 408)",
        "Rollback plan documented",
    ],
}

Model ID Migration Map

Direct ProviderOpenRouter ID
gpt-4oopenai/gpt-4o
gpt-4o-miniopenai/gpt-4o-mini
o1openai/o1
claude-3-5-sonnet-20241022anthropic/claude-3.5-sonnet
claude-3-haiku-20240307anthropic/claude-3-haiku
gemini-2.0-flashgoogle/gemini-2.0-flash-001
llama-3.1-8b-instructmeta-llama/llama-3.1-8b-instruct

Comparison Test Script

def compare_migration(prompt: str, old_model: str, new_model: str):
    """Run same prompt through old and new configurations to compare."""
    import time

    # New: OpenRouter
    or_client = OpenAI(
        base_url="https://openrouter.ai/api/v1",
        api_key=os.environ["OPENROUTER_API_KEY"],
        default_headers={"HTTP-Referer": "https://my-app.com", "X-Title": "migration-test"},
    )

    start = time.monotonic()
    or_response = or_client.chat.completions.create(
        model=new_model,
        messages=[{"role": "user", "content": prompt}],
        max_tokens=200, temperature=0,
    )
    or_latency = (time.monotonic() - start) * 1000

    return {
        "openrouter": {
            "model": or_response.model,
            "content": or_response.choices[0].message.content[:100],
            "tokens": or_response.usage.prompt_tokens + or_response.usage.completion_tokens,
            "latency_ms": round(or_latency),
        },
    }

# Test
result = compare_migration(
    "What is 2+2?",
    old_model="gpt-4o",
    new_model="openai/gpt-4o",
)
print(json.dumps(result, indent=2))

Feature Flag Migration

import os

USE_OPENROUTER = os.environ.get("USE_OPENROUTER", "false").lower() == "true"

def get_llm_client():
    """Feature flag for gradual migration."""
    if USE_OPENROUTER:
        return OpenAI(
            base_url="https://openrouter.ai/api/v1",
            api_key=os.environ["OPENROUTER_API_KEY"],
            default_headers={"HTTP-Referer": "https://my-app.com", "X-Title": "my-app"},
        )
    else:
        return OpenAI(api_key=os.environ["OPENAI_API_KEY"])

def get_model_id(model: str) -> str:
    """Map model IDs based on current backend."""
    if USE_OPENROUTER and "/" not in model:
        MODEL_MAP = {"gpt-4o": "openai/gpt-4o", "gpt-4o-mini": "openai/gpt-4o-mini"}
        return MODEL_MAP.get(model, f"openai/{model}")
    return model

Output

  • Migrated client initialization code: 3 changed lines (base_url, api_key, headers) plus provider-prefixed model IDs across routes/configs
  • A comparison test JSON per prompt with the served model, a content preview, combined token count, and latency_ms
  • A four-category migration checklist (config / code / testing / operations) to track cutover readiness
  • A feature-flagged get_llm_client() that flips between direct OpenAI and OpenRouter via the USE_OPENROUTER env var

Examples

Verify a migrated model on the same prompt before flipping traffic:

result = compare_migration("What is 2+2?", old_model="gpt-4o", new_model="openai/gpt-4o")
print(json.dumps(result, indent=2))
# {
#   "openrouter": {
#     "model": "openai/gpt-4o",
#     "content": "2 + 2 = 4",
#     "tokens": 21,
#     "latency_ms": 934
#   }
# }

Expect OpenRouter latency to run ~50-100ms above the direct API. More worked examples: references/examples.md.

Error Handling

ErrorCauseFix
401 after migrationUsing old API key with new base_urlUpdate to OpenRouter API key (sk-or-v1-...)
model_not_foundMissing provider prefixAdd openai/ or anthropic/ prefix to model ID
Different response formatSwitched from Anthropic SDK to OpenAI SDKUpdate response parsing: .choices[0].message.content
Higher latencyOpenRouter proxy overheadExpected: +50-100ms; use streaming to mask it

Enterprise Considerations

  • Migration from direct provider to OpenRouter requires only 3 lines of code change
  • Use feature flags for gradual migration (10% -> 50% -> 100%)
  • Run comparison tests on critical prompts before full migration
  • OpenRouter adds ~50-100ms overhead; use streaming to mask perceived latency
  • Keep direct provider keys active during migration for quick rollback
  • Update monitoring dashboards for OpenRouter-specific metrics (generation_id, provider used)

References

When not to use it

  • When the application requires features exclusive to a specific provider SDK
  • When immediate cutover without testing is required

Prerequisites

OpenRouter API keyExisting OpenAI or Anthropic integrationPython 3.8+ or Node.js 18+

Limitations

  • Expect 50-100ms latency overhead due to proxying
  • Requires updating response parsing logic when switching from Anthropic SDK

How it compares

It automates the configuration changes and provides a structured testing approach compared to manual refactoring.

Compared to similar skills

openrouter-upgrade-migration side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
openrouter-upgrade-migration (this skill)027dReviewIntermediate
mistral-migration-deep-dive027dReviewAdvanced
apollo-upgrade-migration127dCautionIntermediate
exa-migration-deep-dive127dReviewIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

More by jeremylongshore

View all by jeremylongshore

analyzing-logs

jeremylongshore

Analyze application logs to detect performance issues, identify error patterns, and improve stability by extracting key insights.

14123

ollama-setup

jeremylongshore

Configure auto-configure Ollama when user needs local LLM deployment, free AI alternatives, or wants to eliminate hosted API costs. Trigger phrases: "install ollama", "local AI", "free LLM", "self-hosted AI", "replace OpenAI", "no API costs". Use when appropriate context detected. Trigger with relevant phrases based on skill purpose.

1167

backtesting-trading-strategies

jeremylongshore

Backtest crypto and traditional trading strategies against historical data. Calculates performance metrics (Sharpe, Sortino, max drawdown), generates equity curves, and optimizes strategy parameters. Use when user wants to test a trading strategy, validate signals, or compare approaches. Trigger with phrases like "backtest strategy", "test trading strategy", "historical performance", "simulate trades", "optimize parameters", or "validate signals".

1071

generating-database-seed-data

jeremylongshore

Process this skill enables AI assistant to generate realistic test data and database seed scripts for development and testing environments. it uses faker libraries to create realistic data, maintains relational integrity, and allows configurable data volumes. u... Use when working with databases or data models. Trigger with phrases like 'database', 'query', or 'schema'.

1033

cursor-codebase-indexing

jeremylongshore

Execute set up and optimize Cursor codebase indexing. Triggers on "cursor index setup", "codebase indexing", "index codebase", "cursor semantic search". Use when working with cursor codebase indexing functionality. Trigger with phrases like "cursor codebase indexing", "cursor indexing", "cursor".

885

testing-mobile-apps

jeremylongshore

Execute mobile app testing on iOS and Android devices/simulators. Use when performing specialized testing. Trigger with phrases like "test mobile app", "run iOS tests", or "validate Android functionality".

810

You might also like

mistral-migration-deep-dive

jeremylongshore

Execute Mistral AI major migrations and re-architecture strategies. Use when migrating to Mistral AI from another provider, performing major refactoring, or re-platforming existing AI integrations to Mistral AI. Trigger with phrases like "migrate to mistral", "mistral migration", "switch to mistral", "mistral replatform", "openai to mistral".

03

apollo-upgrade-migration

jeremylongshore

Plan and execute Apollo.io SDK upgrades. Use when upgrading Apollo API versions, migrating to new endpoints, or updating deprecated API usage. Trigger with phrases like "apollo upgrade", "apollo migration", "update apollo api", "apollo breaking changes", "apollo deprecation".

11

exa-migration-deep-dive

jeremylongshore

Execute Exa major re-architecture and migration strategies with strangler fig pattern. Use when migrating to or from Exa, performing major version upgrades, or re-platforming existing integrations to Exa. Trigger with phrases like "migrate exa", "exa migration", "switch to exa", "exa replatform", "exa upgrade major".

10

instantly-upgrade-migration

jeremylongshore

Analyze, plan, and execute Instantly SDK upgrades with breaking change detection. Use when upgrading Instantly SDK versions, detecting deprecations, or migrating to new API versions. Trigger with phrases like "upgrade instantly", "instantly migration", "instantly breaking changes", "update instantly SDK", "analyze instantly version".

10

perplexity-upgrade-migration

jeremylongshore

Analyze, plan, and execute Perplexity SDK upgrades with breaking change detection. Use when upgrading Perplexity SDK versions, detecting deprecations, or migrating to new API versions. Trigger with phrases like "upgrade perplexity", "perplexity migration", "perplexity breaking changes", "update perplexity SDK", "analyze perplexity version".

10

aid-update-api

AndreVianna

>

00

Search skills

Search the agent skills registry