# How to Add Custom Providers to OmniRoute's Provider Catalog: A Complete Developer Guide

> Learn to add custom providers to OmniRoute's catalog. This developer guide shows how to register, prefix, and persist your provider details for seamless integration.

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

---

**To add a custom provider to OmniRoute, you need to: (1) prefix your provider ID with `openai-compatible-` or `anthropic-compatible-`, (2) register it in the provider registry at [`src/open-sse/config/providerRegistry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/open-sse/config/providerRegistry.ts), and (3) persist the connection details via the dashboard, CLI, or API.**

Adding custom providers lets you route any OpenAI-compatible or Anthropic-compatible endpoint through OmniRoute's unified URL. This guide walks you through the exact implementation based on the OmniRoute source code, covering the three-layer architecture that makes custom providers work.

## Understanding the Three-Layer Architecture

OmniRoute's custom provider system consists of three interconnected layers:

| Layer | Purpose | Source File |
|-------|---------|-------------|
| **Constants** | Defines compatibility prefixes that identify API shapes | [`src/shared/constants/providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers.ts) |
| **Registry** | Maps provider IDs to URL builders and authentication logic | [`src/open-sse/config/providerRegistry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/open-sse/config/providerRegistry.ts) |
| **Database/UI** | Persists connection credentials and exposes provider selection | [`src/lib/db/providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/db/providers.ts) & Settings → Providers UI |

All three layers work together so that once you register a custom provider, it behaves identically to built-in providers in routing combos and direct API calls.

## Step 1: Choose the Compatibility Prefix

Custom providers are identified by mandatory prefixes that tell OmniRoute which API schema to use. These prefixes are defined in **[`src/shared/constants/providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers.ts)**:

- **`openai-compatible-`** — Provider implements OpenAI's Chat/Completion JSON schema
- **`anthropic-compatible-`** — Provider implements Anthropic's Chat schema

Your provider ID must start with one of these prefixes. For example, a custom provider named `my-ai-service` that follows the OpenAI spec must be registered as `openai-compatible-my-ai-service`.

## Step 2: Register the Provider in the Registry

The **provider registry** in [`src/open-sse/config/providerRegistry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/open-sse/config/providerRegistry.ts) is a plain JavaScript object that OmniRoute uses to build request URLs and authentication headers. For most custom providers, you only need a minimal entry:

```typescript
// src/open-sse/config/providerRegistry.ts
export const providerRegistry = {
  // ... existing providers ...
  
  // Custom OpenAI-compatible provider
  'openai-compatible-my-custom-ai': {
    baseUrl: (conn) => conn.baseUrl,        // Retrieved from database record
    authHeader: (conn) => `Bearer ${conn.apiKey}`,
    // No transformer needed — default OpenAI executor handles the rest
  },
  
  // Custom Anthropic-compatible provider (if needed)
  // 'anthropic-compatible-my-custom-ai': { ... }
};

```

The registry entry is consumed by **[`open-sse/executors/default.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/executors/default.ts)**. Because the shape matches the default executor, no additional code is required for standard OpenAI-compatible endpoints.

## Step 3: Persist the Provider Connection

Once the registry entry exists, you must store the actual connection credentials. OmniRoute provides three equivalent methods:

### Dashboard UI

1. Navigate to **Settings → Providers**
2. Click **"Add Custom Provider"**
3. Complete the form:
   - **Name** — Display label for the provider
   - **ID** — Must match the registry key (e.g., `openai-compatible-my-custom-ai`)
   - **Base URL** — Root API endpoint (e.g., `https://api.myservice.com/v1`)
   - **API Key** — Encrypted and stored in SQLite
   - **Headers** — Optional extra headers (e.g., `x-custom-header`)
4. Save — **[`src/lib/db/providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/db/providers.ts)** persists the record

### CLI

```bash
omniroute providers add \
  --type openai-compatible \
  --id my-custom-ai \
  --url https://api.myservice.com/v1 \
  --key $MY_API_KEY

```

The CLI writes identical database rows to the UI method, making the provider immediately available to routing logic.

### Direct API

```bash
POST /api/v1/providers
Content-Type: application/json
Authorization: Bearer ADMIN_API_KEY

{
  "id": "openai-compatible-my-custom-ai",
  "name": "My Custom AI",
  "baseUrl": "https://api.myservice.com/v1",
  "apiKey": "sk-...",
  "extraHeaders": { "x-custom-header": "value" }
}

```

The route handler invokes the same database layer ([`src/lib/db/providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/db/providers.ts)) as the other methods.

## Step 4: Use Your Custom Provider

After registration, your provider appears automatically in:

- **Model selectors** — Dashboard "Create Combo" dialog and CLI `omniroute combos create`
- **Routing combos** — Select the provider, choose its models, and configure failover strategies
- **Direct requests** — Call `/v1/chat/completions` with `provider=openai-compatible-my-custom-ai` or include `providerId` in the request body

The combo engine in **[`open-sse/services/combo.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/combo.ts)** resolves targets by matching provider ID, requiring no additional code changes.

## Optional: Advanced Customization for Non-Standard Providers

If your provider requires non-standard authentication or request-body formats, extend the system at two integration points:

1. **Custom executor** — Create a new file in `open-sse/executors/` extending `BaseExecutor`
2. **Custom translator** — Add request/response mapping in `open-sse/translator/`

Both are auto-discovered by the executor factory at **[`open-sse/executors/index.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/executors/index.ts)**. Most OpenAI-compatible endpoints do not need this; the default executor works without modification.

## Verification Steps

Confirm your custom provider is fully operational:

```bash

# 1. List registered providers

omniroute providers list

# 2. Test with a direct chat request

omniroute chat \
  --provider openai-compatible-my-custom-ai \
  --model gpt-4o-mini \
  "Hello, custom provider!"

# 3. Review OmniRoute logs for built URL and auth header

```

The logs will show the resolved `baseUrl` and `Authorization` header reflecting your stored configuration.

## Summary

- **Custom providers** extend OmniRoute to any OpenAI-compatible or Anthropic-compatible endpoint
- **Prefix requirement** — Use `openai-compatible-` or `anthropic-compatible-` identifier prefixes defined in [`src/shared/constants/providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers.ts)
- **Registry entry** — Add minimal configuration in [`src/open-sse/config/providerRegistry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/open-sse/config/providerRegistry.ts) pointing to database-backed connection details
- **Persistence options** — Dashboard UI, CLI, or REST API all write to [`src/lib/db/providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/db/providers.ts)
- **Immediate availability** — Once stored, custom providers work in routing combos and direct calls without further code changes
- **Extensibility** — Non-standard providers can add custom executors and translators in `open-sse/executors/` and `open-sse/translator/`

## Frequently Asked Questions

### What API shapes does OmniRoute support for custom providers?

OmniRoute supports **OpenAI-compatible** and **Anthropic-compatible** API schemas. You must prefix your provider ID accordingly—`openai-compatible-` or `anthropic-compatible-`—so the executor selects the correct request builder and response parser.

### Do I need to modify the codebase to add a custom provider?

For standard OpenAI-compatible endpoints, **no code changes are required** beyond adding a registry entry. The default executor in [`open-sse/executors/default.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/executors/default.ts) handles request building. Only non-standard authentication schemes or request formats require custom executors or translators.

### Where are custom provider credentials stored?

All credentials—including base URL, API key, and optional headers—are stored in OmniRoute's **SQLite database** via [`src/lib/db/providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/db/providers.ts). API keys are encrypted at rest. The same storage layer serves the dashboard, CLI, and REST API.

### Can I use custom providers in routing combos immediately after creation?

Yes. Once persisted through any method (UI, CLI, or API), the provider appears in model selectors and can be added to routing combos instantly. The combo engine ([`open-sse/services/combo.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/combo.ts)) resolves provider IDs dynamically from the database.