# How to Implement Custom Providers in OmniRoute Using OpenAI and Anthropic Compatible Prefixes

> Learn to implement custom LLM providers in OmniRoute with OpenAI and Anthropic compatible prefixes. Effortlessly route requests and extend functionality without core code changes.

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

---

**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`](https://github.com/diegosouzapw/OmniRoute/blob/main/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`](https://github.com/diegosouzapw/OmniRoute/blob/main/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`](https://github.com/diegosouzapw/OmniRoute/blob/main/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`](https://github.com/diegosouzapw/OmniRoute/blob/main/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`](https://github.com/diegosouzapw/OmniRoute/blob/main/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`](https://github.com/diegosouzapw/OmniRoute/blob/main/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`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/validation/providerSchema.ts).

### OpenAI-Compatible Execution

The **DefaultExecutor** in [`open-sse/executors/default.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/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`](https://github.com/diegosouzapw/OmniRoute/blob/main/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

```typescript
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:

```bash
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:

```bash
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`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/config/providerRegistry.ts) to route traffic without code changes.
- **Automatic execution**: OpenAI-compatible providers use [`open-sse/executors/default.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/executors/default.ts), while Anthropic-compatible services utilize [`open-sse/translator/anthropic.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/anthropic.ts) for bidirectional payload conversion.
- **Simple registration**: Add entries to the `provider_connections` table via [`src/lib/db/providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/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`](https://github.com/diegosouzapw/OmniRoute/blob/main/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`](https://github.com/diegosouzapw/OmniRoute/blob/main/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.