Documentation

Everything you need to understand, configure, and operate ModelRouter.

01 / Getting Started

Quick Setup

Get up and running with ModelRouter in four steps.

1
Get your API key. Your admin key is configured in the Fastly secret store during deployment. Go to Settings and enter your ModelRouter API URL and key.
2
Connect your provider API keys. ModelRouter is BYOK (Bring Your Own Keys). Add API keys for the providers you want to use: Ollama (self-hosted), Groq, Together AI, Mistral, DeepSeek, OpenAI, or Anthropic. Test each connection via POST /v1/providers/test or the Settings page.
3
Configure preferences. Use the sliders on the Settings page to set your default cost/speed/quality weights. Higher cost weight means lowest-cost models are preferred; higher quality weight means premium models.
4
Send your first prompt. Go to the Dashboard, type a message, and click Send. ModelRouter will classify your prompt, pick the optimal model from your connected providers, and return the response with full routing metadata.

Quick Test
curl -X POST https://gratefully-stunning-skylark.edgecompute.app/v1/chat/completions \ -H "Authorization: Bearer YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"model":"auto","messages":[{"role":"user","content":"Hello, world!"}]}'
02 / Architecture

Request Flow

Every request passes through a multi-stage pipeline running at the edge on Fastly Compute.

Browser/SDK | v +-------------------+ | Fastly Compute | <-- WASM at the edge, sub-ms cold start | (Edge PoP) | +-------------------+ | | 1. Auth Check ............. Validate Bearer token | 2. Injection Check ........ 30+ heuristic patterns, <1ms | 3. Custom Rules Check ..... KV-stored rules (any/all/none logic) | 4. Cache Check ............ SimpleCache (per-POP) -> KV Store (global) | 5. Detect Modality ........ Images, OCR, code, image generation requests | 6. Classify Prompt ........ Heuristic tier: fast/balanced/quality/reasoning/code/vision/ocr/image_gen/embedding | 7. Route to Provider ...... Score 26 models by cost/speed/quality weights + capability filtering | 8. Call LLM Provider ...... Ollama / OpenAI / Anthropic / Groq / Together / Mistral / DeepSeek | 9. Cache Response ......... Store in SimpleCache + KV (if cacheable) | 10. Audit Log .............. Fire-and-forget KV write | v Response + Routing Headers

Auth Check: Validates the Bearer token against the secret store. Rejects unauthorized requests immediately.

Injection Check: Runs 30+ regex/heuristic patterns against the prompt content. Produces a 0.0-1.0 injection score. Prompts above the threshold (default 0.5) are blocked before any LLM call.

Custom Rules: Evaluates user-defined blocking rules stored in the KV store. Rules support contains, regex, starts_with, equals, and not_contains operators with AND/OR/NOT logic.

Cache Check: Looks up an exact-match cache key (hash of model + messages + temperature). SimpleCache is per-POP with microsecond latency. KV Store is global with millisecond latency.

Detect Modality: Scans message content for images (OpenAI image_url format), OCR requests, image generation prompts ("create an image", "generate a picture"), and code blocks. Detected modality determines which capability filters apply during routing.

Classify: Analyzes prompt complexity to assign one of 9 tiers (fast, balanced, quality, reasoning, code, vision, ocr, image_gen, embedding). Uses keyword heuristics, question detection, code block detection, image detection, and content analysis.

Route: Scores all 26 available models for the assigned tier using user preference weights (cost, speed, quality) and internal quality rankings (Claude Opus 4 at the top, down through GPT-5.4, Claude Sonnet 4, DeepSeek R1, GPT-4o, and so on). Models without the required capability (e.g., vision, ocr, image_gen) are automatically excluded. Picks the highest-scoring model from connected providers with a fallback chain if the primary provider fails.

Audit Log: Writes a fire-and-forget entry to the KV store keyed by tenant and date. Zero added latency to the response.

03 / Routing Engine

How ModelRouter Selects a Model

Every prompt goes through a two-stage process: first the prompt is classified into a tier, then the best model within that tier is selected based on your preference weights. No LLM is used for classification -- it runs deterministic heuristics in microseconds.

9 Routing Tiers

  • Fast — Simple questions, greetings, factual lookups. Models: Gemma 9B (Groq), GPT-4o-mini, Mistral Small, Phi-3 (Ollama).
  • Balanced — Summarization, translation, general Q&A. Models: Llama 3.3 70B (Groq/Together), DeepSeek Chat, GPT-4o-mini.
  • Quality — Creative writing, detailed analysis. Models: Claude Sonnet 4, GPT-4o, DeepSeek V4, Mistral Large.
  • Reasoning — Complex math, logic, multi-step proofs. Models: Claude Opus 4, GPT-5.4, DeepSeek R1.
  • Code — Programming, debugging, code generation. Models: DeepSeek Coder, GPT-4o, Claude Sonnet 4.
  • Vision — General image understanding (describe, analyze, compare images). Models: GPT-4o, Claude Sonnet 4. For text extraction, see OCR tier. For image creation, see Image Generation tier.
  • OCR — When text extraction is needed, ModelRouter routes to Mistral OCR -- a purpose-built document parser that achieves state-of-the-art accuracy at $0.002/page. This is 10x cheaper and more accurate than sending OCR tasks to GPT-4o. Specialized OCR models preserve table structure, formulas, and layout that general-purpose models lose. Models: Mistral OCR, DeepSeek OCR, GPT-4o (fallback).
  • Image Generation — Image generation routes to FLUX models via Together AI -- faster, cheaper, and higher quality than DALL-E 3. FLUX.1 schnell generates images in 2 seconds. FLUX.1 Pro matches or exceeds DALL-E 3 quality at lower cost. Models: FLUX.1 Schnell (free), FLUX.1 Pro, DALL-E 3 (fallback).
  • Embedding — Vector embeddings for search/RAG. Models: text-embedding-3-small, nomic-embed-text.

Model Quality Rankings

Models are ranked by overall quality. These rankings are used as one of three factors (alongside cost and speed) when scoring models within a tier:

  1. Claude Opus 4 — Highest quality reasoning and nuanced analysis
  2. GPT-5.4 — Strongest general-purpose, large context window
  3. Claude Sonnet 4 — Excellent balance of quality and cost, supports vision
  4. DeepSeek R1 — Specialized reasoning with transparent thinking chains
  5. GPT-4o — Strong multimodal, supports vision and OCR
  6. DeepSeek Coder — Code specialist, very low cost
  7. DeepSeek V4 — Solid general-purpose at included-tier pricing
  8. Mistral Large — Good quality with function calling support
  9. Llama 3.3 70B — Strong open-source, free on Groq
  10. GPT-4o-mini — Fast and cheap for simpler tasks

How a Prompt is Classified

When a prompt arrives, ModelRouter reads it and decides what kind of work it is. The classifier runs through checks in priority order -- the first match wins:

1. CONTENT TYPE CHECK (highest priority) Does the message contain image blocks? + text about extracting/reading text? --> OCR tier + otherwise --> VISION tier Does the text ask to generate/create/draw an image? --> IMAGE_GEN tier Does it request text embeddings? --> EMBEDDING tier 2. COMPLEXITY CHECK Does it match code patterns? (function names, language keywords, "write code", "debug", "implement", code blocks) --> CODE tier Does it match reasoning patterns? ("step by step", "prove", "analyze", multi-step math, formal logic) --> REASONING tier Does it match quality patterns? ("essay", "article", "creative", "comprehensive", "detailed analysis")--> QUALITY tier Is the prompt very long (8000+ tokens)? --> REASONING tier Is it moderately long (4000+ tokens)? --> QUALITY tier 3. SIMPLICITY CHECK Is it short and simple? ("yes", "no", "define X", "translate", factual lookups, greetings) --> FAST tier Default (nothing else matched) --> BALANCED tier

How a Model is Selected Within a Tier

Once the tier is chosen, ModelRouter scores each available model in that tier using your preference weights (the cost, speed, and quality sliders):

score = (cost_weight x cost_rank) + (speed_weight x speed_rank) + (quality_weight x quality_rank)

Models are ranked 0 to 1 within their tier for each dimension. The highest-scoring model wins.

  • If you set Cost to 100%: the cheapest model in the tier is always chosen.
  • If you set Quality to 100%: the highest-rated model in the tier is always chosen.
  • If you set Speed to 100%: the lowest-latency model in the tier is always chosen.

Additional constraints:

  • Only models from your connected providers are considered (you must have the API key configured).
  • Only models with the required capabilities are considered (e.g., a vision request only considers vision-capable models).
  • If the primary model fails (provider error, timeout), the next-best model in the tier is tried automatically (fallback chain across all 7 providers).

Worked Example

A user sends: "Write a Python function to sort a list"

Step 1 - Content type check: No image blocks --> skip vision/OCR/image_gen No embedding request --> skip embedding Step 2 - Complexity check: Text contains "function" + "Python" --> matches code patterns --> CODE tier Step 3 - Model selection in CODE tier: User preferences: cost=50%, speed=25%, quality=25% DeepSeek Coder: cost=$0.27/1M latency=300ms quality=high --> score: 0.82 GPT-4o: cost=$2.50/1M latency=500ms quality=v.high --> score: 0.61 Claude Sonnet 4: cost=$3.00/1M latency=600ms quality=v.high --> score: 0.58 Winner: DeepSeek Coder (highest score -- cost preference gives it a big advantage)

Vision Detection

ModelRouter reads each message's content blocks. In the OpenAI format, a message can contain multiple content blocks:

{ "role": "user", "content": [ { "type": "text", "text": "What's in this image?" }, { "type": "image_url", "image_url": { "url": "https://..." } } ]}

If any content block has type image_url or image, the prompt is classified as VISION. This overrides all other classification -- even if the text says "write code", the presence of an image means vision routing.

Within the VISION tier, only models with vision capability are considered:

  • GPT-4o (OpenAI) — supports image URLs and base64
  • Claude Sonnet 4 (Anthropic) — supports image URLs and base64

If the text also contains OCR keywords ("extract text", "read the text", "OCR"), it is classified as OCR instead, which routes to specialized OCR models like Mistral OCR and DeepSeek OCR that preserve table structure, formulas, and layout.

Why Specialized Models?

ModelRouter doesn't just route to the biggest model. It routes to the right model.

Sending OCR to GPT-4o is like using a bulldozer to plant a flower. Mistral OCR is purpose-built for document parsing -- it's more accurate, 10x cheaper, and preserves structure (tables, formulas) that GPT-4o flattens.

Sending image generation to DALL-E 3 ignores that FLUX.1 Pro generates higher-quality images in less time at lower cost.

This is the core value of ModelRouter: you don't need to know which model is best for each task. We do.

03.5 / Multimodal Requests

Content-Aware Routing for Images, OCR & Code

ModelRouter automatically detects content type in your prompts and routes to models with the required capabilities. Models that lack a required capability (e.g., vision) are automatically excluded from selection.

Sending Images (Vision)

Include images using the OpenAI image_url content block format. ModelRouter detects the image and routes to vision-capable models (GPT-4o, Claude Sonnet 4).

{ "model": "auto", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "What's in this image?" }, { "type": "image_url", "image_url": { "url": "https://example.com/photo.jpg" } } ] } ] }

OCR Detection

When your prompt includes an image and mentions text extraction keywords (e.g., "extract text", "read the text", "OCR"), ModelRouter routes to purpose-built OCR models. Mistral OCR is the primary choice -- a specialized document parser that achieves state-of-the-art accuracy at $0.002/page, preserving table structure, formulas, and layout that general-purpose models lose. DeepSeek OCR is available as a lower-cost alternative, with GPT-4o as a fallback. The detection is automatic — no special flags needed.

Image Generation

Prompts requesting image creation (e.g., "create an image of...", "generate a picture", "draw a...") are automatically routed to FLUX models via Together AI. FLUX.1 Schnell (free) generates images in ~2 seconds. FLUX.1 Pro matches or exceeds DALL-E 3 quality at lower cost with faster generation. DALL-E 3 is available as a fallback. No model override needed — just describe what you want.

Code Detection

Prompts containing code blocks, programming keywords, or debugging requests are routed to code-optimized models like DeepSeek Coder.

Provider Capabilities

Provider Text Vision OCR Image Gen Code Reasoning
OpenAI (GPT-4o)YesYesFallbackDALL-E 3YesYes
Anthropic (Claude Sonnet 4)YesYesYesYes
Anthropic (Claude Opus 4)YesYesYes
GroqYes
Together AI (FLUX)YesFLUX.1Yes
Mistral (OCR)YesPrimary
DeepSeekYesYesYesYes
OllamaYes

Capability filtering: When a modality is detected (vision, OCR, image generation), models without that capability are automatically excluded from routing. This ensures your request always reaches a model that can handle it.

04 / Provider Tiers

Available Models — 26 Models, 7 Providers

All models available through ModelRouter, organized by provider. BYOK: you bring your own API keys, we route. Models only appear in GET /v1/models when you have the provider's key connected.

Model Provider Tier Capabilities Input Cost Output Cost Pricing
Ollama (self-hosted, 6 models)
llama3.2:latest Ollama Fast text $0 $0 INCLUDED
phi3:latest Ollama Fast text $0 $0 INCLUDED
qwen2.5:latest Ollama Fast text $0 $0 INCLUDED
glm4:latest Ollama Fast text $0 $0 INCLUDED
gpt-oss:latest Ollama Fast text $0 $0 INCLUDED
nomic-embed-text Ollama Embedding embedding $0 $0 INCLUDED
OpenAI (paid, 5 models)
gpt-4o-mini OpenAI Balanced text vision $0.15/1M $0.60/1M PAID
gpt-4o OpenAI Quality text vision ocr code $2.50/1M $10/1M PAID
gpt-5.4 OpenAI Reasoning text code reasoning $5/1M $20/1M PAID
o3-mini OpenAI Reasoning text reasoning $1.10/1M $4.40/1M PAID
text-embedding-3-small OpenAI Embedding embedding $0.02/1M PAID
Anthropic (paid, 2 models)
claude-sonnet-4-20250514 Anthropic Quality text vision ocr code $3/1M $15/1M PAID
claude-opus-4-20250514 Anthropic Reasoning text code reasoning $15/1M $75/1M PAID
Groq (included tier, 2 models)
llama-3.3-70b-versatile Groq Balanced text $0 $0 INCLUDED
gemma2-9b-it Groq Fast text $0 $0 INCLUDED
Together AI (200+ models, 5 featured)
meta-llama/Llama-3.3-70B-Instruct-Turbo Together AI Balanced text $0.88/1M $0.88/1M INCLUDED
mistralai/Mixtral-8x7B-Instruct-v0.1 Together AI Balanced text $0.60/1M $0.60/1M INCLUDED
togethercomputer/CodeLlama-34b-Instruct Together AI Code text code $0.78/1M $0.78/1M INCLUDED
black-forest-labs/FLUX.1-schnell-Free Together AI Image Gen image_gen $0 $0 INCLUDED
black-forest-labs/FLUX.1-pro Together AI Image Gen image_gen $50/1M PAID
Mistral (included tier, 3 models)
mistral-small-latest Mistral Fast text $0 $0 INCLUDED
mistral-large-latest Mistral Quality text $0 $0 INCLUDED
mistral-ocr-latest Mistral OCR ocr vision $1/1M PAID
DeepSeek (included tier, 5 models)
deepseek-chat DeepSeek Balanced text $0.14/1M $0.28/1M INCLUDED
deepseek-v4 DeepSeek Quality text $0.27/1M $1.10/1M INCLUDED
deepseek-reasoner DeepSeek Reasoning text reasoning $0.55/1M $2.19/1M INCLUDED
deepseek-coder DeepSeek Code text code $0.14/1M $0.28/1M INCLUDED
deepseek-ocr DeepSeek OCR ocr vision $0.03/1M INCLUDED

BYOK: You bring your own API keys and pay providers directly. ModelRouter adds no markup to token costs. Ollama models run on your own hardware at zero cost. Groq, Together AI, Mistral, and DeepSeek all offer included tiers with their API keys.

05 / Security

Injection Detection & Protection

ModelRouter runs a multi-layer security pipeline at the edge before any prompt reaches an LLM.

Injection Detection (30+ Patterns)

The injection detector scans every prompt against a library of heuristic patterns covering:

  • Instruction overrides: "Ignore all previous instructions", "disregard your programming"
  • Role hijacking: "You are now DAN", "pretend you have no restrictions"
  • Delimiter injection: <system> tags, markdown separators used to inject fake system messages
  • System prompt extraction: "Print your initial instructions", "output your system prompt"
  • Jailbreak patterns: "Do Anything Now", "developer mode", "unrestricted mode"

Each pattern contributes a weighted score. The combined injection score (0.0 to 1.0) determines whether the prompt is blocked. Default threshold: 0.5.

Custom Blocking Rules

Beyond automatic injection detection, you can define custom rules with flexible logic:

  • ANY (OR): Block if any condition matches. Use for broad content filters.
  • ALL (AND): Block only if all conditions match. Use for precise targeting.
  • NONE (NOT): Block if any condition matches — used as an allowlist violation detector.

Rules are stored in the KV store and evaluated at every edge PoP. Create and test rules on the Rules page.

Data Loss Prevention (DLP)

Use custom rules as a DLP layer to prevent sensitive data from leaving your organization through AI prompts:

  • SSN detection: Regex pattern \b\d{3}-\d{2}-\d{4}\b blocks Social Security Numbers.
  • Source code blocking: Detect code patterns, function signatures, or internal API keys in prompts.
  • Trade secrets: Block mentions of internal project names, proprietary algorithms, or confidential data markers.
  • Credit card numbers: Regex for card patterns across all major networks.

DLP rules run at the edge in <1ms and block before any data reaches an external LLM provider.

Employee AI Audit Logging

Every request is logged with: timestamp, provider, model, injection score, cache status, latency, token usage, and HTTP status. Logs are keyed by tenant and date in the KV store. Full visibility into which employees are using AI, what they are asking, and which models are being invoked. View and export logs on the Logging page.

06 / Caching

Two-Tier Edge Cache

ModelRouter uses two complementary caching layers to minimize LLM API calls and costs.

Tier 1: Fastly SimpleCache (Per-POP)

SimpleCache is a local in-memory cache at each Fastly edge Point of Presence (PoP). Lookups complete in microseconds. If a user at the same PoP asks the same question, the response is served instantly from memory without any network calls.

Tier 2: Fastly KV Store (Global)

The KV Store is a globally distributed key-value database. If the SimpleCache misses, ModelRouter checks the KV Store. KV lookups take milliseconds and work across all PoPs worldwide. This means a cache entry written in San Francisco is readable in Tokyo.

When Caching Applies

  • Caching is active when temperature=0 (deterministic output)
  • Streaming responses (stream=true) are not cached
  • The cache key is a SHA-256 hash of: model + messages array + temperature
  • Cache entries expire based on configurable TTL (default: 1 hour for SimpleCache, 24 hours for KV)

Cost impact: Every cache hit is a $0 LLM call. At a 50% hit rate on 10,000 daily requests using GPT-4o, caching saves approximately $150/day in API costs. Cache hits also return in under 1ms vs 500ms+ for live LLM calls.

07 / Custom Rules

Rule Configuration Guide

Define custom blocking rules that are deployed instantly to every edge PoP via the KV store. No service redeploy needed.

Rule Structure

{ "id": "rule-unique-id", // Auto-generated or custom "name": "Human-readable name", "enabled": true, // Toggle without deleting "action": "block", // Currently only "block" supported "logic": "any", // "any" | "all" | "none" "conditions": [ { "field": "content", // "content" | "role" | "model" "operator": "contains", // See operator list below "value": "search term" } ] }

Operators

OperatorBehaviorExample Value
containsCase-insensitive substring matchsocial security
not_containsPasses if substring is NOT foundapproved
regexRegular expression match\b\d{3}-\d{2}-\d{4}\b
starts_withChecks if field starts with valueSYSTEM:
equalsExact string matchadmin

Logic Types

  • any (OR): The rule fires if any one condition matches. Best for broad content filters. Example: block prompts containing "SSN" OR "credit card number".
  • all (AND): The rule fires only if every condition matches. Best for precise targeting. Example: block prompts where content contains "extract" AND content contains "database".
  • none (NOT): The rule fires if any condition matches. Used for allowlist enforcement. Example: block if role is NOT "user" (i.e., block system/assistant injection).

Fields

  • content: The text content of the message being evaluated.
  • role: The message role (user, system, assistant).
  • model: The requested model name.

Example: Block PII Extraction
{ "id": "rule-block-pii", "name": "Block PII extraction attempts", "enabled": true, "action": "block", "logic": "any", "conditions": [ { "field": "content", "operator": "regex", "value": "\\b\\d{3}-\\d{2}-\\d{4}\\b" }, { "field": "content", "operator": "contains", "value": "social security number" }, { "field": "content", "operator": "contains", "value": "credit card number" }, { "field": "content", "operator": "regex", "value": "\\b\\d{4}[- ]?\\d{4}[- ]?\\d{4}[- ]?\\d{4}\\b" } ] }
08 / Multi-Tenancy Roadmap

Multi-Tenant Architecture Coming Soon

ModelRouter is designed to support multi-tenant deployments where each customer gets isolated resources and configuration.

Planned Features

  • Per-tenant Fastly services: Each tenant gets a dedicated Compute service with isolated configuration, secret stores, and backend definitions.
  • Isolated KV stores: Tenant-specific KV stores for rules, audit logs, and cache. No data leakage between tenants.
  • Provisioning API: Programmatically create, configure, and tear down tenant services via a management API. Automate onboarding.
  • White-labeling: Custom domains, branding, and UI themes per tenant. Each tenant can point their own domain at their ModelRouter service.
  • Usage metering: Per-tenant request counts, token usage, and cost tracking for billing and chargeback.
  • Role-based access: Tenant admins manage their own rules and settings. Platform admins manage all tenants.

Multi-tenancy is on the roadmap for a future release. The current single-tenant architecture already supports isolated KV namespacing. Contact jacob.rosenbacher@gmail.com for early access to multi-tenant features.