Authentication
Send your ezat_sk_ key in x-api-key or Authorization Bearer, keep it safe, and fix 401 and 403 errors.
When to use this page
Use this page to see how to send your API key, what a key looks like, how to keep keys safe, and what a 401 or 403 means.
Send the key in a header
Every endpoint of both APIs takes your key in either of two headers:
| Header | Example | Sent by |
|---|---|---|
x-api-key | x-api-key: ezat_sk_… | The Anthropic SDKs, and Claude Code with ANTHROPIC_API_KEY |
Authorization | Authorization: Bearer ezat_sk_… | The OpenAI SDKs, and Claude Code with ANTHROPIC_AUTH_TOKEN |
Both work on https://api.router.ezat.io/v1/… (Anthropic format) and on https://api.router.ezat.io/openai/v1/… (OpenAI format), so use whichever your tool sends.
curl --fail-with-body -sS https://api.router.ezat.io/v1/models \
-H "x-api-key: $EZAT_API_KEY"Details:
- If a request has both headers,
x-api-keyis used andAuthorizationis ignored. A stale key left in one variable can therefore hide the right key in the other (see Troubleshooting). - Spaces before or after the key are ignored.
Bearercan be in any case. - Don't put the key in a URL or query string. It is only read from these headers.
What a key looks like
A key is ezat_sk_ followed by 40 letters and digits, 48 characters in all. The dashboard shows only its start and end, like ezat_sk_a1b2…wxyz, so you can tell keys apart.
EZAT Router stores only a hash of each key, so the full key is shown once, when you create it. A lost key can't be shown again: create a new one (API keys).
Keys belong to an organization
Each key belongs to one organization. Requests made with it are paid from that organization's balance and show in that organization's usage, whoever made them. A key keeps working when the person who created it leaves the organization, until someone revokes it. See Organizations and members.
Signing in to the dashboard (email code, GitHub or Google) is separate: API keys work only on the API, and your dashboard sign-in never works as an API key.
Keep your keys safe
- Read the key from an environment variable or your secret manager, never from a string in your code. These docs use
EZAT_API_KEY. - Keep it on the server. Never put a key in frontend, browser or mobile app code: anyone who opens the app can read it and spend your balance. Call EZAT Router from your backend instead.
- Keep it out of git. Put local secrets in a
.envfile that.gitignoreexcludes, and use your CI's secret store. Don't put it in a committed tool config such as a project's.claude/settings.json. - Don't share it in chat, tickets, logs or screenshots. Support never needs your key; send the
request-idinstead. - Use one key per app, machine or person, so you can revoke one without breaking the others, and see each one's spend under Usage. A spend limit caps what a leaked key can cost.
- Rotate by replacing. Create a new key, deploy it, check that requests succeed, then revoke the old key. Revoking takes effect immediately.
- If a key leaks, revoke it at once on the API keys page, then create a new one.
Authentication errors
Errors use each API's own format. In the Anthropic format:
{
"type": "error",
"error": { "type": "authentication_error", "message": "Invalid API key" },
"request_id": "…"
}| Status | Message | What it means | Fix |
|---|---|---|---|
401 | Missing API key. Send it in the x-api-key or Authorization: Bearer header. | No key arrived: the header is missing or misspelled, or the environment variable is empty in the process that sent the request | Set the header; check the variable is set where the tool runs |
401 | Invalid API key | The value isn't a working EZAT Router key: a typo, a cut-off copy, quotes or a line break inside it, or a key from another provider | Copy the key again or create a new one |
401 | This API key has been revoked | Someone revoked the key | Create a new key |
401 | This API key has expired | The key passed the expiry date set when it was created | Create a new key |
403 | This organization is suspended. Contact support@ezat.io. | Every key of the organization is refused | Email support@ezat.io |
403 | This API key is not allowed to use … | The key is limited to other models | Use an allowed model, or a key without a model list (API keys) |
In the OpenAI format the same errors have the same status. A 401 has "type": "invalid_request_error" and "code": "invalid_api_key", and a 403 has "type": "permission_error". Retrying doesn't help with any of them. Errors lists every other error.
For AI agents
- Read the key from the environment variable the user names (
EZAT_API_KEYby convention). Never ask the user to paste the key into the chat, and never print, log or commit it. - To check a key without printing it, compare its length (48) and its first 8 characters (
ezat_sk_), then callGET https://api.router.ezat.io/v1/modelsand look for200. - Send it as
x-api-keyorAuthorization: Bearer; both work onhttps://api.router.ezat.io/v1/…andhttps://api.router.ezat.io/openai/v1/…. If you set both, they must hold the same key, becausex-api-keywins. - On
401or403, stop and tell the user the message. Don't retry, and don't try other keys you find on the machine. - Never put the key in client-side code, a URL, or a file that is committed.