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 prefix
  • baseUrl: 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 permits
  • type: Inferred from the prefix (openai-compatible or anthropic-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- and anthropic-compatible- prefixes in open-sse/config/providerRegistry.ts to route traffic without code changes.
  • Automatic execution: OpenAI-compatible providers use open-sse/executors/default.ts, while Anthropic-compatible services utilize open-sse/translator/anthropic.ts for bidirectional payload conversion.
  • Simple registration: Add entries to the provider_connections table via src/lib/db/providers.ts with the full prefixed ID, base URL, and optional API key.
  • Standard interface: Access custom providers using the prefix-suffix/model-name format 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →