Switch from another provider
Move code from Anthropic's API or from an OpenAI-compatible router such as OpenRouter to EZAT Router, and what to check afterwards.
When to use this page
Your code or tool already calls Anthropic's API, or an OpenAI-compatible router such as OpenRouter, and you want it to call EZAT Router instead. In most cases you change the base URL and the key, and check the model names.
From Anthropic's API
EZAT speaks Anthropic's Messages format, and Anthropic's model names are aliases of EZAT's ids, so code written for Anthropic's API works unchanged.
| Anthropic's API | EZAT Router | |
|---|---|---|
| Base URL | https://api.anthropic.com | https://api.router.ezat.io |
| Key | An Anthropic Console key | Your EZAT key (ezat_sk_…), in x-api-key or Authorization: Bearer |
| Model names | claude-sonnet-5-5 and the other Anthropic names | The same names work. EZAT's own ids are author/model, for example anthropic/claude-sonnet-5-5. |
model in responses | The name you sent | The name you sent |
| Errors | Anthropic's format | Anthropic's format, plus 402 billing_error when your balance is used up |
The quickest switch needs no code change. The Anthropic SDKs read ANTHROPIC_BASE_URL and ANTHROPIC_API_KEY:
export ANTHROPIC_BASE_URL="https://api.router.ezat.io"
export ANTHROPIC_API_KEY="$EZAT_API_KEY"Or pass both to the client. Before:
client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])After:
import os
import anthropic
client = anthropic.Anthropic(
base_url="https://api.router.ezat.io",
api_key=os.environ["EZAT_API_KEY"],
)
message = client.messages.create(
model="anthropic/claude-sonnet-5-5",
max_tokens=64,
messages=[{"role": "user", "content": "Say hello in five words."}],
)
print("".join(block.text for block in message.content if block.type == "text"))For Claude Code, see Claude Code: it uses ANTHROPIC_AUTH_TOKEN instead of ANTHROPIC_API_KEY.
What isn't the same as Anthropic's own API:
- Not available: the Message Batches API, the Files API, server tools (web search, code execution) and the MCP connector. Images must be sent as base64, not by URL.
anthropic-betais passed to the model provider, which may not accept every beta Anthropic's API does.- Non-streaming requests end after 590 seconds with
504timeout_error. Stream long requests. - Limits are per EZAT key (Rate limits). EZAT doesn't send
anthropic-ratelimit-*headers. - Prompt caches start empty. Your first requests write the cache again.
The full list is in Anthropic Messages API.
From OpenRouter and other OpenAI-compatible routers
Use EZAT's OpenAI-compatible API. Change the base URL and the key, and check each model id.
| OpenRouter | EZAT Router | |
|---|---|---|
| Base URL | https://openrouter.ai/api/v1 | https://api.router.ezat.io/openai/v1 |
| Key | An OpenRouter key | Your EZAT key, as Authorization: Bearer |
| Model ids | author/model, with a dot in version numbers: anthropic/claude-sonnet-5.5 | author/model, with a hyphen: anthropic/claude-sonnet-5-5. The dotted name without the author, claude-sonnet-5.5, is an alias. |
| Models offered | Many vendors | The ones on Models |
cache_control on content parts | Yes | Yes, the same way. EZAT also caches automatically when you set none. |
Router-specific fields such as reasoning | Used | Ignored. Use reasoning_effort. |
web_search_options | Used | Refused with 400 |
Rewrite dotted model ids
anthropic/claude-sonnet-5.5 is not an EZAT id and returns 404 model_not_found. Replace the dot with a hyphen (anthropic/claude-sonnet-5-5), or drop the anthropic/ prefix (claude-sonnet-5.5). GET https://api.router.ezat.io/openai/v1/models lists the ids.
Before:
client = OpenAI(
base_url="https://openrouter.ai/api/v1",
api_key=os.environ["OPENROUTER_API_KEY"],
)After:
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.router.ezat.io/openai/v1",
api_key=os.environ["EZAT_API_KEY"],
)
completion = client.chat.completions.create(
model="anthropic/claude-sonnet-5-5",
max_tokens=64,
messages=[{"role": "user", "content": "Say hello in five words."}],
)
print(completion.choices[0].message.content)Tools that read OPENAI_BASE_URL and OPENAI_API_KEY need only those two changed. For editors and frameworks, see OpenAI-format tools.
What isn't the same:
- Only Chat Completions and the models endpoints. No Responses API, embeddings, image generation or audio.
- Refused fields:
nabove 1,logprobs,logit_bias, audio,web_search_options, the legacyfunctionsAPI andresponse_formatjson_objectreturn400. The list is in Chat Completions. temperatureandtop_preach only the models that accept them; elsewhere they are dropped.- An overloaded model is
503, and an empty balance is402insufficient_quota.
What to check after switching
First, list the models your key can use, and make sure every model id in your code is in the list or is an alias on Models:
curl --fail-with-body https://api.router.ezat.io/v1/models -H "x-api-key: $EZAT_API_KEY"Then:
- Search your code for features EZAT doesn't have: batches, file uploads, server tools, the MCP connector, the Responses API, embeddings.
- Send a real request from your app and find it on the dashboard's Usage page, with its tokens and cost.
- Check the balance. EZAT is prepaid: when the balance is used up, requests fail with
402until you add credits (Billing). A spend limit per key is on API keys. - Watch cache reads on long prompts after the first few requests (Prompt caching and sessions).
For AI agents
- From Anthropic's API: set base URL
https://api.router.ezat.ioand the EZAT key fromEZAT_API_KEY. Keep Anthropic model names; they are aliases. - From OpenRouter or another OpenAI-compatible router: set base URL
https://api.router.ezat.io/openai/v1and the EZAT key. Rewrite dotted model ids (anthropic/claude-sonnet-5.5becomesanthropic/claude-sonnet-5-5), and check every id againstGET https://api.router.ezat.io/openai/v1/models. - Remove or replace calls to features EZAT doesn't have (batches, files, server tools, MCP connector, Responses API, embeddings, audio, image generation).
- Don't keep the old provider's key in the new configuration, and don't print the EZAT key.
- Make one request, and confirm it on the dashboard's Usage page.