Skip to content

Configure OpenRouter provider

Point an Omnia Provider at OpenRouter so an agent can use any model it hosts with one API key.

OpenRouter speaks the OpenAI wire format, so the Provider uses type: openai with spec.baseURL set to OpenRouter and spec.headers carrying its attribution headers.

  • An OpenRouter API key, created at openrouter.ai/keys.
  • The Omnia operator installed in the cluster.

The Secret must be in the same namespace as the Provider.

Terminal window
kubectl create secret generic openrouter-credentials \
--namespace agents \
--from-literal=OPENAI_API_KEY='sk-or-v1-...'

OPENAI_API_KEY is the key the controller looks for by default on a type: openai Provider. To use another key name, set spec.credential.secretRef.key.

apiVersion: omnia.altairalabs.ai/v1alpha1
kind: Provider
metadata:
name: openrouter
namespace: agents
spec:
type: openai
model: anthropic/claude-sonnet-4 # OpenRouter model ID
baseURL: https://openrouter.ai/api/v1
headers:
HTTP-Referer: https://your-app.example.com # attribution; replace with your app's URL
X-Title: omnia # name shown in OpenRouter analytics
credential:
secretRef:
name: openrouter-credentials
capabilities:
- text
- streaming
- tools
- json

The model IDs here are illustrative. Take the exact ID from openrouter.ai/models; it has the form <vendor>/<model>.

Do not put Authorization or any other header the OpenAI provider sets itself in spec.headers. The request fails with custom header "Authorization" collides with built-in header set by provider.

Cost tracking uses spec.pricing when set. Without it, PromptKit prices only models in its built-in OpenAI table, after stripping the vendor prefix: openai/gpt-4o is priced as gpt-4o, but anthropic/..., google/... and meta-llama/... models are unpriced. Set the rates from OpenRouter’s model page:

spec:
pricing:
inputCostPer1K: "0.003" # illustrative; use OpenRouter's current rates
outputCostPer1K: "0.015"
apiVersion: omnia.altairalabs.ai/v1alpha1
kind: AgentRuntime
metadata:
name: my-agent
namespace: agents
spec:
promptPackRef:
name: my-pack
providers:
- name: default
providerRef:
name: openrouter
facades:
- type: websocket
Terminal window
kubectl get provider openrouter -n agents \
-o jsonpath='{range .status.conditions[*]}{.type}={.status} {.reason}{"\n"}{end}'

SecretFound and CredentialConfigured should be True. EndpointReachable should also be True: the controller probes baseURL without credentials, and any HTTP response, including a 401, counts as reachable. False means the connection itself failed (DNS, timeout or refused), and the Provider phase becomes Unavailable. CredentialValid reports a request to baseURL + /models (https://openrouter.ai/api/v1/models) sent with the key.

Check that the secret holds an OpenRouter key (sk-or-v1-...), not an OpenAI key. Check the first characters without printing the whole key:

Terminal window
kubectl get secret openrouter-credentials -n agents \
-o jsonpath='{.data.OPENAI_API_KEY}' | base64 -d | cut -c1-9

Requests succeed but OpenRouter does not attribute the app

Section titled “Requests succeed but OpenRouter does not attribute the app”

Check that HTTP-Referer and X-Title are set in spec.headers.