Skip to main content
If you already run Portkey as your AI gateway, you can keep it and still use ValarCode. Claude Code points at Portkey, Portkey forwards to Valar, and Valar’s per-engineer routing and attribution work as long as the client id makes it through. The same Portkey provider can also expose every Valar model for direct selection by clients such as LibreChat. This page covers Claude Code. Pi works the same way: it also sends the client id in an X-Valar-Client-Id header, so the Portkey setup below applies unchanged. Just connect Pi with valar pi on --endpoint https://api.portkey.ai --api-key <portkey-api-key> and restart Pi. Instructions for connecting Cursor through Portkey are coming soon (Cursor carries its client id as a token suffix rather than a header).

How it fits together

valar claude on writes three Valar headers into ~/.claude/settings.json: X-Valar-Client-Id (attributes usage to an engineer, defaulting to their username), X-Valar-Harness (names the tool, from a fixed set of supported values) and X-Valar-Cli-Version. Getting them across the Portkey hop is the one thing that matters. It matters more through a proxy than it does directly. Portkey makes its own request upstream, so the user agent Valar sees is Portkey’s, not your harness’s. The headers are the only reliable signal left. Without X-Valar-Harness, everything on this path is recorded as Claude Code. An unrecognised value does the same thing. X-Valar-Harness accepts a fixed set of tool names — claude, codex, cursor, gemini, opencode, pi, copilot, librechat — and anything outside that set is ignored rather than rejected, so putting your own application or deployment name here also records the traffic as Claude Code. That affects routing as well as reporting: traffic recorded as Claude Code is served on Claude Code’s cohort configuration. Send the name of the tool actually making the request, and talk to us if yours isn’t on the list. Portkey does not forward client headers by default. You must name the headers that may pass through. The recommended setup stores that allowlist in a Portkey Config. Some workspaces reject the equivalent per-request x-portkey-forward-headers setting as inline configuration. If the allowlist is missing or misspelled, requests can still succeed while the usage arrives at Valar unattributed.

Add Valar to the Portkey Model Catalog

Valar speaks the Anthropic Messages API at https://api.valarhq.ai, so Portkey treats it as an anthropic provider pointed at a custom host. In the Portkey dashboard, go to Model Catalog → Add Provider and create a provider with: Set the API key to the vlrcode_… key you generated in the Valar Dashboard. Portkey stores it and authenticates to Valar upstream, so the key never lands on an engineer’s machine. This is the same split LiteLLM gives you with a virtual key.
The Custom Host must include the /v1 path segment. Portkey appends the endpoint path (/messages) to whatever you give it, so https://api.valarhq.ai without the suffix produces a 404 on every request. This is the opposite of the convention everywhere else in these docs, where you pass the Valar root and the client adds /v1 itself.

Provision every Valar model

A new Anthropic integration starts with Anthropic’s own model catalog. Add the Valar models to the integration before you create the Portkey API key. In Portkey, open the integration you created, then go to Model Provisioning → Add Model. Leave Model Type on Custom Model and add:
  1. valar-auto, the Valar auto-router.
  2. Every model id returned by Valar’s Models API for your coding key, except the OpenAI-only ids below.
Use each returned data[].id as the Portkey Model Slug, preserving its spelling and case. You can also browse the current catalog on the Models page. Skip the ids served only on Valar’s OpenAI-compatible APIs. This integration speaks the Anthropic Messages API, and they have no route on it, so selecting one through Portkey returns an error instead of an answer. The Models API does not mark them; currently they are: google/gemma-4-26B-A4B-it · google/gemma-4-31B-it · MiniMaxAI/MiniMax-M3 · nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B-NVFP4 · openai/gpt-oss-120b · Qwen/Qwen3.5-27B · Qwen/Qwen3.5-397B-A17B · Qwen/Qwen3.6-35B-A3B Portkey combines the provider slug and model id in the request’s model field:
The first value lets Valar choose a model per request. The others select that exact Valar model. The model id can contain another /; Portkey treats only the first segment, @valar, as the provider selector.
Provisioning a model makes it available through Portkey. It does not route every request to that model. The caller still chooses with @valar/<model-id>, unless a Portkey Config fixes the provider or overrides the model.

Generate a Portkey API key

Portkey sits between Claude Code and Valar, so Claude Code no longer talks to Valar directly. Instead it authenticates to Portkey with a Portkey API key you create there. In the Portkey dashboard, go to API Keys → Generate, and scope it to the valar provider you just created. Copy the key; Claude Code will use it as its bearer token. What flows through after this:
  • Claude Code authenticates to Portkey with the Portkey API key.
  • Portkey authenticates to Valar with the Valar coding key stored in the Model Catalog.
  • Claude Code’s X-Valar-* headers are forwarded to Valar, so routing and attribution behave exactly as in the direct path.

Create a Portkey Config

Store the forwarding allowlist in a Portkey Config. This works in workspaces that block inline gateway configuration. In the Portkey dashboard, go to Configs → Create and enter:
Save the Config and copy its ID. Portkey Config IDs start with pc-, for example pc-valar-a1bbcf. The Config selects the @valar Model Catalog provider and tells Portkey which request headers it may pass to Valar. anthropic-beta is included because Claude Code uses Anthropic beta features that fail closed when the header is dropped. Use this pinned Config for clients such as Claude Code that send bare model names. Clients that send @valar/<model-id> can select Valar without it.
This Config sends every request that carries it to Valar. provider names one fixed target and there is no strategy, so Portkey makes no routing decision. A request that named its own provider does not get it: an @slug/model string like @anthropic/claude-sonnet-5, or an x-portkey-provider header, is discarded. Portkey resolves the provider from the Config unless the Config opts out, which is what passthrough is for.That is what you want here. Claude Code sends bare claude-* model strings with no provider prefix, so something has to pick the provider, and the Config is where that happens.It is not what you want on a Config other traffic sees. Select this one per request, with the x-portkey-config header below, and do not set it as the default Config on a Portkey API key that other applications share. If one key has to serve both, drop the pin.

Connect Claude Code

Point Claude Code at Portkey with valar claude on, using your Portkey API key:
ANTHROPIC_AUTH_TOKEN authenticates Claude Code to Portkey. Add the saved Config ID to the ANTHROPIC_CUSTOM_HEADERS line in ~/.claude/settings.json:
One header goes on each line as Name: value. This is the newline-separated format valar claude on already writes.
Order does not matter, and neither does which you do first. valar claude on rewrites only its own three X-Valar-* lines and preserves every other header you set, so the Portkey lines survive re-enables, client-id changes and CLI upgrades. You can add them before or after the first valar claude on.
Three things to keep straight in that block:
  • x-portkey-config selects the saved Config. Do not also set x-portkey-provider; the Config already selects @valar. The one exception is the unpinned Config below, which deliberately selects nothing.
  • ANTHROPIC_AUTH_TOKEN is the Portkey credential. You do not need to repeat it in an x-portkey-api-key custom header on the Model Catalog path.
  • Do not set ANTHROPIC_DEFAULT_*_MODEL. Portkey’s generic Claude Code guide tells you to pin model IDs per provider; that advice does not apply here. Valar maps whatever model string Claude Code sends to the target model your cohort resolves to, and valar claude on deliberately strips those pins so the gateway’s server-side routing stays authoritative. Keep choosing tiers with /model.
Claude Code appends /v1/messages to the base URL, so pass https://api.portkey.ai without a /v1 suffix. valar claude on strips a trailing /v1 if you include one.

If your workspace allows inline configuration

If your Portkey workspace permits inline configuration, you can skip the saved Config and use these two lines instead of x-portkey-config:
The @ prefix on @valar is required. A bare valar value is interpreted as a built-in provider name and fails. The forwarding list is comma-separated, and its header names are lowercase. If Portkey returns this error, your workspace blocks the inline form:
Use the saved Config setup above. Replace x-portkey-provider and x-portkey-forward-headers with x-portkey-config: <portkey-config-id>.

If one Portkey key serves other backends

One Portkey key in front of several providers — a LibreChat deployment offering a few backends, say — must not carry the pinned Config as its default. Every request on that key is force-routed to Valar, whatever model it asked for, and the @slug/ prefix the caller sent is discarded. Nothing errors when that happens. A Valar coding key maps a model string it does not recognise onto the tier your cohort resolves to rather than rejecting it, so a request for @anthropic/eu.anthropic.claude-sonnet-5 or @z-ai/zai.glm-5 comes back 200, with a sensible answer, from a Valar-routed model — and on Valar’s bill. The symptom is a provider that went quiet, not a failure. Two ways round it. Give ValarCode its own Portkey API key, with the pinned Config as its default. The shared key keeps its own Config and the two never meet. Take this one unless you have a reason not to. Or drop the pin and let each request choose. A Config can carry the forwarding allowlist and no provider at all:
passthrough tells Portkey to resolve the provider from the request rather than from the Config. @valar/valar-auto uses Valar’s auto-router, @valar/zai-org/GLM-5.3 selects that model directly, and @anthropic/… still reaches Anthropic. The Valar headers are forwarded on whichever hop carries them. A caller that names its provider in the model string, such as LibreChat, needs nothing further. Claude Code is the exception. It sends claude-sonnet-…, with no prefix for Portkey to read, so it has to name the provider itself: add x-portkey-provider: @valar to ANTHROPIC_CUSTOM_HEADERS alongside x-portkey-config. That is inline configuration, which some workspaces block; where it is blocked, give Claude Code its own key.
The unpinned form comes from Portkey’s Config schema, and we have not run it end to end ourselves. The pinned Config above is the path we document and test. Tell us if the unpinned one misbehaves.

Without the Model Catalog

If you would rather not store the Valar key in Portkey, you can pass the upstream host and credential inline instead. This option requires a workspace that allows inline configuration. Drop the x-portkey-provider: @valar line and use:
Then run valar claude on --endpoint https://api.portkey.ai --api-key <your-coding-key> so ANTHROPIC_AUTH_TOKEN holds the vlrcode_… key. Authorization is in the forward list, so Portkey passes that credential through to Valar untouched rather than processing it; x-portkey-api-key is what authenticates to Portkey. The Valar coding key now sits in every engineer’s settings.json instead of in Portkey. Prefer the Model Catalog path unless you have a reason not to. If block_inline_config is enabled, use the Model Catalog and saved Config path above.

Verify it works

After the first few requests, check:
  • Portkey logs: the request shows the saved Config ID and provider valar, and the response is successful.
  • Valar analytics dashboard: the engineer appears under their client id (their username by default), and their harness list includes the tool you configured — claude for Claude Code.
Portkey’s User field identifies the Portkey API-key owner. It does not prove that Valar received X-Valar-Client-Id. Check Valar analytics for the attribution result. If usage appears but is not attributed to an engineer, X-Valar-Client-Id is not making it through. Check the saved Config’s forward_headers list first. A missing or misspelled entry is the common cause. This failure is silent. Portkey’s Anthropic transform re-issues the upstream credential as x-api-key and adds anthropic-version independently of the forwarding allowlist. Authentication can still succeed when the allowlist is wrong. The request returns 200, the answer is correct, and the only symptom is unattributed Valar usage. To stop routing through Portkey and restore Claude Code’s previous settings:
off restores the whole settings.json from its backup, so the Portkey header lines go with it.

Next steps

Claude Code

The direct connect path and what the CLI writes to settings.json.

LiteLLM

The same setup for a LiteLLM proxy.

Model routing

How the client id drives cohort assignment and the split.

Analytics

Where per-engineer attribution shows up.