# How to Add a Custom Provider to OmniRoute’s 290-Provider Catalog

> Learn how to add a custom provider to OmniRoute's extensive catalog. Create a new registry module to define endpoints, auth, and models for seamless integration.

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

---

**You can add a custom provider to OmniRoute by creating a new registry module that exports a `RegistryEntry` object describing the provider’s endpoints, authentication, and models, then importing it into the central `REGISTRY` map in [`open-sse/config/providers/index.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/config/providers/index.ts).**

OmniRoute is an open-source LLM routing platform that maintains a single source of truth for every provider inside `open-sse/config/providers/registry/`. When you add a custom provider to OmniRoute, you create a new registry entry and stitch it into the global `REGISTRY` export—everything else, including legacy provider lists, alias mappings, and executor resolution, is generated automatically by the framework.

## Step-by-Step Guide to Adding a Custom Provider

### 1. Create the Provider Directory

Create a new directory under `open-sse/config/providers/registry/` using your provider’s unique identifier. This directory will house the provider’s configuration module.

```bash
mkdir open-sse/config/providers/registry/myai

```

### 2. Define the RegistryEntry

Create an [`index.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/index.ts) file inside your new directory that exports a `RegistryEntry` object. Use the `buildOpenAiCompatibleRegistryEntry` helper from [`open-sse/config/providers/shared.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/config/providers/shared.ts) to minimize boilerplate for OpenAI-compatible APIs.

```typescript
// File: open-sse/config/providers/registry/myai/index.ts
import type { RegistryEntry } from "../../shared.ts";
import { buildOpenAiCompatibleRegistryEntry } from "../../shared.ts";

export const myaiProvider: RegistryEntry = buildOpenAiCompatibleRegistryEntry({
  id: "myai",
  alias: "myai",
  baseUrl: "https://api.myai.com/v1/chat/completions",
  modelsUrl: "https://api.myai.com/v1/models",
  authType: "apikey",
  authHeader: "bearer",
  models: [
    { id: "my-model-1", name: "My Model 1", supportsReasoning: true },
    { id: "my-model-2", name: "My Model 2", contextLength: 128000 },
  ],
});

```

The `buildOpenAiCompatibleRegistryEntry` function automatically sets common fields like `format: "openai"` and `executor: "default"`, reducing the configuration required to add a custom provider to OmniRoute.

### 3. Register in the Global Catalog

Import your new provider into [`open-sse/config/providers/index.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/config/providers/index.ts) and add it to the exported `REGISTRY` object. This step stitches your provider into the catalog so routing strategies and the `/v1/models` endpoint can discover it.

```typescript
// File: open-sse/config/providers/index.ts
import { myaiProvider } from "./registry/myai/index.ts";

export const REGISTRY: Record<string, RegistryEntry> = {
  // existing entries like fireworks, openai, anthropic...
  myai: myaiProvider,   // <- add your custom provider here
};

```

Once imported, functions like `getRegistryEntry` and `generateModels` defined in [`open-sse/config/providerRegistry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/config/providerRegistry.ts) automatically include your provider in the runtime system.

### 4. Optionally Implement a Custom Executor

If your provider requires special request handling—such as multipart uploads, non-standard URL building, or custom header injection—create a custom executor in `open-sse/executors/`.

```typescript
// File: open-sse/executors/myai.ts
import { DefaultExecutor } from "./default.ts";

export class MyAiExecutor extends DefaultExecutor {
  protected buildUrl(model: string, stream: boolean): string {
    const base = this.entry.baseUrl!;
    const path = stream ? "/v1/chat/stream" : "/v1/chat/completions";
    return `${base}${path}`;
  }
}

```

Reference the custom executor in your `RegistryEntry`:

```typescript
executor: "myai",  // matches the filename myai.ts in open-sse/executors/

```

The executor factory in [`open-sse/executors/index.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/executors/index.ts) loads the class automatically when routing requests to your provider.

## Key Source Files

- **[`open-sse/config/providers/shared.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/config/providers/shared.ts)** – Contains the `buildOpenAiCompatibleRegistryEntry` helper and type definitions for `RegistryEntry` and `RegistryModel`.
- **[`open-sse/config/providers/index.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/config/providers/index.ts)** – The central hub that exports the global `REGISTRY` map. This is where you import new providers.
- **[`open-sse/config/providerRegistry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/config/providerRegistry.ts)** – Generates derived structures including `PROVIDERS`, `PROVIDER_MODELS`, and alias-to-ID mappings from the `REGISTRY` object.
- **[`open-sse/executors/base.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/executors/base.ts)** – Defines the abstract base class for all executors, specifying the request lifecycle interface.
- **[`open-sse/executors/default.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/executors/default.ts)** – The default OpenAI-compatible executor used by most providers in the catalog.

## Summary

- **Single source of truth**: OmniRoute stores all provider metadata in `RegistryEntry` objects under `open-sse/config/providers/registry/<provider-id>/`.
- **Minimal setup**: Use `buildOpenAiCompatibleRegistryEntry` in [`shared.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/shared.ts) to create compliant entries with minimal boilerplate.
- **Central registration**: Import your provider into [`open-sse/config/providers/index.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/config/providers/index.ts) and add it to the `REGISTRY` export.
- **Automatic generation**: Legacy maps, model lists, and executor lookups are generated automatically by [`open-sse/config/providerRegistry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/config/providerRegistry.ts) once your entry is registered.
- **Custom logic**: Implement a custom executor in `open-sse/executors/` only if your provider deviates from standard OpenAI-compatible patterns.

## Frequently Asked Questions

### How does OmniRoute handle provider authentication?

OmniRoute handles authentication through the `authType` and `authHeader` fields in the `RegistryEntry`. Set `authType` to `"apikey"` or `"oauth"` and specify the header format (such as `"bearer"` or `"x-api-key"`) in `authHeader`. The executor automatically injects credentials from environment variables or request headers according to these specifications.

### Can I add a provider that doesn't use OpenAI's API format?

Yes. While the `buildOpenAiCompatibleRegistryEntry` helper is convenient for OpenAI-compatible providers, you can construct a raw `RegistryEntry` object with a custom `format` value and implement a bespoke executor in `open-sse/executors/`. Extend the `DefaultExecutor` class or implement the interface from [`open-sse/executors/base.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/executors/base.ts) to handle non-standard request and response formats.

### What happens after I add my provider to the REGISTRY?

Once your provider is added to the `REGISTRY` export in [`open-sse/config/providers/index.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/config/providers/index.ts), the system immediately recognizes it. The code in [`open-sse/config/providerRegistry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/config/providerRegistry.ts) automatically rebuilds the `PROVIDERS` array, `PROVIDER_MODELS` mapping, and alias lookups. Your provider’s models become available via the `/v1/models` endpoint and can be targeted by routing strategies without restarting the server in development mode.

### Where should I place custom executor logic?

Place custom executor implementations in the `open-sse/executors/` directory, using the provider ID as the filename (e.g., [`myai.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/myai.ts)). Export a class that extends `DefaultExecutor` or implements the base executor interface. Reference the executor by its lowercase filename (without extension) in the `executor` field of your `RegistryEntry`.