# How to Add a New AI Provider to OmniRoute's 341-Provider Catalog

> Learn how to add a new AI provider to OmniRoute's extensive 341-provider catalog. Create a typed provider definition to seamlessly integrate new services into the AI_PROVIDERS proxy.

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

---

**Adding an AI provider to OmniRoute requires creating a typed provider definition in the appropriate authentication category file under `src/shared/constants/providers/`, which the `AI_PROVIDERS` proxy automatically aggregates at runtime.**

OmniRoute maintains its extensive catalog of **341 AI providers** in a structured, Zod-validated registry. Each provider is organized by authentication family—OAuth, API key, web cookie, local, and more. This guide walks through the exact steps to extend the catalog with a new service, based on the implementation in `diegosouzapw/OmniRoute`.

## Understand the Provider Architecture

The provider system splits definitions across multiple files by authentication method, then merges them through a lazy-loading proxy. This design keeps related providers grouped together while presenting a unified interface to the rest of the application.

The aggregation happens in [`src/shared/constants/providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers.ts), where `_PROVIDER_SECTIONS` collects all category exports:

```typescript
// src/shared/constants/providers.ts
const _PROVIDER_SECTIONS = [
  NOAUTH_PROVIDERS,
  OAUTH_PROVIDERS,
  APIKEY_PROVIDERS,
  WEB_COOKIE_PROVIDERS,
  LOCAL_PROVIDERS,
  SEARCH_PROVIDERS,
  AUDIO_ONLY_PROVIDERS,
  UPSTREAM_PROXY_PROVIDERS,
  CLOUD_AGENT_PROVIDERS,
  SYSTEM_PROVIDERS,
];

```

The `AI_PROVIDERS` proxy builds its map on first access via `getOrCreateAiProviders()`, which iterates through sections and assigns them to a shared object. No manual registration is required—additions appear immediately.

## Step 1: Select the Authentication Category

Determine how the new service authenticates users. OmniRoute supports these categories, each with its own file in `src/shared/constants/providers/`:

- **[`oauth.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/oauth.ts)** — OAuth 2.0 flows (authorization code, implicit, etc.)
- **[`apikey.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/apikey.ts)** — Simple API key authentication
- **[`noauth.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/noauth.ts)** — No authentication required
- **[`webcookie.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/webcookie.ts)** — Session-based or cookie authentication
- **[`local.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/local.ts)** — Locally-hosted models (Ollama, LM Studio, etc.)
- **[`search.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/search.ts)** — Search-specific providers
- **[`audioonly.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/audioonly.ts)** — Speech-to-text or text-to-speech services
- **[`upstreamproxy.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/upstreamproxy.ts)** — Proxied upstream connections
- **[`cloudagent.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/cloudagent.ts)** — Cloud-based agent platforms
- **[`system.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/system.ts)** — Internal or system-defined providers

Each file exports a constant (e.g., `OAUTH_PROVIDERS`) containing provider definitions keyed by provider ID.

## Step 2: Define the Provider Object

Add a new entry to the selected category file. The definition must satisfy the `AiProviderDefinition` Zod schema defined in [`src/shared/validation/providerSchema.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/validation/providerSchema.ts). At minimum, include:

- **`id`** — Unique identifier (kebab-case or lowercase)
- **`name`** — Human-readable display name
- **`alias`** — Short shorthand for the provider
- **Auth-specific fields** — Vary by category (e.g., `authUrl`, `tokenUrl` for OAuth; `keyName` for API key)

Here's a complete OAuth example:

```typescript
// src/shared/constants/providers/oauth.ts
import { OAUTH_PROVIDERS as BASE } from "./providers/oauth";

export const OAUTH_PROVIDERS = {
  ...BASE,
  mynewprovider: {
    id: "mynewprovider",
    name: "My New Provider",
    alias: "mynp",
    authUrl: "https://mynewprovider.com/oauth/authorize",
    tokenUrl: "https://mynewprovider.com/oauth/token",
    defaultModel: "gpt-4o",
    supportsChat: true,
    supportsEmbedding: false,
    // Additional capabilities as defined in providerSchema.ts
  },
};

```

For API key providers, the pattern differs slightly:

```typescript
// src/shared/constants/providers/apikey.ts
import { APIKEY_PROVIDERS as BASE } from "./providers/apikey";

export const APIKEY_PROVIDERS = {
  ...BASE,
  anotherprovider: {
    id: "anotherprovider",
    name: "Another Provider",
    alias: "ap",
    keyName: "ANOTHER_PROVIDER_API_KEY",
    defaultBaseUrl: "https://api.anotherprovider.com/v1",
    defaultModel: "claude-3-opus",
    supportsChat: true,
    supportsStreaming: true,
  },
};

```

## Step 3: Verify Schema Compliance

OmniRoute validates every provider at module load time. The `validateProviders` function in [`src/shared/constants/providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers.ts) runs Zod validation against [`providerSchema.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/providerSchema.ts). Any missing required fields or type mismatches throw immediately, preventing invalid providers from entering the catalog.

Before committing, check that your definition includes all fields specified in the schema for your auth category. Common optional extensions include:

- **`supportsImageInput`** — Vision/multimodal capability
- **`supportsToolUse`** — Function calling support
- **`supportsStreaming`** — Server-sent events for responses
- **`maxContextTokens`** — Maximum context window size
- **`pricing`** — Per-token cost structure

## Step 4: Test the Registration

Create a unit test to verify the provider appears correctly in `AI_PROVIDERS`:

```typescript
// tests/unit/providers.test.ts
import { AI_PROVIDERS } from "@/shared/constants/providers";

test("mynewprovider is registered and valid", () => {
  const provider = AI_PROVIDERS.mynewprovider;
  
  expect(provider).toBeDefined();
  expect(provider.id).toBe("mynewprovider");
  expect(provider.name).toBe("My New Provider");
  expect(provider.authUrl).toContain("oauth");
  expect(provider.supportsChat).toBe(true);
});

```

The proxy resolves dynamically, so tests verify both registration and field integrity without mocking the internal structure.

## Key Implementation Files

| File | Purpose |
|------|---------|
| [`src/shared/constants/providers/oauth.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers/oauth.ts) | OAuth provider definitions (or matching auth category) |
| [`src/shared/constants/providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers.ts) | Central aggregation, validation, and `AI_PROVIDERS` proxy |
| [`src/shared/validation/providerSchema.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/validation/providerSchema.ts) | Zod schema enforcing provider structure |
| [`tests/unit/providers.test.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/tests/unit/providers.test.ts) | Validation tests for new registrations |

## Summary

- **Choose the correct auth category** file based on the provider's authentication method
- **Define a complete provider object** matching the Zod schema with required `id`, `name`, `alias`, and auth-specific fields
- **Export from the category file** — the `AI_PROVIDERS` proxy automatically includes new entries via `Object.assign` in `getOrCreateAiProviders()`
- **Run validation** — schema mismatches throw at startup, protecting catalog integrity
- **Add unit tests** to confirm registration and field correctness

## Frequently Asked Questions

### What happens if I forget a required field in the provider definition?

OmniRoute throws a runtime error during application startup. The `validateProviders` function in [`src/shared/constants/providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers.ts) executes Zod validation immediately after merging provider sections, surfacing missing fields or type violations before the server accepts traffic.

### Can I add custom fields not in the standard schema?

Only if you first extend [`providerSchema.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/providerSchema.ts). The validation is strict—unrecognized fields cause startup failures. Modify [`src/shared/validation/providerSchema.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/validation/providerSchema.ts) to add new optional or required fields, then update all existing providers or mark them with `.optional()` to maintain backward compatibility.

### Does adding a provider require restarting the development server?

Yes. Since `AI_PROVIDERS` builds its map at module load time through `getOrCreateAiProviders()`, changes to provider definition files are only picked up on process restart. The proxy itself is lazy (creates the map on first access), but the underlying module cache must refresh to incorporate new source code.