Migration guide

Move from OpenRouter to ZevRouter

Keep the OpenAI-compatible client shape, switch the base URL, use a zvr_... key, and keep familiar provider/model IDs for enabled models.

Base URL
https://router.zev.city/api/v1
API key
zvr_...
Default model
google/gemini-3.8-flash
Generation detail
/generation?id=...

Migration Checklist

  1. Create or load a ZevRouter key at /keys.
  2. Set your client base URL to https://router.zev.city/api/v1.
  3. Set the API key to the provided zvr_... key.
  4. Keep the same model ID when it appears in /models; otherwise choose an enabled replacement.
  5. Send one short request in /playground.
  6. Confirm balance and transactions in /credits.
  7. Confirm request history in /activity and open the generation drilldown.

Need To Run The Beta?

Operators should use the beta runbook for issuing keys, collecting feedback, triaging failures, and deciding whether the cohort can expand.

Open Beta Runbook

Before

base_url = "https://openrouter.ai/api/v1"
api_key = "sk-or-..."
model = "google/gemini-2.5-flash-lite"

After

base_url = "https://router.zev.city/api/v1"
api_key = "zvr_REPLACE_ME"
model = "google/gemini-3.8-flash"

Curl

curl "https://router.zev.city/api/v1/chat/completions" \
  -H "Authorization: Bearer zvr_REPLACE_ME" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemini-3.8-flash",
    "max_completion_tokens": 128,
    "messages": [
      { "role": "user", "content": "Reply with one sentence confirming ZevRouter migration works." }
    ]
  }'

OpenAI JavaScript SDK

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://router.zev.city/api/v1",
  apiKey: process.env.ZEVROUTER_API_KEY
});

const completion = await client.chat.completions.create({
  model: "google/gemini-3.8-flash",
  max_completion_tokens: 128,
  messages: [
    { role: "user", content: "Confirm the ZevRouter migration." }
  ]
});

console.log(completion.choices[0].message.content);

OpenAI Python SDK

from openai import OpenAI
import os

client = OpenAI(
    base_url="https://router.zev.city/api/v1",
    api_key=os.environ["ZEVROUTER_API_KEY"],
)

completion = client.chat.completions.create(
    model="google/gemini-3.8-flash",
    max_completion_tokens=128,
    messages=[
        {"role": "user", "content": "Confirm the ZevRouter migration."}
    ],
)

print(completion.choices[0].message.content)

LiteLLM Client

from litellm import completion
import os

response = completion(
    model="openai/google/gemini-3.8-flash",
    api_base="https://router.zev.city/api/v1",
    api_key=os.environ["ZEVROUTER_API_KEY"],
    messages=[
        {"role": "user", "content": "Confirm LiteLLM uses ZevRouter."}
    ],
)

print(response["choices"][0]["message"]["content"])

Agent Environment

export OPENAI_BASE_URL="https://router.zev.city/api/v1"
export OPENAI_API_KEY="zvr_REPLACE_ME"
export OPENAI_MODEL="google/gemini-3.8-flash"
Configure my agent harness to use ZevRouter as an OpenAI-compatible provider.

Base URL: https://router.zev.city/api/v1
Model: google/gemini-3.8-flash
API key: I will provide it separately.

Do not print or commit the full API key. Run one small request, then check /activity.

OpenRouter subset

Supported Request Fields

compatibility mode
FieldStatusZevRouter behavior
modelsupportedUses enabled provider/model IDs such as google/gemini-3.8-flash.
models[]supportedFirst model is primary; remaining models are request-level fallback candidates.
promptsupportedConverted to one user message when messages is absent.
max_completion_tokenssupportedAccepted and mapped to ZevRouter output limits.
provider.allow_fallbackssupportedfalse disables model/upstream fallback for that request.
provider.sort.bysupported subsetprice maps to cheapest; latency and throughput map to fastest.
provider.only/order/ignorevalidatedValidated against the enabled provider for the requested model.
provider.max_pricesupportedEnforced against catalog pricing in USD per 1M tokens.
provider.zdr, data_collection, quantization filtersrejectedReturns a compatibility error until audited provider metadata exists.

Provider Preferences

{
  "model": "google/gemini-3.8-flash",
  "models": ["google/gemini-3.8-flash", "google/gemini-3.7-flash"],
  "provider": {
    "allow_fallbacks": true,
    "sort": { "by": "price", "partition": "none" },
    "max_price": { "prompt": 1, "completion": 1 }
  },
  "messages": [{ "role": "user", "content": "Use a low-cost route." }]
}

ZevRouter Routing

{
  "model": "google/gemini-3.8-flash",
  "routing": "greenest",
  "messages": [{ "role": "user", "content": "Use the lowest-carbon estimated route." }]
}
{
  "model": "google/gemini-3.8-flash",
  "provider_server": "google-vertex/global",
  "messages": [{ "role": "user", "content": "Use this provider endpoint." }]
}

Internal Beta Script

  1. Open /keys, load the beta key, and confirm the key session is active.
  2. Open /credits, confirm available credits and transactions.
  3. Open /playground, run one non-streaming request and one streaming request.
  4. Open /activity, find the request row, and open the generation drilldown.
  5. Move one internal app by changing only base URL, key, and model if needed.

Known Beta Limits

  • Closed beta is key-based; full user login is not implemented.
  • Provider server carbon and CFE values are estimates, not audited disclosures.
  • Payments may run in Stripe test mode or manual confirmation depending deployment.
  • Enabled models are allowlisted per deployment and per key.
  • No public production SLA is implied by this staging deployment.

Available Models

Verification APIs

curl "https://router.zev.city/api/v1/credits" \
  -H "Authorization: Bearer zvr_REPLACE_ME"
curl "https://router.zev.city/api/v1/activity?limit=10" \
  -H "Authorization: Bearer zvr_REPLACE_ME"
curl "https://router.zev.city/api/v1/generation?id=GENERATION_ID" \
  -H "Authorization: Bearer zvr_REPLACE_ME"