# How to Migrate from LiteLLM or OpenRouter to OmniRoute: A Complete Guide

> Seamlessly migrate from LiteLLM or OpenRouter to OmniRoute. Deploy the binary, add API keys, and update your base URL for enhanced routing capabilities.

- Repository: [Diego Rodrigues de Sa e Souza/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- Tags: migration-guide
- Published: 2026-08-13

---

**Migrate from LiteLLM or OpenRouter to OmniRoute by deploying the self-hosted binary, registering your existing API keys, and updating your client base URL to `http://localhost:20128/v1/` while optionally adopting auto-combo routing syntax.**

OmniRoute is a self-hosted, all-in-one LLM routing layer that replaces both the SDK-style approach of **LiteLLM** and the hosted SaaS gateway of **OpenRouter**. This guide walks you through the exact migration steps based on the source code in `diegosouzapw/OmniRoute`, with specific references to configuration files, provider registries, and the auto-combo routing engine.

## Understanding the Migration Path

Moving from LiteLLM or OpenRouter to OmniRoute involves three core steps. Each step maps directly to architectural components in the OmniRoute codebase.

### Step 1: Deploy OmniRoute and Initialize the SQLite Data Store

OmniRoute stores every provider credential, model catalog, combo definition, and rate-limit state in a single, version-controlled SQLite database. This differs fundamentally from LiteLLM's in-process caching, which loses state on restart.

The default data directory is `~/.omniroute/`. Database initialization and migrations are handled in [`src/lib/db/core.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/db/core.ts). According to the database guide in [`docs/ops/DATABASE_GUIDE.md`](https://github.com/diegosouzapw/OmniRoute/blob/main/docs/ops/DATABASE_GUIDE.md) (lines 9-20), the SQLite backend ensures persistence for connection cooldowns, circuit-breaker status, quota tracking, and model-level lockouts.

```bash

# Install OmniRoute globally

npm install -g omniroute

# Start the server on default port 20128

omniroute serve

```

### Step 2: Register Your Existing API Keys

OmniRoute's provider registry in [`open-sse/config/providerRegistry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/config/providerRegistry.ts) automatically syncs the live model catalog for each provider you add. This includes native support for OpenRouter as a provider itself.

Register your existing keys via the CLI:

```bash

# Add an OpenRouter connection

omniroute providers add openrouter --api-key sk-your-openrouter-key

# Add a direct OpenAI connection (if you had one in LiteLLM)

omniroute providers add openai --api-key sk-your-openai-key

# Verify all registered providers and their synced models

omniroute providers list

```

The OpenRouter entry is documented in [`docs/reference/PROVIDER_REFERENCE.md`](https://github.com/diegosouzapw/OmniRoute/blob/main/docs/reference/PROVIDER_REFERENCE.md) at line 279. The `DefaultExecutor` in [`open-sse/executors/DefaultExecutor.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/executors/DefaultExecutor.ts) handles all provider types uniformly—adding or removing a provider only touches the registry, requiring no per-client code changes.

### Step 3: Point Client Code at the OmniRoute HTTP API

Update your application to call OmniRoute's OpenAI-compatible endpoint at `http://127.0.0.1:20128/v1/`. The main chat completions route is implemented in [`src/app/api/v1/chat/completions/route.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/app/api/v1/chat/completions/route.ts).

**Before (LiteLLM Python):**

```python
import openai

client = openai.OpenAI(
    base_url="https://openrouter.ai/api/v1",
    api_key="sk-your-openrouter-key"
)

response = client.chat.completions.create(
    model="openrouter/anthropic/claude-3.5-sonnet:free",
    messages=[{"role": "user", "content": "Explain the migration steps"}],
    temperature=0.2
)

```

**After (OmniRoute):**

```bash
curl -X POST http://127.0.0.1:20128/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk-your-omniroute-key" \
  -d '{
        "model": "auto/coding:free",
        "messages": [{"role":"user","content":"Explain the migration steps"}],
        "temperature": 0.2
      }'

```

You can also preserve existing OpenRouter model strings while gaining OmniRoute's resilience features:

```bash
curl -X POST http://127.0.0.1:20128/v1/chat/completions \
  -H "Authorization: Bearer $(omniroute auth export --json | jq -r .apiKey)" \
  -H "Content-Type: application/json" \
  -d '{
        "model": "openrouter/anthropic/claude-3.5-sonnet:free",
        "messages": [{"role":"user","content":"What’s new in v3.8.50?"}]
      }'

```

## Key Architectural Differences That Simplify Migration

### Unified Provider Layer

All providers—OpenAI, Anthropic, OpenRouter, and others—are represented by a single `DefaultExecutor` in [`open-sse/executors/DefaultExecutor.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/executors/DefaultExecutor.ts). This abstraction means you can switch between direct provider access and aggregated access without changing client code.

### SQLite-Backed State Persistence

Unlike LiteLLM's in-process caching, OmniRoute persists all state to SQLite. The core database implementation in [`src/lib/db/core.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/db/core.ts) handles migrations and automatic backup. Server restarts preserve rate-limit information, circuit-breaker status, and quota tracking that would otherwise be lost.

### Auto-Combo Routing with OpenRouter-Style Suffixes

The auto-combo engine in [`open-sse/services/autoCombo/suffixComposition.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/autoCombo/suffixComposition.ts) interprets `auto/<category>:<tier>` suffixes. This syntax, inspired by OpenRouter, lets you request capabilities rather than specific models:

- **`auto/coding:fast`** — Best coding model optimized for speed
- **`auto/vision:pro`** — Top-tier vision-capable model
- **`auto/reasoning:cheap`** — Most cost-effective reasoning model

As documented in [`docs/routing/AUTO-COMBO.md`](https://github.com/diegosouzapw/OmniRoute/blob/main/docs/routing/AUTO-COMBO.md) (lines 31-33), the engine scores available models against your requested capability and tier, then selects the optimal provider.

### Zero-Migration Credential Support

Public upstream OAuth credentials (like Google client IDs) are automatically resolved via `resolvePublicCred()` in [`open-sse/utils/publicCreds.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/utils/publicCreds.ts). Environment variables stored in `.env` for LiteLLM or OpenRouter continue to work without modification.

### Robust Quota and Error Handling

OpenRouter-specific quota counters and `402` rate-limit handling are integrated into OmniRoute's quota-share subsystem in [`open-sse/services/quotaShare.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/quotaShare.ts). Instead of abrupt failures, you get graceful cooldowns with persistent tracking. See [`docs/routing/QUOTA_SHARE.md`](https://github.com/diegosouzapw/OmniRoute/blob/main/docs/routing/QUOTA_SHARE.md) (line 33) for implementation details.

## When to Migrate: OmniRoute vs. LiteLLM vs. OpenRouter

The comparison table in [`docs/comparison/OMNIROUTE_VS_ALTERNATIVES.md`](https://github.com/diegosouzapw/OmniRoute/blob/main/docs/comparison/OMNIROUTE_VS_ALTERNATIVES.md) (lines 14-20) clarifies the trade-offs:

| Aspect | OmniRoute | LiteLLM | OpenRouter (SaaS) |
|--------|-----------|---------|-------------------|
| Deployment | Self-hosted | Python library/with hosted proxy | Fully hosted |
| State persistence | SQLite-backed | In-process only | Cloud-managed |
| Rate limit control | Full visibility and customization | Limited | Opaque |
| Routing policies | Custom combo strategies | Basic fallback | Provider-defined |
| Circuit breakers | Built-in | Manual implementation | None |

**Choose OmniRoute when** you need self-hosted reliability, auditability, custom routing strategies, or persistent quota tracking that survives restarts.

## Essential Migration Files

| File | Purpose in Migration |
|------|----------------------|
| [`docs/comparison/OMNIROUTE_VS_ALTERNATIVES.md`](https://github.com/diegosouzapw/OmniRoute/blob/main/docs/comparison/OMNIROUTE_VS_ALTERNATIVES.md) | Feature comparison for decision-making |
| [`src/app/api/v1/chat/completions/route.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/app/api/v1/chat/completions/route.ts) | OpenAI-compatible endpoint you call instead of OpenRouter |
| [`open-sse/config/providerRegistry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/config/providerRegistry.ts) | Where you add or edit provider connections |
| [`src/lib/db/core.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/db/core.ts) | SQLite bootstrap, migrations, and backup |
| [`open-sse/services/autoCombo/suffixComposition.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/autoCombo/suffixComposition.ts) | Parsing logic for `auto/<category>:<tier>` suffixes |
| [`docs/reference/ENVIRONMENT.md`](https://github.com/diegosouzapw/OmniRoute/blob/main/docs/reference/ENVIRONMENT.md) | Environment variables for data directory and encryption |

## Complete Migration Checklist

- [x] **Install and start**: `npm install -g omniroute` → `omniroute serve`
- [x] **Import keys**: `omniroute providers add <provider> --api-key <key>` for each existing credential
- [x] **Verify catalog**: `omniroute providers list` to confirm model sync
- [x] **Update endpoints**: Change base URL to `http://<host>:20128/v1/` in all clients
- [x] **Optional: Adopt auto-combos**: Replace hard-coded model IDs with `auto/<category>:<tier>` syntax
- [x] **Validate deployment**: Run `omniroute health` and `omniroute providers test-all`

## Summary

- **OmniRoute replaces both LiteLLM and OpenRouter** with a self-hosted, SQLite-backed routing layer
- **Three-step migration**: deploy binary, register existing keys, update endpoint URL
- **Keep existing model strings** or adopt `auto/<category>:<tier>` combos for intelligent routing
- **Gain persistent state**, circuit breakers, and quota tracking that LiteLLM lacks
- **Zero credential changes required**—existing `.env` variables work via [`publicCreds.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/publicCreds.ts) resolution

## Frequently Asked Questions

### Can I use OpenRouter as a provider within OmniRoute?

Yes. Register OpenRouter as one of many providers using `omniroute providers add openrouter --api-key <key>`. The provider registry in [`open-sse/config/providerRegistry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/config/providerRegistry.ts) automatically syncs OpenRouter's live model catalog. You can then route to OpenRouter models directly or through OmniRoute's auto-combo engine.

### Do I need to change my existing model identifiers?

No. OmniRoute's [`suffixComposition.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/suffixComposition.ts) parser accepts OpenRouter-style model strings like `openrouter/anthropic/claude-3.5-sonnet:free` without modification. However, adopting `auto/<category>:<tier>` syntax unlocks OmniRoute's capability-based routing and failover features.

### How does OmniRoute handle rate limits compared to LiteLLM?

LiteLLM caches rate-limit state in-memory and loses it on process restart. OmniRoute persists all quota counters, circuit-breaker states, and cooldown timers to SQLite via [`src/lib/db/core.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/db/core.ts). The quota-share subsystem in [`open-sse/services/quotaShare.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/quotaShare.ts) also implements graceful degradation with `402` handling that LiteLLM does not provide natively.

### What happens to my LiteLLM configuration files?

LiteLLM YAML configurations are not automatically imported. You must recreate provider entries using `omniroute providers add`. However, environment variables referenced in LiteLLM configs (API keys, base URLs) typically require no changes due to OmniRoute's automatic public credential resolution in [`open-sse/utils/publicCreds.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/utils/publicCreds.ts).