# How OmniRoute's Tier Cascade Works: Subscription → API Key → Free Providers

> Discover how OmniRoute's tier cascade prioritizes subscriptions, uses API key overrides, and falls back to free providers for LLM access. Learn more today.

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

---

**OmniRoute determines which LLM providers a request may access through a three-step tier cascade that prioritizes subscription status, allows API key overrides, and falls back to free providers for unauthenticated requests.**

The **OmniRoute** repository implements a sophisticated access control system that routes AI model requests through a prioritized hierarchy. This **tier cascade** ensures paid subscribers receive premium access while guaranteeing service availability through free-tier providers for unauthenticated users. Understanding this mechanism is essential for developers integrating with OmniRoute's proxy system or managing subscription-based API access.

## The Three-Step Tier Cascade

OmniRoute's authorization layer evaluates credentials in a strict sequence, with each step capable of expanding or restricting the available provider pool.

### Step 1: Subscription Tier Resolution

The cascade begins by examining the authenticated user's **subscription record** stored in the `proxy_subscriptions` table. The [`src/lib/services/accountFallback.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/services/accountFallback.ts) module loads this data via the `resolveTier` function, which returns a tier object containing **allowedTiers** arrays and optional model-level constraints.

This subscription tier establishes the baseline provider access list. For example, a *Pro* subscription might yield `['tier_pro', 'tier_business']` in the `allowedTiers` array, while a *Free* subscription provides a more restricted set. The system merges these values into the request's candidate list before proceeding to the next validation layer.

### Step 2: API Key Tier Override

When a request includes an **API key** in the `x-api-key` or `Authorization: Bearer` header, OmniRoute loads the key's associated tier from [`src/lib/db/apiKeys.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/db/apiKeys.ts). The `getApiKeyInfo` function resolves the key to a subscription that can **override** the user-level subscription tier.

If the API key's tier is more permissive (e.g., *Enterprise* level), the provider list expands accordingly. Conversely, a restricted API key can narrow access to specific providers even if the user holds a higher-tier subscription. This override mechanism enables fine-grained access control for multi-tenant applications and specialized integrations.

### Step 3: Free-Tier Fallback

When neither a valid subscription nor API key yields usable providers, OmniRoute activates its **free-tier fallback** defined in [`src/shared/constants/providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers.ts). This catalog contains only providers flagged with `isFree: true`, such as OpenAI's `gpt-3.5-turbo` or Anthropic's `claude-instant`.

The `filterProvidersByTier` function in [`src/open-sse/config/providerRegistry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/open-sse/config/providerRegistry.ts) automatically injects these free providers as a safety net. This guarantees that every request receives service, even from completely unauthenticated callers, while maintaining strict isolation between paid and free resource pools.

## Implementation in the Account-Selection Pipeline

The tier cascade executes within a four-phase pipeline that transforms raw credentials into a filtered provider registry.

### 1. Authentication Extraction

The [`src/open-sse/handlers/auth.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/open-sse/handlers/auth.ts) module extracts the user session or API key from incoming request headers. This handler parses both cookie-based sessions and bearer tokens, normalizing them into a standard credential format for downstream processing.

### 2. Credential Resolution

The [`src/open-sse/services/auth.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/open-sse/services/auth.ts) file contains `markAccountUnavailable`, which works alongside `src/lib/services/accountFallback.ts::resolveTier` to translate credentials into a structured **tier object**. This object includes:
- `allowedTiers`: Array of accessible provider tier IDs
- `maxConcurrent`: Optional rate limiting parameters
- Model-specific lock flags

### 3. Provider Registry Filtering

The [`src/open-sse/config/providerRegistry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/open-sse/config/providerRegistry.ts) module receives the tier object and constructs a filtered list of `ProviderEntry` objects. This filtering respects both the `allowedTiers` array and any model-lock constraints imposed by previous 403 responses from specific providers.

### 4. Combo Routing

The filtered provider list passes to the combo engine in [`open-sse/services/combo.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/combo.ts). If the filtered list is empty—indicating no subscription or valid API key—the engine automatically injects **free-tier** providers to ensure request fulfillment.

## Code Examples

The following examples demonstrate how the tier cascade manifests in practice within the OmniRoute codebase.

### Authenticated User with Pro Subscription

```typescript
import { getSession } from '@/lib/auth/session';
import { resolveTier } from '@/lib/services/accountFallback';

const session = await getSession(req);
const tier = await resolveTier({ userId: session.userId });

// tier.allowedTiers → ['tier_pro', 'tier_business']
// This grants access to premium providers associated with these tier IDs

```

### API Key Tier Override

```typescript
import { getApiKeyInfo } from '@/lib/db/apiKeys';

// Header: x-api-key: abcdef123456
const keyInfo = await getApiKeyInfo('abcdef123456');

// keyInfo.tier → { allowedTiers: ['tier_enterprise'] }
// This expands access beyond the user's base subscription level

```

### Automatic Free-Tier Fallback

```typescript
import { filterProvidersByTier } from '@/open-sse/config/providerRegistry';

// No authentication provided
const providers = filterProvidersByTier({ allowedTiers: [] });

// Returns only providers where isFree: true
// e.g., [{ id: 'openai', model: 'gpt-3.5-turbo', isFree: true }, ...]

```

## Key Design Guarantees

OmniRoute's tier cascade architecture enforces three critical operational guarantees:

- **Pay-wall enforcement**: Paid subscriptions and API keys gate access to premium models through the `allowedTiers` validation in [`accountFallback.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/accountFallback.ts), ensuring revenue-generating resources remain protected.

- **Graceful degradation**: The free-tier fallback in [`providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/providers.ts) ensures 100% request servicing availability, preventing outages for unauthenticated traffic while isolating free resource consumption.

- **Fine-grained model locking**: When a provider returns a 403 response indicating subscription issues, OmniRoute locks only that specific model while preserving access to other providers within the same tier. The [`tests/unit/sse-auth.test.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/tests/unit/sse-auth.test.ts) file validates this behavior through the "ollama-cloud subscription 403" test case.

## Summary

- OmniRoute implements a **three-step tier cascade** that prioritizes subscription tiers, allows API key overrides, and falls back to free providers.
- The `resolveTier` function in [`src/lib/services/accountFallback.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/services/accountFallback.ts) orchestrates the core resolution logic between user subscriptions and API keys.
- **API keys** can expand or restrict access beyond the user's base subscription level through [`src/lib/db/apiKeys.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/db/apiKeys.ts).
- **Free-tier providers** serve as a universal fallback when no authentication is present, defined in [`src/shared/constants/providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers.ts) with the `isFree: true` flag.
- The pipeline flows through [`auth.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/auth.ts) handlers → [`accountFallback.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/accountFallback.ts) resolution → [`providerRegistry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/providerRegistry.ts) filtering → [`combo.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/combo.ts) routing.

## Frequently Asked Questions

### How does OmniRoute handle requests with both a valid subscription and an API key?

When both credentials are present, the API key tier **overrides** the subscription tier. The `resolveTier` function in [`src/lib/services/accountFallback.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/services/accountFallback.ts) checks for API key presence first, and if the key maps to a valid subscription via [`src/lib/db/apiKeys.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/db/apiKeys.ts), that tier's `allowedTiers` array replaces the user-level subscription permissions. This allows for granular access control where specific API keys can grant elevated or restricted permissions compared to the user's account.

### What happens if a user's subscription expires mid-request?

The tier cascade evaluates credentials at request time through the `markAccountUnavailable` logic in [`src/open-sse/services/auth.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/open-sse/services/auth.ts). If a subscription expires, the next request will fail the subscription tier check and cascade down to the API key tier. If no valid API key exists, the system falls back to **free-tier providers** automatically. This ensures no hard failures occur, though the user may experience reduced model quality or rate limits associated with free-tier access.

### Can free-tier providers be disabled entirely for security reasons?

Yes. Since free-tier providers are defined in [`src/shared/constants/providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers.ts), administrators can modify the `isFree: true` flags or remove entries entirely. Additionally, the `filterProvidersByTier` function in [`src/open-sse/config/providerRegistry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/open-sse/config/providerRegistry.ts) can be configured to skip the free-tier fallback when `allowedTiers` is empty, returning an empty provider list instead. This effectively blocks unauthenticated requests rather than degrading to free models.

### How does OmniRoute prevent free-tier users from accessing paid models?

The system enforces strict **provider registry filtering** in [`src/open-sse/config/providerRegistry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/open-sse/config/providerRegistry.ts), which cross-references every request's `allowedTiers` array against the provider's required tier. Paid models are associated with tier IDs like `'tier_pro'` or `'tier_enterprise'`, which only appear in authenticated subscription objects or premium API keys. When a free-tier request (empty `allowedTiers` or `isFree: true` only) attempts to access a paid model, the filtering logic excludes that provider from the candidate list before the combo engine ever receives it.