How it works Pricing Docs Book a demo Login
Documentation

Rouva Docs

Everything you need to connect your app to Rouva — from a quick start to the full API reference.

Updated on October 5, 2026


Quick start

Connect your app to Rouva in three steps. No infrastructure changes required.

  1. Create an account
    Sign up at app.rouva.io and connect one or more AI provider API keys in Settings.
  2. Generate your Rouva gateway key
    Go to Integrations in your dashboard and click Generate API key. Your key starts with rva_.
  3. Route your first request
    Use the SDK or call the gateway directly. Rouva handles the rest.

SDK

The official Node.js SDK is the fastest way to integrate. One client, any connected provider — drop-in compatible with the OpenAI SDK.

Install

npm install @rouvanpm/rouva

Usage

import { Rouva } from '@rouvanpm/rouva'

const rouva = new Rouva({ apiKey: 'rva_your_key' })

const response = await rouva.chat.completions.create({
  messages: [{ role: 'user', content: 'Your prompt here' }],
})
Omit model to let Rouva route automatically to the cheapest capable model. Pass a model to use it as a cost ceiling — Rouva will route cheaper when possible, and savings are tracked against it.

Already using OpenAI or Anthropic?

Change two lines. Rouva uses the same message format — your existing code works as-is.

// Before (OpenAI)
import OpenAI from 'openai'
const openai = new OpenAI({ apiKey: '...' })
const res = await openai.chat.completions.create({ messages, model: 'gpt-4o' })

// Before (Anthropic)
import Anthropic from '@anthropic-ai/sdk'
const anthropic = new Anthropic({ apiKey: '...' })
const res = await anthropic.messages.create({ messages, model: 'claude-sonnet-4-6', max_tokens: 1024 })

// After — one client, any provider, intelligently routed
import { Rouva } from '@rouvanpm/rouva'
const rouva = new Rouva({ apiKey: 'rva_...' })
const res = await rouva.chat.completions.create({ messages, model: 'gpt-4o' }) // model optional

Options

Option Type Required Description
apiKey string Required Your rva_ gateway key from the dashboard
baseURL string Optional Override the default gateway URL

API reference

All three endpoints require Authorization: Bearer rva_your_key and Content-Type: application/json.

POST /api/gateway/messages Native gateway — intelligent routing, streaming

Routes your prompt to the cheapest capable model across your connected providers. Streams by default. Omit model to let Rouva auto-route, or pin a model as a cost ceiling.

▸ Request parameters
FieldTypeRequiredDescription
messagesarrayRequiredArray of { role, content } objects. Roles: system, user, assistant, tool. Content must be a string except on tools requests.
modelstringOptionalPin a model. Omit to auto-route. For non-tools requests, Rouva routes cheaper when possible and tracks savings against it. For tools requests, the named model is honored exactly on this endpoint, except when a same-provider routing override applies — in that case the override model is used instead. Workspace members are additionally subject to the administrator’s model allowlist: if the requested model is disallowed, the cheapest permitted model is substituted. Honored exactly for all requests when Intelligent Routing is off.
providerstringOptionalanthropic, openai, gemini, mistral, deepseek, xai, zai, alibaba, moonshot
systemstring | arrayOptionalSystem prompt — plain string or Anthropic-style text blocks.
max_tokensnumberOptionalDefaults to 4096. max_completion_tokens accepted as alias.
temperaturenumberOptional0–1. Omitted for reasoning models and for Claude models that reject it (Opus 4.7 and newer, Sonnet 5 and newer, Fable).
streambooleanOptionalDefaults to true (SSE). Set false for buffered JSON.
toolsarrayOptionalTool definitions in your provider's format, forwarded verbatim. Requires model.
tool_choicestring | objectOptionalForwarded verbatim. Only valid with tools.
top_pnumberOptionalNucleus sampling. top_p: 1 treated as omitted. Not supported on OpenAI reasoning models. Omitted for the same Claude models as temperature.
stopstring | string[]OptionalUp to 4 stop sequences. Not supported on OpenAI or xAI reasoning models (e.g. grok-4.7): a request pinned to one gets a 400, and Intelligent Routing skips them when stop is set.
seedintegerOptionalOpenAI models only — pins routing to OpenAI.
metadataobjectOptionalFlat string map stored with the request. Up to 10 keys.
Unsupported options are rejected with an explicit 400, never silently ignored: response_format, logit_bias, logprobs, reasoning_effort, parallel_tool_calls, n ≠ 1, non-zero penalties, and the legacy functions/function_call fields.

Response format

Responses use the wire format of the provider Rouva routed to — either OpenAI-format or Anthropic-format. Parse the format that matches the provider, or use the SDK which normalises both.

OpenAI-format stream (SSE)

data: {"id":"chatcmpl-...","choices":[{"delta":{"content":"Hello"},"index":0}]}
data: {"id":"chatcmpl-...","choices":[{"delta":{},"finish_reason":"stop","index":0}]}
data: [DONE]

Anthropic-format stream (SSE)

data: {"type":"content_block_delta","delta":{"type":"text_delta","text":"Hello"}}
data: {"type":"message_delta","delta":{"stop_reason":"end_turn"}}
data: {"type":"message_stop"}

Buffered JSON (stream: false) — OpenAI format

{"id":"chatcmpl-...","choices":[{"message":{"role":"assistant","content":"Hello"},"finish_reason":"stop","index":0}],"usage":{"prompt_tokens":10,"completion_tokens":5,"total_tokens":15}}
POST /v1/chat/completions OpenAI-compatible alias

Drop-in replacement for the OpenAI API. Point any OpenAI SDK or compatible client at https://app.rouva.io/v1 with your rva_ key — no other changes needed.

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://app.rouva.io/v1",
  apiKey: process.env.ROUVA_API_KEY,
});

const completion = await client.chat.completions.create({
  model: "gpt-4o-mini",
  messages: [{ role: "user", content: "Hello" }],
});
▸ Differences from /api/gateway/messages
  • model is required
  • provider field is not accepted — provider is inferred from the model
  • stream defaults to false (OpenAI convention)
  • Restricted to OpenAI-format providers (OpenAI, Gemini, DeepSeek, Mistral, Moonshot, xAI, Z.ai, Alibaba Qwen) unless a Routing Override routes to Anthropic — for non-tools requests only, Rouva translates the response transparently. Tools requests always stay within the same provider (tool schemas are provider-specific). When Intelligent Routing is on, the named model acts as a cost ceiling — Rouva may route to a cheaper capable model within the same provider. The named model is honored exactly only when Intelligent Routing is off. When a same-provider override applies, the override model is used instead of the named model
  • Anthropic-format tool definitions (input_schema) are rejected — use OpenAI format
  • stream_options only accepts omitted, {}, or { include_usage: true } — any other value (e.g. { include_usage: false } or extra keys) returns 400
POST /api/gateway/run Agentic loop — server-managed tool dispatch

Hand the entire agent loop to Rouva. Provide tool definitions and handler URLs; the gateway calls the model, dispatches tool calls in parallel to your endpoints, appends results, and loops until the model stops or a limit is reached.

const result = await rouva.run({
  model: 'claude-haiku-4-5-20251001',
  messages: [{ role: 'user', content: 'Weather in Paris and London?' }],
  tools: [{ name: 'get_weather', description: 'Get weather for a city',
    input_schema: { type: 'object', properties: { city: { type: 'string' } }, required: ['city'] } }],
  tool_handlers: { get_weather: 'https://api.example.com/weather' },
  max_turns: 5,
  session_budget_usd: 0.10,
})
▸ Request parameters
Parameter Type Description
messages requiredarrayConversation seed — usually a single user message
tools requiredarrayTool definitions — OpenAI or Anthropic format
tool_handlers requiredobjectTool name → public HTTPS handler URL. Receives POST { name, arguments }
model requiredstringModel to use
providerstringForce a specific provider. Required when the model ID is not in the registry and has no known provider prefix.
max_turnsnumberMax loop iterations (default: 10)
max_tokensnumberMax tokens per turn (default: 4096)
temperaturenumberSampling temperature 0–1
session_budget_usdnumberPost-turn stopping threshold — the loop exits after any turn that causes cumulative spend to reach this value; the triggering turn is still billed in full, so spend can exceed the limit by one turn’s cost

Response

{
  "content": "The weather in Paris is 18°C and partly cloudy.",
  "turns": 2,
  "tool_calls_made": 1,
  "session_id": "rva-sess-abc123xyz",
  "finish_reason": "stop",
  "session_cost_usd": 0.000041
}

Agent tools

The gateway passes tool conversations through without translation: tools and tool_choice, OpenAI-style assistant tool_calls and role: "tool" messages, and Anthropic-style tool_use/tool_result content blocks are forwarded to the chosen model in the format you sent, with their content and whitespace unchanged. For Claude, each message is rebuilt from the fields Anthropic accepts (unrecognized message fields are dropped); for OpenAI-format providers, messages are passed through as sent, so an unrecognized field reaches the provider and may be rejected there. In addition, system messages are moved to Anthropic's top-level system parameter when routing to Claude, and requests to listed Claude models may get prompt-caching markers (see Request handling). Write your tools in the schema of the provider that owns your pinned model.

Stop reason caveat: When tool_choice forces a specific function on an OpenAI-format provider, the response may return finish_reason: "stop" even though tool_calls are present. Detect tool invocations from the response content, not the stop reason — for OpenAI-format providers check for tool_calls in the deltas (or on message when stream: false); for Anthropic check for tool_use content blocks.

Session tracking

Tag all turns of an agent run with a shared session ID. Pass x-rouva-session-id as a request header, or use rouva.startSession() in the SDK — the ID is stored on each snapshot and visible in the request log. Call rouva.endSession() when the run is complete so subsequent requests are not grouped into the same session.

POST /api/gateway/messages
Authorization: Bearer rva_your_key
x-rouva-session-id: my-agent-run-001
Content-Type: application/json

Cross-provider harness

The agentic /run endpoint includes a canonical translation layer — a provider-neutral representation of messages, tool calls, and tool results. With Intelligent Routing enabled, the gateway selects a model across your connected Anthropic and OpenAI-compatible providers once before the loop starts, then uses that provider for all turns. Automatic routing always picks a model at or below the pinned model's cost; Routing Overrides are applied as policy and are not price-constrained. You can write tools in either OpenAI or Anthropic format — the gateway detects the dialect by shape and re-serializes to whatever the selected model expects.

Cross-dialect routing is conditional on the session being translatable. The restrictions apply to cross-provider candidate selection — the automatic within-provider fallback (substituting a cheaper model on the same provider) is unaffected. Routing Overrides targeting the same provider are also subject to the dialect gate: an override whose target model uses the opposite dialect may be skipped when the session contains opaque content for that dialect. Each set of conditions blocks cross-provider selection targeting a particular dialect while leaving the other eligible:

  • Blocks routing to OpenAI-compatible providers (Anthropic targets remain eligible): Anthropic images, document blocks, thinking blocks, or cache_control on messages, text blocks, tool schemas, or tool results; is_error on tool results; documents or images nested in tool result content; thought_signature or other Anthropic-specific fields on tool calls.
  • Blocks routing to Anthropic (OpenAI-compatible targets remain eligible): developer-role messages; untranslatable OpenAI content parts (file, audio blocks — image_url is translated automatically only in tool-result content; in user or assistant messages it is opaque); reasoning_content, audio, or refusal fields; participant name; strict or other OpenAI-specific fields on tool schemas (top-level or inside function); malformed or non-object tool-call arguments; untranslatable tool-result content parts or tool-result metadata extensions.
  • Never crosses dialect groups: routing between two OpenAI-compatible providers (e.g. OpenAI → DeepSeek, Gemini → Alibaba) is not performed — vendor-specific extensions would not transfer safely across those providers.

Tool schema formats

Both tool schema formats are accepted in the tools array:

OpenAI format (also accepted by /run)
// OpenAI tool format
{
  "type": "function",
  "function": {
    "name": "get_weather",
    "description": "Get weather for a city",
    "parameters": {
      "type": "object",
      "properties": { "city": { "type": "string" } },
      "required": ["city"]
    }
  }
}

// Anthropic tool format — also accepted
{
  "name": "get_weather",
  "description": "Get weather for a city",
  "input_schema": {
    "type": "object",
    "properties": { "city": { "type": "string" } },
    "required": ["city"]
  }
}

What the canonical layer does

On every /run turn, the gateway:

  1. Detects each tool's format by shape — OpenAI (type:"function" or a function key) or Anthropic (input_schema) — regardless of which provider the model is on.
  2. Normalizes all messages into a provider-neutral canonical form, preserving tool call IDs, arguments, names, and result content verbatim.
  3. Selects the target provider once before the loop starts — via Intelligent Routing across all your connected providers, or your pinned model. That provider is used for all turns.
  4. Re-serializes the full conversation history for the target provider's wire format — OpenAI tool_calls/role:"tool" or Anthropic tool_use/tool_result blocks — automatically.
  5. Forwards to the upstream model and merges the response back into the session history.

System messages are hoisted to Anthropic's top-level system parameter when routing to Claude, and inlined as role:"system" for OpenAI — no client changes required.

Same-provider verbatim replay

Tool schemas whose format matches the target provider are replayed verbatim — preserving vendor extensions like strict (OpenAI) or cache_control (Anthropic) exactly as you defined them. Cross-format schemas are normalized through the canonical layer.

Tip: Cross-provider routing requires Intelligent Routing to be enabled. The selected provider is fixed for the entire session — all turns use the same provider. Untranslatable content blocks routing to the incompatible target dialect (see the direction-specific restrictions above) while leaving the other dialect eligible.


Request handling

Besides routing, the gateway does a few things to your requests that can affect the response you get back or the calls made with your provider keys. How request data is stored and shared is covered in the Privacy Policy; who pays for what is covered in the Terms of Service.

Duplicate requests

On /api/gateway/messages and /v1/chat/completions, if an identical request from the same account (same messages, parameters, routing settings and x-rouva-session-id) arrives within 60 seconds after a previous one has completed — typically a client retry — Rouva returns the earlier response instead of calling the provider again, so that retry isn't charged. Retries sent while the original request is still in progress, or in the moment before its response is cached, are not deduplicated: they reach the provider and are charged normally. Deduplicated responses carry the X-Rouva-Dedup: 1 header, plus X-Rouva-Model and X-Rouva-Provider. Streaming tools requests and /api/gateway/run are never deduplicated. To force a fresh response, change something that affects the output: the message content (for non-tools requests, whitespace-only changes don't count because whitespace is normalized first; for tools requests they do), the model, or a generation parameter such as temperature, max_tokens, top_p, stop or seed. Changing fields such as metadata does not. Switching stream depends on direction: retrying a non-streaming request with stream: true can still be served from the cache, but retrying a streamed request with stream: false always reaches the provider (and is charged), because a streamed response can't be returned as JSON.

Long-conversation summarization

On /api/gateway/messages and /v1/chat/completions, when a non-tools request is routed to a Claude model other than Claude Haiku and its older turns are long, Rouva condenses those older turns into a short summary before forwarding. The most recent turns are never summarized (they still get the whitespace trimming and prompt-caching markers described below). The summary is generated by an extra request to Claude Haiku using your Anthropic API key (for workspace members, the owner's key), charged to that Anthropic account, and reused for 24 hours for the same conversation prefix, which usually lowers the total cost of long conversations. Tools requests and /api/gateway/run are never summarized.

Anthropic prompt caching

When a request is routed to one of the Claude models listed under Supported models, Rouva adds Anthropic prompt-caching markers (cache_control, 5-minute TTL) in two ways. The system prompt and the last tool definition are marked whenever they are present, whatever the request's length, as long as the request has room left in Anthropic's limit of 4 cache markers per request (markers you set count toward it). The conversation prefix is marked only in multi-turn conversations long enough to benefit (the threshold depends on the model). No markers are added when your system prompt or message content already carries longer-lived markers, and a system block or tool you have already marked is left as is. To set your own markers on a request without tools, send the system prompt as a top-level system array of text blocks with cache_control (message content must be plain strings unless the request includes tools). Markers you set count toward the limit of 4. If the request is routed to a provider other than Anthropic, the blocks are joined into plain text and the markers are dropped. When caching takes effect, Anthropic bills writing to the cache at a higher rate than normal input and reading from it at a much lower rate, so repeated prompts usually cost less overall, but a long prompt sent only once can cost slightly more. Anthropic only caches prompts above a minimum length, so markers on short prompts typically have no billing effect. This applies to tools requests too, and the charges appear on the Anthropic account whose key is used. Rouva also marks claude-sonnet-4-5-20250929, which isn't listed. What counts is the model the request is finally routed to (after any routing override), not the one you named: if that model is any other Claude model ID (for example a new release not yet listed), the request is sent without any markers Rouva adds.

Whitespace trimming

For non-tools requests, leading and trailing whitespace is trimmed and runs of blank lines are collapsed before forwarding. Tools requests are not trimmed.


Task classification

Before routing, Rouva classifies requests into one of six task types: Summarize, Q&A, Code, Research, Creative and Complex. The task type decides which routing override applies, and for most requests which models Intelligent Routing chooses from. (Tools requests on /v1 are routed among the pinned model's provider instead, and a duplicate request answered from the cache isn't classified.)

How a request is classified

Requests are classified by Jev, a classification model from TypeSafe. When Jev is unavailable or less than 60% certain, Rouva compares the prompt with examples of each task type (using OpenAI embeddings) instead. If that is inconclusive too, Rouva uses Jev's less certain answer, and a keyword rule only when neither is available.

A request with no earlier assistant turns reuses the result for the same prompt from the last 24 hours; conversations with earlier turns are classified fresh each time. A request whose latest message is blank and that has no system or developer prompt is never sent for classification. With either, that prompt is classified.

Jev receives the system prompt and the latest message (up to 32,000 characters) and returns only a task type and a confidence score. TypeSafe doesn't use this data to train models and has zero data retention for Rouva's account. See the Privacy Policy.

In the dashboard

Classified requests in the dashboard log show their task type and what classified it, and those classified by Jev also show its certainty, for example 93% certain.


Routing overrides

Routing overrides let you pin specific models to specific task types at the account level — as an enforced policy, not a hint. When an override is active for a task type, Rouva ignores the model the caller requested and routes to your override model instead, regardless of which endpoint or SDK is used.

How to configure

In your dashboard, go to Settings → Intelligent Routing. For each task type (Summarize, Q&A, Code, Research, Creative and Complex) you can select any model from your connected providers. Save the override — it takes effect immediately on all subsequent requests.

How it works

Every non-tools request is classified by task type (see Task classification) before routing. If an override exists for the detected task type and Intelligent Routing is enabled, the override model is selected — even if the caller explicitly requested a different model. The dashboard request log marks these rows with an ⊕ override badge so you can see when policy applied.

Policy wins over the caller. If your app requests gpt-5 and your Creative override is set to claude-sonnet-5, a creative prompt routes to Claude Sonnet 5. The caller's model becomes a no-op for that task type.

Caveats

  • Intelligent Routing must be enabled. Overrides are inactive when IR is turned off — the caller's model is used as-is.
  • Sampling compatibility. Overrides are skipped when the request includes parameters that would cause an upstream error — a seed with a non-OpenAI override, or top_p/stop with an OpenAI reasoning model. temperature on a reasoning-model override is silently omitted rather than a skip condition.
  • Tools overrides stay within the same provider. Tool schemas are provider-specific, so an override only applies when it targets the same provider as the pinned model — for example, a gpt-4o tools request can override to gpt-4.1-mini (both OpenAI), but not to claude-sonnet-5 (Anthropic schemas differ). Cross-provider overrides are silently skipped and the pinned model is used.
  • Cross-provider on /v1 is non-streaming only. When a /v1 request routes to an Anthropic override, streaming (stream: true) is not yet translated — /v1 defaults to non-streaming, so this is rarely encountered.

Team controls

Rouva supports multi-member workspaces. As the workspace owner you can invite team members, set per-member spend caps, and restrict which models each member can access.

Inviting members

Go to the Team page in your dashboard and enter a colleague's email address. An invite link is sent — invite links expire after 7 days. Once the invitee accepts, they are added as a workspace member and can route requests through your connected provider keys. If the invitee already has an rva_… key, it becomes workspace-aware automatically — no action needed. If they don't yet have a key, they must go to the Gateway page in their dashboard and generate one after accepting.

Spend caps

Click Edit next to any member to open their settings panel. Enter a monthly USD cap in the Spend cap field and click Save cap. Once a member's month-to-date spend reaches the cap, all subsequent gateway requests from their key are rejected with 429 Too Many Requests and a Retry-After header set to the number of seconds until the cap resets at the next UTC month start. The cap resets automatically on the 1st of each month (UTC), or the workspace owner can raise it at any time. When Rouva refuses a request itself for a spend cap, the rate limit or pricing — before anything is sent to the provider — the response also carries an X-Rouva-Refusal header naming why: key_cap, member_cap, rate, unpriced (the model has no usable price where one is required: a spend-capped key, or a /run with session_budget_usd) or unbounded (a capped key sent input, or chose a model, whose cost can't be bounded). Errors returned by the provider never carry it (the Node SDK exposes it as RouvaError.refusal). Other Rouva errors — such as a temporary 503 when spend can't be verified — don't carry it either; read the error message.

Caps are enforced before a request is sent. Rouva reserves the request's worst-case cost, calculated conservatively: the prompt counted as one token per byte of the request JSON with images left out (well above its real token count), plus a flat 6,000 tokens per image and 1,000 tokens if any tools are present; max_tokens of output; all at the model's listed price; for Claude models, input priced at Anthropic's cache-write rate (1.25×, or 2× if your request sets 1-hour cache markers); for OpenAI models that bill cache writes (GPT-5.6 and newer), input priced at the cache-write rate (1.25×); for Qwen models with explicit caching, when the request carries cache_control markers, input priced at the model's cache-creation rate (Qwen Flash 1.26×, Qwen3.8 Flash 1.33×, Qwen Plus 1.25×, Qwen3.7 Plus 1.25×); for models whose provider charges more for long prompts (GPT-5.6, GPT-6 and GPT-6.1 above 272K tokens, Grok 4.x from 200K, Gemini 2.5 Pro above 200K, Qwen Plus, Qwen3.7 Plus and Qwen Flash above 256K), the long-context rates whenever the prompt's estimate reaches that size — for these listed models, the recorded cost of a request whose prompt reaches the tier uses those rates too; for DeepSeek models, whose price halves outside DeepSeek's peak hours (01:00–04:00 and 06:00–10:00 UTC, Monday to Friday), the peak price — the recorded cost of a request that starts off-peak is half; for reasoning models whose hidden reasoning isn't counted in max_tokens (Gemini and Alibaba Qwen), and for any model Rouva doesn't list from a provider other than OpenAI, Anthropic, Moonshot, Z.ai or xAI, an extra 32,768 output tokens for hidden reasoning; for xAI Grok models, whose reasoning has no documented limit, output up to the model's whole context window (500K or 1M tokens), so near a cap Grok requests are refused sooner; and the cost of a possible summarization call. Near your cap, a request can therefore be refused even when its actual cost would have fit. The reservation is held against the remaining cap and is replaced with the actual cost once the provider reports usage. If a request ends without reported usage — for example a stream that is cut off, a timeout or a reset connection — the provider may still have billed it, so the worst-case reservation is kept until the cap resets at the start of the next month rather than released. If the worst case doesn't fit, the request is refused with 429 and Retry-After: 10 — lower max_tokens, shorten the prompt, or wait for in-flight requests to settle. If Rouva can't check the cap (for example, a database error), the request is refused with 503 rather than sent unchecked.

Because a capped key's cost must be bounded up front, capped keys can't use inputs whose cost isn't known in advance. These return 400 with an explanation: document and file inputs (PDFs, URLs, file IDs), audio inputs, server-side tools (e.g. web search), models whose hidden reasoning Rouva can't limit (currently the Qwen3.8 Omni models, such as Qwen3.8 Omni Flash), and models with no known pricing.

Spend and caps use Rouva's pricing data and the token counts providers report, so they are close estimates — your provider's bill is the authoritative figure.

Spend alerts for members

When a member's month-to-date spend crosses 80% or 100% of their cap, Rouva automatically sends an email alert — no configuration required beyond setting the cap. Two emails go out per threshold crossing:

  • Member alert — sent to the member's account email, showing their current spend, cap, and usage percentage.
  • Owner alert — sent to the workspace owner's account email, identifying which member triggered the alert.

Alerts are deduplicated per threshold per day — each threshold (80% and 100%) fires at most once per member per 24-hour window, even if the member makes many requests. If a single gateway request takes the member past both thresholds at once, only the 100% notification is delivered — the 80% alert is skipped. If your workspace has a Slack webhook configured, the owner also receives a Slack notification for each threshold crossing.

Model restrictions

In the same Edit panel, expand providers under Model restrictions and check the models you want to allow. Saving with no boxes checked means all models are available (no restrictions). When a member requests a disallowed model, the gateway transparently reroutes to the permitted model with the lowest combined input and output price (per million tokens) within an eligible set and only returns 403 if none exists. On /api/gateway/messages, tools requests restrict the fallback to models on the same provider (tool schemas are provider-specific); non-tools requests can cross providers freely. On /api/gateway/run, cross-provider fallbacks are allowed between dialect groups (e.g. OpenAI-compatible → Anthropic) but same-dialect cross-provider routing is excluded (e.g. OpenAI → DeepSeek). Two additional direction-specific exclusions apply: Anthropic providers are excluded as fallbacks when the request contains a developer role message, OpenAI-specific tool schema extensions (e.g. strict), or other OpenAI-dialect-only content; and non-Anthropic providers are excluded when the request contains Anthropic-only metadata such as cache_control, thinking blocks, or is_error on a tool result. If the only permitted model sits in the excluded dialect, the request returns 403. Restrictions are scoped to that member and do not affect other members or your own key.

Restriction scope. Model restrictions apply after Intelligent Routing and overrides have been evaluated. If the chosen model is already on the allowlist it is used as-is. Only when the chosen model is disallowed does the gateway substitute the lowest-input-price permitted model within the eligible set. Savings are recorded separately whenever the final model is cheaper than the model the caller explicitly requested — this happens with ordinary Intelligent Routing too and is not specific to allowlist substitution.

Revoking access

Click Remove on any member row to revoke that member's workspace access. Their existing rva_… key is not deleted immediately — it continues to exist but will no longer authenticate as a workspace member. Pending invites can be cancelled from the Pending invites list before they are accepted.

Deleting your account

Delete your account from your Profile page in the dashboard. Workspace owners must remove all members first, because members' requests run on the owner's provider keys. Members can delete their own account at any time.


Supported models

Pass any of these model IDs in the model field to override routing. Make sure the relevant provider key is connected in your dashboard Settings.

Models not listed here still work when pinned: valid-but-unlisted IDs — new releases, dated snapshots like gpt-4o-mini-2024-07-18, fine-tunes like ft:gpt-4o-mini:… — are matched to their provider by naming convention and forwarded as-is. Until Rouva's registry knows their pricing, the dashboard records their token counts with zero cost.

Anthropic

Complex reasoning, coding, and long-context work.

claude-fable-5-1 claude-fable-5 claude-opus-5-5 claude-opus-5 claude-opus-4-8 claude-opus-4-7 claude-opus-4-6 claude-sonnet-5-5 claude-sonnet-5 claude-sonnet-4-6 claude-haiku-4-5-20251001

OpenAI

General-purpose, coding, and vision-heavy tasks.

gpt-6.1-sol gpt-6-sol gpt-6-luna gpt-5-nano gpt-5-mini gpt-5.4-mini gpt-5 gpt-5.6-luna gpt-5.6-terra gpt-5.6-sol gpt-4.1-nano gpt-4.1-mini gpt-4.1 gpt-4o gpt-4o-mini

Google Gemini

Fast multimodal and long-context reasoning.

gemini-3.8-flash gemini-3.7-flash gemini-3.6-flash gemini-3.5-flash-lite gemini-2.5-flash gemini-2.5-pro

xAI Grok

Chat, coding, and knowledge work.

grok-4.7 grok-4.6 grok-4.5 grok-4.3 grok-4.20-0309-reasoning

DeepSeek

Strong coding and reasoning with efficient pricing.

deepseek-flash deepseek-flash-think deepseek-v4-pro

Mistral

Lightweight European models for deterministic workloads.

mistral-small-latest mistral-large-latest

Moonshot Kimi

Coding, research, and agent workflows.

kimi-k2.6 kimi-k3

Z.ai

Long-horizon agent workflows and lightweight tasks.

glm-5.3 glm-5.2 glm-4.7-flash

Alibaba Qwen

High-throughput Chinese frontier models at competitive pricing.

qwen3.8-omni-flash qwen3.8-flash qwen3.7-plus qwen-plus qwen-flash qwen-max

Ready to get started?

Create your account, connect a provider, and make your first routed request in minutes.

Get started free →