# How to Add a New Provider to OmniRoute's 290-Provider Registry

> Learn to add a new provider to OmniRoute's 290-provider registry. Follow steps for authentication modules, metadata definition, and UI set registration for Zod validation.

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

---

**Adding a new provider requires selecting the correct authentication category module in `src/shared/constants/providers/`, defining a metadata object with required fields, and registering the provider ID in supplemental UI sets before the built-in Zod validation automatically processes the entry.**

OmniRoute maintains a centralized registry of over 290 AI providers through a barrel file architecture that aggregates category-specific definitions. To extend this ecosystem, contributors must create provider entries in dedicated authentication modules (OAuth, API-Key, No-Auth, etc.) that automatically validate and expose new entries to the routing engine, UI components, and quota-tracking systems.

## Understanding the Registry Architecture

OmniRoute uses a **single source-of-truth** pattern centered on [`src/shared/constants/providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers.ts). This barrel file imports provider definitions from individual category modules and exposes them through the `AI_PROVIDERS` Proxy.

When the module loads, `getOrCreateAiProviders()` aggregates all category objects (OAuth, API-Key, No-Auth, Web-Cookie, Local, Search, Audio, Upstream-Proxy, Cloud-Agent, and System) into a unified catalogue. The `validateProviders` function runs automatically at lines 76-87, ensuring every entry conforms to the Zod schema defined in [`src/shared/validation/providerSchema.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/validation/providerSchema.ts) before the UI or router can access the data.

## Step-by-Step Guide to Adding a New Provider

### Select the Authentication Category

First, identify the authentication method your provider uses and open the corresponding file:

- **OAuth** → [`src/shared/constants/providers/oauth.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers/oauth.ts)
- **API-Key** → [`src/shared/constants/providers/apikey.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers/apikey.ts)
- **No-Auth** (credential-less) → [`src/shared/constants/providers/noauth.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers/noauth.ts)
- **Web-Cookie** → [`src/shared/constants/providers/web-cookie.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers/web-cookie.ts)
- **Local / Self-Hosted** → [`src/shared/constants/providers/local.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers/local.ts)
- **Search** → [`src/shared/constants/providers/search.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers/search.ts)
- **Audio-Only** → [`src/shared/constants/providers/audio.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers/audio.ts)
- **Upstream-Proxy** → [`src/shared/constants/providers/upstream-proxy.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers/upstream-proxy.ts)
- **Cloud-Agent** → [`src/shared/constants/providers/cloud-agent.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers/cloud-agent.ts)
- **System** (virtual) → [`src/shared/constants/providers/system.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers/system.ts)

### Define the Provider Object

Add a new entry to the exported constant object in your chosen category file. The provider object must include these fields used throughout the UI and routing engine:

```typescript
export const OAUTH_PROVIDERS = {
  // ...existing providers
  
  "my-new-provider": {
    id: "my-new-provider",              // Unique string used everywhere
    alias: "mnp",                        // Optional short alias for URLs/CLI
    name: "My New Provider",             // Human-readable name
    icon: "auto_awesome",                // Material icon name
    color: "#123456",                    // Brand color for UI theming
    subscriptionRisk: true,               // True if charges per-request
    riskNoticeVariant: "oauth",           // "oauth" | "webCookie" | "deprecated" | "embedded-service"
    website: "https://mynewprovider.com",
    authHint: "Sign in via the provider's OAuth flow.", // Optional UI hint
    hasFree: true,                        // Optional - indicates free tier
  },
};

```

For API-Key providers, add the object to [`apikey.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/apikey.ts) using the same base fields plus any provider-specific flags like `freeNote`.

### Register in Supplemental UI Sets

Update [`src/shared/constants/providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers.ts) to include your provider ID in relevant grouping sets that affect UI behavior:

- **`IMAGE_ONLY_PROVIDER_IDS`** – Add as a `Set` entry if the provider supports only image generation
- **`AGGREGATOR_PROVIDER_IDS`** – Include if the provider is a meta-gateway like OpenRouter
- **`ENTERPRISE_CLOUD_PROVIDER_IDS`** – Add for managed cloud offerings
- **`VIDEO_PROVIDER_IDS`**, **`IDE_PROVIDER_IDS`**, **`EMBEDDING_RERANK_PROVIDER_IDS`** – Category-specific groupings

Example for an image-only provider around lines 55-66:

```typescript
export const IMAGE_ONLY_PROVIDER_IDS = new Set([
  // ...existing IDs
  "my-new-provider",   // ← new entry
]);

```

### Enable Usage Tracking (Optional)

If the new provider supports quota or usage APIs, append the provider's `id` to the `USAGE_SUPPORTED_PROVIDERS` array in [`providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/providers.ts) (see lines 16-58).

```typescript
export const USAGE_SUPPORTED_PROVIDERS = [
  // ...existing IDs
  "my-new-provider",
];

```

### Validate Your Changes

The barrel file automatically imports `validateProviders` and executes validation for every category at module load (lines 76-87). Simply adding your object to the correct category module triggers this validation during compilation or when running `npm run check`. The CI pipeline also runs `npm run check:fabricated-docs` to flag any undocumented fields.

## Code Examples

### Adding an OAuth Provider

```typescript
// src/shared/constants/providers/oauth.ts
export const OAUTH_PROVIDERS = {
  "openai": { /* existing config */ },
  
  "my-new-provider": {
    id: "my-new-provider",
    alias: "mnp",
    name: "My New Provider",
    icon: "auto_awesome",
    color: "#123456",
    subscriptionRisk: true,
    riskNoticeVariant: "oauth",
    website: "https://mynewprovider.com",
    authHint: "Sign in via the provider's OAuth flow.",
    hasFree: true,
  },
};

```

### Resolving Providers by ID or Alias

After registration, access the provider using the registry utilities:

```typescript
import { getProviderById, resolveProviderId } from "@/shared/constants/providers";

const id = resolveProviderId("mnp");        // → "my-new-provider"
const provider = getProviderById(id);     // Full definition object

```

## Key Implementation Files

| File | Purpose |
|------|---------|
| [`src/shared/constants/providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers.ts) | Barrel file merging categories and exposing `AI_PROVIDERS` Proxy |
| [`src/shared/constants/providers/oauth.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers/oauth.ts) | OAuth provider definitions |
| [`src/shared/constants/providers/apikey.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers/apikey.ts) | API-Key provider definitions |
| [`src/shared/constants/providers/noauth.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers/noauth.ts) | Credential-less provider definitions |
| [`src/shared/validation/providerSchema.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/validation/providerSchema.ts) | Zod schema for runtime validation |

## Summary

- **Choose the correct category file** based on authentication method (OAuth, API-Key, etc.)
- **Define the provider object** with required fields including `id`, `alias`, `name`, `icon`, `color`, and `subscriptionRisk`
- **Register in supplemental sets** like `IMAGE_ONLY_PROVIDER_IDS` or `AGGREGATOR_PROVIDER_IDS` to control UI grouping
- **Add to `USAGE_SUPPORTED_PROVIDERS`** if the provider reports quota or usage data
- **Validation runs automatically** via `validateProviders` when the module loads or tests execute

## Frequently Asked Questions

### What authentication categories are supported in OmniRoute?

OmniRoute supports ten distinct authentication categories: OAuth, API-Key, No-Auth, Web-Cookie, Local/Self-Hosted, Search, Audio-Only, Upstream-Proxy, Cloud-Agent, and System. Each category has a dedicated file in `src/shared/constants/providers/` that exports a constant object containing provider definitions with identical metadata shapes.

### How does OmniRoute validate new provider definitions?

The registry uses Zod schema validation defined in [`src/shared/validation/providerSchema.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/validation/providerSchema.ts). When you add a provider to any category file, the barrel file ([`providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/providers.ts)) imports `validateProviders` and automatically validates the combined catalogue at lines 76-87 during module initialization. This validation runs during compilation or when executing `npm run check`, ensuring type safety before the UI or router accesses the data.

### Can I reference providers by alias instead of the full ID?

Yes. OmniRoute exposes `resolveProviderId()` which accepts either the full provider `id` or the short `alias` defined in the provider object. For example, `resolveProviderId("mnp")` returns `"my-new-provider"`, allowing both CLI tools and UI components to use shorthand references while the registry maintains canonical IDs.

### What happens if a provider is not added to supplemental sets like IMAGE_ONLY_PROVIDER_IDS?

Omitting a provider from supplemental sets does not prevent it from appearing in the registry, but it will not receive specialized UI treatment or filtering. For instance, an image-generation provider not listed in `IMAGE_ONLY_PROVIDER_IDS` will still be selectable in the general provider list but may not appear in image-specific dropdowns or filtered views that rely on these sets for categorization.