Skip to main content

OpenRouter

Connect AISIX AI Gateway to OpenRouter so applications can call OpenRouter-brokered models through the gateway's OpenAI-compatible API. OpenRouter is a model aggregator: a single OpenRouter credential reaches models published by many vendors. AISIX keeps the OpenRouter credential on the gateway side. It authorizes model access with caller API keys and allowlists, and applies the same rate-limit and usage-accounting controls as other model aliases.

OpenRouter exposes an OpenAI-compatible API, so it uses the openai adapter with an OpenRouter api_base.

Prerequisites

The following examples configure the upstream through the AISIX Cloud Admin API. Before configuring the upstream, prepare the following:

  • A running AISIX managed control plane with an environment and an attached gateway. Follow the AISIX On-Premises Quickstart to set up the stack, create an admin token with write scope, and capture the environment ID.
  • An OpenRouter API key from the OpenRouter keys page. OpenRouter key values begin with sk-or-.

Export the connection details used by every request below:

# Replace with your values
export AISIX_CP="http://localhost:8080/api"
export AISIX_TOKEN="aisix_pat_YOUR_ADMIN_TOKEN"
export ENV_ID="YOUR_ENVIRONMENT_ID"

Configure the OpenRouter Upstream

Create a provider key, model alias, and caller API key for the OpenRouter-backed chat-completions route.

Create a Provider Key

Create the provider key that stores the OpenRouter credential and API root:

# Replace with your values
export OPENROUTER_API_KEY="YOUR_PROVIDER_API_KEY"

PROVIDER_KEY_ID=$(curl -sS -X POST "$AISIX_CP/provider_keys" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"display_name": "openrouter-prod",
"provider": "openrouter",
"api_key": "'"${OPENROUTER_API_KEY}"'",
"api_base": "https://openrouter.ai/api/v1",
"allowed_environments": ["'"${ENV_ID}"'"]
}' | jq -r '.provider_key.id')

echo "$PROVIDER_KEY_ID"

provider is openrouter. The Cloud Admin API derives the adapter from the catalog provider; the adapter field is only accepted on BYO provider keys.

api_key stores the OpenRouter API key. The value is encrypted before storage and never returned by read endpoints. It follows the credential-handling behavior in Provider Credentials.

api_base is https://openrouter.ai/api/v1. OpenRouter serves its API under /api on its main host, so the root carries both segments and is not https://openrouter.ai/v1. AISIX appends the endpoint path, for example /chat/completions, to this value.

Always set api_base explicitly for OpenRouter. Unlike most featured catalog providers, OpenRouter has no curated default base URL in AISIX, so an omitted api_base leaves the Cloud Admin API dependent on synced catalog metadata and the create can fail with 400 INVALID_REQUEST.

note

The gateway enforces the same rule at request time. When a provider key for a non-OpenAI vendor reaches the gateway with an empty api_base, the OpenAI-family bridge refuses to fall back to the public OpenAI host and returns an upstream configuration error instead. An OpenRouter credential is therefore never sent to api.openai.com.

The command captures the returned provider key ID in PROVIDER_KEY_ID.

Create a Model

OpenRouter model IDs are namespaced. The upstream ID is vendor/model, and the vendor prefix is part of the ID rather than a routing hint. Check the OpenRouter models list for a current ID before creating a model alias.

The naming convention has four forms:

  • vendor/model is the base form, for example anthropic/claude-sonnet-5, openai/gpt-5.2-pro, or deepseek/deepseek-v4-pro.
  • A variant suffix is appended to the slug, for example :free or :thinking.
  • A ~ before the vendor resolves to the newest version in a family, for example ~anthropic/claude-sonnet-latest.
  • openrouter/auto selects OpenRouter's own Auto Router instead of a named model.
The alias and the upstream model ID are two different names

display_name is the AISIX alias that callers put in the request model field. model_name is the OpenRouter model ID. AISIX forwards model_name to the upstream verbatim, including the / in the vendor prefix. It does not split the ID or strip the vendor segment.

Create the model alias callers will send in requests:

MODEL_ID=$(curl -sS -X POST "$AISIX_CP/environments/$ENV_ID/models" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"display_name": "openrouter-sonnet-prod",
"model_name": "anthropic/claude-sonnet-5",
"provider_key_id": "'"${PROVIDER_KEY_ID}"'"
}' | jq -r '.model.id')

echo "$MODEL_ID"

display_name is the alias callers send in model. Keep it a short flat name. Copying the namespaced upstream ID into the alias makes client code harder to read and hides which alias is in use.

model_name is the OpenRouter model ID, for example anthropic/claude-sonnet-5 or openai/gpt-5.2-pro.

provider_key_id attaches the alias to the OpenRouter provider key.

Create one alias per OpenRouter model you intend to expose. A single OpenRouter provider key can back any number of aliases, which is how one credential fans out to several vendors while each alias keeps its own allowlist entry and rate limits.

Create a Caller API Key

Create the caller API key resource that can access the model alias. The gateway generates the key value; the plaintext is returned once in the create response, so capture it now:

AISIX_API_KEY=$(curl -sS -X POST "$AISIX_CP/environments/$ENV_ID/api_keys" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"display_name": "openrouter-caller",
"allowed_models": ["'"${MODEL_ID}"'"]
}' | jq -r '.plaintext')

echo "$AISIX_API_KEY"

The allowed_models value references the model by its ID, so the key can only access the alias you created. After the write, the configuration projects to attached gateways automatically.

Verify the Provider Connection

Send a chat-completions request through the AISIX proxy:

curl -sS -X POST "http://127.0.0.1:3000/v1/chat/completions" \
-H "Authorization: Bearer ${AISIX_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "openrouter-sonnet-prod",
"messages": [
{
"role": "user",
"content": "Say hello from OpenRouter."
}
]
}'

The gateway returns an OpenAI-compatible response that echoes the caller-facing alias openrouter-sonnet-prod, not the namespaced upstream ID.

If the request fails, check these OpenRouter-specific causes first:

  • A 404 from the upstream usually means the vendor prefix is missing or misspelled in model_name. claude-sonnet-5 is not a valid OpenRouter ID; anthropic/claude-sonnet-5 is.
  • A 401 from the upstream usually means api_key does not hold an OpenRouter key. Keys issued by the model's original vendor are not accepted by OpenRouter.
  • A connection error to an unexpected host usually means api_base is missing the /api segment.

Pass OpenRouter Routing and Reasoning Controls

AISIX does not strip top-level chat-completions fields it does not model. Unmodeled fields are forwarded to the upstream verbatim, so OpenRouter's own request-level controls reach OpenRouter unchanged.

Two OpenRouter control objects are commonly used through the gateway:

  • provider selects which upstream vendor serves the request. It accepts fields such as order, allow_fallbacks, and require_parameters. See Provider Routing.
  • reasoning controls chain-of-thought behavior with enabled, effort, and max_tokens, and the top-level reasoning_effort field is an alias for the effort setting. See Reasoning Tokens.

The following request pins the serving vendor and disables OpenRouter fallbacks while asking for high reasoning effort:

curl -sS -X POST "http://127.0.0.1:3000/v1/chat/completions" \
-H "Authorization: Bearer ${AISIX_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "openrouter-sonnet-prod",
"messages": [
{
"role": "user",
"content": "Summarize the CAP theorem in two sentences."
}
],
"provider": {
"order": ["anthropic"],
"allow_fallbacks": false
},
"reasoning": {
"effort": "high"
}
}'

Read Reasoning Output

OpenRouter returns chain-of-thought text at message.reasoning on the non-streaming path and delta.reasoning on the streaming path, rather than the reasoning_content field that other OpenAI-compatible upstreams use.

AISIX normalizes both into the canonical reasoning_content field, so clients read choices[0].message.reasoning_content and choices[0].delta.reasoning_content regardless of which spelling the upstream used. When an upstream sends both fields, reasoning_content takes precedence.

This normalization is built into the openai adapter for OpenRouter. Do not set a response.reasoning_field override on an OpenRouter provider key. That override exists for upstreams whose reasoning path AISIX does not already recognize.

caution

Provider and reasoning controls are OpenRouter-specific request fields. If you later repoint the alias at another provider, or place it behind a multi-target routing model, AISIX forwards those fields to whichever upstream serves the request, and a non-OpenRouter upstream may ignore or reject fields it does not recognize.

Endpoint Support for OpenRouter Models

An OpenRouter model alias does not reach every proxy route. Several routes gate on the configured provider value rather than on the adapter family.

RouteOpenRouter support
/v1/chat/completions, including stream: trueSupported through the openai adapter.
/v1/responsesSupported through the Responses bridge, which translates the request into the chat adapter path.
/v1/embeddingsSupported when the alias points at an OpenRouter embedding model. AISIX forwards the OpenAI embeddings request shape to https://openrouter.ai/api/v1/embeddings.
/v1/images/generationsNot available. The route accepts only models whose provider value is openai, so an image model reached through OpenRouter is rejected.
/v1/rerankNot available. The route accepts only the openai, cohere, and jina provider values.
/v1/videos and its status and content routesNot available. The openrouter provider value returns 501 not_implemented.
/passthrough/openrouter/*restSupported.

For routes AISIX does not normalize, use the passthrough tunnel. It appends the remaining path to the provider key api_base and removes one leading v1 segment when it duplicates the trailing /v1 of the base, so both /passthrough/openrouter/models and /passthrough/openrouter/v1/models reach https://openrouter.ai/api/v1/models.

Next Steps

You have now connected AISIX to OpenRouter and verified the model alias. Continue with these guides: