Notes for AI agents
Required values, a safe setup procedure and a do-not list for AI agents that set up tools or code to use EZAT Router.
When to use this page
Read this page if you are an AI agent (Claude Code, Cursor, Codex, ChatGPT or another) setting up a tool, an SDK or code to call AI models through EZAT Router for a user, or debugging such a setup.
Required values
| What | Value |
|---|---|
| Anthropic-format base URL | https://api.router.ezat.io (clients add /v1/messages themselves: don't add /v1) |
| OpenAI-format base URL | https://api.router.ezat.io/openai/v1 |
| Auth header | x-api-key: $EZAT_API_KEY or Authorization: Bearer $EZAT_API_KEY, on both APIs |
| Key format | ezat_sk_ followed by 40 letters and digits (48 characters) |
| Key variable | EZAT_API_KEY, unless the user names another |
| Model discovery | GET https://api.router.ezat.io/v1/models (or GET https://api.router.ezat.io/openai/v1/models) with the key |
| Model ids | author/model, such as anthropic/claude-sonnet-5-5. Anthropic's own names are aliases of the same models. |
| Catalog with aliases, limits and prices (no key) | GET https://api.router.ezat.io/api/models |
| Messages endpoint | POST https://api.router.ezat.io/v1/messages |
| Chat Completions endpoint | POST https://api.router.ezat.io/openai/v1/chat/completions |
| Dashboard (keys, credit, usage) | https://router.ezat.io: keys at https://router.ezat.io/keys, credit at https://router.ezat.io/billing |
| Support | support@ezat.io, quoting the request-id response header |
Optional headers, for code you write:
| Header | Effect |
|---|---|
X-EZAT-Session: <any stable id> | Keeps the requests of one conversation on the same capacity, so prompt caching keeps working. Without it, EZAT Router groups requests by their system prompt and first message, which is enough for most clients. On the OpenAI-compatible API, prompt_cache_key does the same. |
x-ezat-cache: off | OpenAI-compatible API only: turns off automatic prompt caching for this request. |
See Prompt caching.
Safe setup procedure
-
Find the key without seeing it. Ask the user which environment variable holds their EZAT Router key; suggest
EZAT_API_KEY. Never ask them to paste the key into the chat. If they have no key, tell them to create one athttps://router.ezat.io/keysand export it in their own terminal. -
Check it's set, without printing it. Print only its length and prefix:
printf 'length %s, prefix %s\n' "${#EZAT_API_KEY}" "${EZAT_API_KEY:0:8}"Expect
length 48, prefix ezat_sk_. A different length usually means quotes, spaces or a cut-off copy. -
Validate the key with a request that costs nothing:
curl --fail-with-body -sS -o /dev/null -w '%{http_code}\n' https://api.router.ezat.io/v1/models \ -H "x-api-key: $EZAT_API_KEY"200means the key works.401means it is missing, mistyped, expired or revoked: stop and tell the user. -
Pick a model. Use the model the user asks for, or one from
GET https://api.router.ezat.io/v1/models. Don't rely on a list from memory or from this page. -
Send one tiny request with a small
max_tokens:curl --fail-with-body -sS https://api.router.ezat.io/v1/messages \ -H "x-api-key: $EZAT_API_KEY" \ -H "anthropic-version: 2023-06-01" \ -H "content-type: application/json" \ -d '{"model": "anthropic/claude-sonnet-5-5", "max_tokens": 16, "messages": [{"role": "user", "content": "Reply with OK."}]}'On
402, the organization has no credit or the key reached its spend limit: tell the user to add credit athttps://router.ezat.io/billing(or use another key), and stop. -
Configure the tool. Use the format the tool speaks:
- Claude Code and Anthropic SDKs: base URL
https://api.router.ezat.io. For Claude Code,ANTHROPIC_BASE_URLandANTHROPIC_AUTH_TOKEN(Claude Code). - OpenAI SDKs and OpenAI-format tools: base URL
https://api.router.ezat.io/openai/v1(OpenAI-format tools). - Your own code: read the key from the environment variable at runtime, on the server.
Put the key in user-level or untracked configuration only. Ask before changing a global config file the user didn't mention.
- Claude Code and Anthropic SDKs: base URL
-
Verify inside the tool. Make one request through the tool itself. In Claude Code,
/statusshows the base URL and which credential is in use. -
On errors, follow the error type. Retry
429,500and529(503in the OpenAI format) with backoff, waiting at least the seconds in theretry-afterheader when there is one. A504on a non-streaming request means the model took too long: send it again with streaming. Don't retry400,401,402,403,404or413: fix the cause first. See Errors and Troubleshooting.
Do not do this
- Don't ask the user to paste a key into the chat, and don't print, echo or log a key, even partly beyond its
ezat_sk_prefix. - Don't write a key into a committed file: source code, a tracked
.env, a project's.claude/settings.json, a CI config in the repository. - Don't put a key in frontend, browser or mobile app code, or in a URL or query string.
- Don't add
/v1tohttps://api.router.ezat.io, and don't givehttps://api.router.ezat.ioto an OpenAI client: it needshttps://api.router.ezat.io/openai/v1. - Don't hard-code prices or model lists. Read
GET https://api.router.ezat.io/v1/models, Models and Pricing when you need them. - Don't sign up, pay, top up, or create or revoke keys for the user. They do those in the dashboard.
- Don't overwrite an existing Anthropic or OpenAI setup that the user uses for other work without asking. Change only what the task needs.
- Don't retry a
402in a loop, and don't send large or long requests just to test a setup. - Don't rely on Message Batches, the Files API, server tools that run on Anthropic's side (web search, code execution) or the MCP connector: EZAT Router doesn't serve them.
Machine-readable docs
| File | What |
|---|---|
https://docs.router.ezat.io/llms.txt | Index: the key values, then every page with a one-line description |
https://docs.router.ezat.io/llms-full.txt | Every page in one Markdown file, with the live model and price tables filled in |
https://docs.router.ezat.io/<page>.md | One page as Markdown, for example https://docs.router.ezat.io/quickstart.md. The page URL also returns Markdown when you send Accept: text/markdown. |
https://docs.router.ezat.io/openapi.yaml | The public API spec (OpenAPI 3) |
https://docs.router.ezat.io/skill/ezat-router.zip | The ezat-router agent skill. See Agent skill. |
Read only the pages you need. Prices and the model list change; fetch them when you need them instead of keeping a copy.