How to Force a Specific Provider and Model in OmniRoute

Omniroute forces a specific LLM provider and model by accepting provider and model identifiers in the request payload, which short-circuits the auto-combo routing logic and routes directly to the requested endpoint.

This guide explains the exact mechanism used by the open-source OmniRoute router to override its default provider-selection heuristics. Whether you're building on top of the self-hosted API or integrating with existing infrastructure, understanding this routing path lets you lock requests to exact backend configurations.

Request Format for Forcing Provider and Model

OmniRoute accepts forced provider/model specifications through two equivalent formats in your request to /v1/chat/completions:

  1. Combined format: A single model string with provider/model syntax (e.g., "openai/gpt-4")
  2. Explicit format: Separate provider and model fields

Both approaches are validated by the Zod schema in src/app/api/v1/chat/completions/route.ts, which parses the incoming JSON and normalizes it into a structured Target object.

curl -X POST https://localhost:20128/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
        "provider": "anthropic",
        "model": "claude-3-5-sonnet-20240620",
        "messages": [{"role":"user","content":"Write a haiku about AI"}]
      }'

The combined shorthand achieves identical behavior with cleaner syntax:

curl -X POST https://localhost:20128/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
        "model": "openai/gpt-4",
        "messages": [{"role":"user","content":"Explain quantum tunnelling"}],
        "max_tokens": 512
      }'

How the Routing Logic Enforces Your Selection

Once parsed, the forced target triggers a specific code path in src/open-sse/services/combo.ts. The combo router normally scores available providers by latency, cost, and reliability—but detects when both provider and model are explicitly supplied.

In this case, the logic bypasses handleSingleModel() from src/open-sse/handlers/chatCore.ts directly to the provider-specific executor, skipping:

  • Auto-combo scoring algorithms
  • Fallback provider selection
  • Load-balancing across equivalent models

The request flows through these specific source files:

Step File Function
Request parsing src/app/api/v1/chat/completions/route.ts Zod schema extracts provider/model
Target construction src/open-sse/handlers/chatCore.ts Builds internal Target object
Forced-target detection src/open-sse/services/combo.ts Bypasses selection heuristics
API dispatch src/open-sse/executors/{provider}.ts Routes to upstream endpoint

This architecture guarantees that no fallback occurs to alternative providers—even if the forced endpoint returns rate-limit errors. The executor's retry logic with exponential backoff still applies, but the routing decision remains locked.

Programmatic Usage with the Node SDK

If your implementation uses the OmniRoute client SDK, forcing a provider works identically:

import { OmnirouteClient } from "omniroute";

const client = new OmnirouteClient({ baseURL: "http://localhost:20128" });

await client.chat.completions.create({
  provider: "gemini",
  model: "gemini-1.5-flash",
  messages: [{ role: "user", content: "Summarize the plot of *Hamlet*" }],
});

The SDK forwards these fields directly to the HTTP endpoint, so the same forced-routing guarantees apply.

Combining Forced Targets with Auto-Selected Ones

You can force specific providers within a combo request that includes additional auto-selected targets. This ensures critical workloads hit your preferred backend while allowing auxiliary traffic to route dynamically:

{
  "model": "openai/gpt-4",
  "targets": [
    { "provider": "openai", "model": "gpt-4" },
    { "provider": "anthropic", "model": "claude-3-sonnet" }
  ],
  "messages": [{"role":"user","content":"Analyze this contract"}]
}

OmniRoute's combo service in src/open-sse/services/combo.ts always includes the forced target, then supplements with scored selections from the remaining entries.

Provider Alias Resolution

The src/lib/modelMetadataRegistry.ts file maintains canonical mappings between provider aliases and their internal identifiers. When you specify "openai/gpt-4", this registry resolves the string to the validated provider name and model ID used throughout the routing pipeline.

This registry also enables shorthand aliases—if your configuration maps "gpt-4" to "openai/gpt-4", requests can use the shorter form while still triggering forced-target behavior.

Summary

  • Force a specific provider and model by including provider and model fields (or combined model: "provider/model") in your /v1/chat/completions request
  • Routing bypass: The combo service detects forced targets in src/open-sse/services/combo.ts and skips auto-selection heuristics
  • No fallback: Errors from forced endpoints trigger retry logic but never reroute to alternative providers
  • SDK compatibility: Both raw HTTP and SDK clients support identical forcing semantics
  • Combo flexibility: Forced targets can coexist with auto-selected ones in multi-target requests

Frequently Asked Questions

What happens if the forced provider is unavailable?

The executor for that provider implements its own retry with exponential backoff, but OmniRoute will not fall back to a different provider. If all retries exhaust, the request returns an error. This matches the deterministic guarantee of forced routing.

Can I use provider aliases instead of canonical names?

Yes. The src/lib/modelMetadataRegistry.ts registry resolves aliases to canonical identifiers before routing decisions occur. Configure your aliases in the OmniRoute configuration file to use short names like "gpt-4" instead of "openai/gpt-4".

Does forcing a provider affect pricing or rate-limit tracking?

No. OmniRoute's metering and quota enforcement operate downstream of routing decisions. Forced requests consume credits and hit rate limits exactly as auto-routed requests would for the same provider/model combination.

Is there a way to force a provider but let OmniRoute select the model?

Partial forcing is not supported. The combo router requires both provider and model to trigger the forced-target bypass. Supplying only one field results in normal auto-selection behavior with that value as a soft preference.

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 →