How to Implement Custom Providers in OmniRoute Using OpenAI and Anthropic Compatible Prefixes
OmniRoute enables custom LLM providers by recognizing provider IDs prefixed with openai-compatible- or anthropic-compatible-, automatically routing requests through specialized executors and translators without requiring core code modifications.
OmniRoute is an open-source LLM routing framework that simplifies the integration of custom endpoints. By leveraging specific identifier prefixes, you can implement custom providers in OmniRoute using OpenAI and Anthropic compatible prefixes to connect self-hosted or third-party APIs. The system automatically detects these prefixes in open-sse/config/providerRegistry.ts and applies the appropriate execution logic.
Understanding the Prefix-Based Provider System
OmniRoute treats any provider ID starting with openai-compatible- or anthropic-compatible- as a specialized service requiring protocol-specific handling. This architecture allows the framework to support hundreds of built-in providers while remaining extensible for custom deployments.
OpenAI-Compatible Prefix Handling
When a provider ID begins with openai-compatible-, OmniRoute routes the request through the DefaultExecutor defined in open-sse/executors/default.ts. This executor expects standard OpenAI API formats for chat completions, embeddings, and function calling. The registry extracts the suffix after the prefix to identify the specific endpoint configuration, such as openai-compatible-my-selfhosted.
Anthropic-Compatible Prefix Handling
For IDs starting with anthropic-compatible-, OmniRoute utilizes the translation layer in open-sse/translator/anthropic.ts. This component converts Anthropic-style message payloads to the OpenAI format before execution, then transforms responses back to the standard OmniRoute schema. This enables seamless integration of Anthropic API-compatible services without modifying client code.
Step-by-Step Implementation Guide
Implementing a custom provider requires three main steps: defining the identifier, configuring connection parameters, and validating the integration.
Step 1: Define the Provider ID
Choose a unique provider ID following the prefix conventions:
openai-compatible-my-selfhosted
anthropic-compatible-my-service
The suffix (my-selfhosted or my-service) must be unique within your OmniRoute instance. According to src/shared/validation/providerSchema.ts, the validation logic accepts any alphanumeric suffix after the recognized prefix.
Step 2: Configure Connection Details
Register the provider in the database via src/lib/db/providers.ts. The system uses the provider_connections table with the following required fields:
id: The full provider ID including the prefixbaseUrl: The root endpoint URL (e.g.,https://api.my-service.com/v1)apiKey: Optional authentication token; OpenAI-compatible providers support anonymous access if the remote service permitstype: Inferred from the prefix (openai-compatibleoranthropic-compatible)
Step 3: Testing the Configuration
Test the integration using the standard OmniRoute API endpoint. When a request reaches the routing layer at src/app/api/v1/*/route.ts, the registry extracts the provider ID from the model parameter format: openai-compatible-my-selfhosted/gpt-4 or anthropic-compatible-my-service/claude-2.1.
Technical Implementation Details
The prefix system relies on specific modules to handle provider resolution and execution.
Provider Registry Logic
In open-sse/config/providerRegistry.ts, the registry parses incoming provider IDs and applies prefix rules to instantiate runtime configurations. The logic determines whether to invoke the OpenAI-compatible path or route through the Anthropic translator based on the prefix match. The registry also handles fallback mechanisms and validation against src/shared/validation/providerSchema.ts.
OpenAI-Compatible Execution
The DefaultExecutor in open-sse/executors/default.ts manages all OpenAI-compatible providers. It constructs HTTP requests to the custom baseUrl, forwards authentication headers, and processes streaming or non-streaming responses. This executor supports chat completions, embeddings, and tool calling when the remote API adheres to OpenAI specifications.
Anthropic Translation Layer
For Anthropic-compatible services, open-sse/translator/anthropic.ts performs bidirectional translation. It converts OpenAI-formatted request payloads to Anthropic's message format, including role mappings and content blocks. After receiving the response from the custom endpoint, it translates the Anthropic output back to the OpenAI-compatible schema expected by OmniRoute clients.
Code Examples
Registering a Provider via Database API
import { getDbInstance } from '@/lib/db/core';
import { ProviderConfig } from '@/lib/db/providers';
const db = getDbInstance();
// Register an OpenAI-compatible custom provider
await db.prepare(`
INSERT INTO provider_connections (id, baseUrl, apiKey, type)
VALUES (?, ?, ?, ?)
`).run(
'openai-compatible-my-selfhosted',
'https://my-api.example.com/v1',
'', // Empty string for optional API key
'openai-compatible'
);
// Register an Anthropic-compatible provider
await db.prepare(`
INSERT INTO provider_connections (id, baseUrl, apiKey, type)
VALUES (?, ?, ?, ?)
`).run(
'anthropic-compatible-my-service',
'https://anthropic.mycompany.com/v1',
'my-anthropic-key',
'anthropic-compatible'
);
Making Requests to Custom Providers
OpenAI-compatible request:
curl -X POST https://router.example.com/v1/chat/completions \
-H "Authorization: Bearer $OMNIROUTE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai-compatible-my-selfhosted/gpt-4",
"messages": [{"role": "user", "content": "Explain quantum entanglement"}]
}'
Anthropic-compatible request:
curl -X POST https://router.example.com/v1/chat/completions \
-H "Authorization: Bearer $OMNIROUTE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic-compatible-my-service/claude-2.1",
"messages": [{"role": "user", "content": "Write a haiku"}]
}'
OmniRoute automatically routes these requests to the appropriate executor and applies necessary payload translations for Anthropic-compatible targets.
Summary
- Prefix recognition: OmniRoute detects
openai-compatible-andanthropic-compatible-prefixes inopen-sse/config/providerRegistry.tsto route traffic without code changes. - Automatic execution: OpenAI-compatible providers use
open-sse/executors/default.ts, while Anthropic-compatible services utilizeopen-sse/translator/anthropic.tsfor bidirectional payload conversion. - Simple registration: Add entries to the
provider_connectionstable viasrc/lib/db/providers.tswith the full prefixed ID, base URL, and optional API key. - Standard interface: Access custom providers using the
prefix-suffix/model-nameformat in API requests, maintaining compatibility with existing OmniRoute clients.
Frequently Asked Questions
Do I need to modify OmniRoute source code to add a custom provider?
No. The prefix-based system in open-sse/config/providerRegistry.ts is designed for zero-code customization. Simply register your provider in the database using the appropriate openai-compatible- or anthropic-compatible- prefix, and the existing routing logic in src/app/api/v1/*/route.ts will automatically handle requests.
What authentication methods are supported for custom providers?
OmniRoute supports API key authentication via the apiKey field in the provider_connections table. For OpenAI-compatible providers, you can leave this field empty if the remote service permits anonymous access. The DefaultExecutor passes the key in the Authorization header using the standard Bearer format.
How does OmniRoute handle model names for custom providers?
Use the format provider-id/model-name in API requests, such as openai-compatible-my-selfhosted/llama-3 or anthropic-compatible-my-service/claude-3. The routing layer splits this string to identify the provider configuration and passes the model name to the remote endpoint. The providerDisplayLabel utility in src/shared/utils/providerDisplayLabel.ts generates friendly UI labels from these identifiers.
Can I use streaming responses with custom providers?
Yes. Both the DefaultExecutor and the Anthropic translation layer support streaming responses. When the remote OpenAI-compatible or Anthropic-compatible endpoint returns server-sent events (SSE), OmniRoute streams these through to the client without buffering, maintaining low latency for real-time applications.
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 →