How to Add a Custom Provider to OmniRoute’s 290-Provider Catalog
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.
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.
mkdir open-sse/config/providers/registry/myai
2. Define the RegistryEntry
Create an index.ts file inside your new directory that exports a RegistryEntry object. Use the buildOpenAiCompatibleRegistryEntry helper from open-sse/config/providers/shared.ts to minimize boilerplate for OpenAI-compatible APIs.
// 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 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.
// 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 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/.
// 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:
executor: "myai", // matches the filename myai.ts in open-sse/executors/
The executor factory in open-sse/executors/index.ts loads the class automatically when routing requests to your provider.
Key Source Files
open-sse/config/providers/shared.ts– Contains thebuildOpenAiCompatibleRegistryEntryhelper and type definitions forRegistryEntryandRegistryModel.open-sse/config/providers/index.ts– The central hub that exports the globalREGISTRYmap. This is where you import new providers.open-sse/config/providerRegistry.ts– Generates derived structures includingPROVIDERS,PROVIDER_MODELS, and alias-to-ID mappings from theREGISTRYobject.open-sse/executors/base.ts– Defines the abstract base class for all executors, specifying the request lifecycle interface.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
RegistryEntryobjects underopen-sse/config/providers/registry/<provider-id>/. - Minimal setup: Use
buildOpenAiCompatibleRegistryEntryinshared.tsto create compliant entries with minimal boilerplate. - Central registration: Import your provider into
open-sse/config/providers/index.tsand add it to theREGISTRYexport. - Automatic generation: Legacy maps, model lists, and executor lookups are generated automatically by
open-sse/config/providerRegistry.tsonce 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 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, the system immediately recognizes it. The code in 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). 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →