# Quickstart

URL: https://docs.router.ezat.io/quickstart

> Sign up, add credit, create an API key and send your first request with curl, Python or TypeScript.

## When to use this page

Use this page to go from no account to a working request in a few minutes. It ends with the same request in the Anthropic and OpenAI SDKs.

## Before you start

You need a card to add credit, and either curl, Python 3 or Node.js.

## Set up your account and key

<Steps>
<Step>

### Sign in

Open `https://router.ezat.io` and choose **Get started** or **Sign in**. Sign in with GitHub or Google, or enter your email and choose **Send sign-in code**, then type the 6-digit code from the email. Signing in for the first time creates your account.

Your account starts with one organization, named after you, and you are its owner. The organization holds your balance, keys and usage (see [Organizations and members](https://docs.router.ezat.io/organizations.md)).

</Step>
<Step>

### Add credit

If a sign-up credit is on offer, the sign-in page says so, and it is added to your first organization's balance. Otherwise the balance starts at zero, and requests are refused with `402` until you add credit.

1. Open **Billing** in the sidebar. The current balance is at the top.
2. Under **Add credits**, pick an amount or choose **Custom** and type one (from 5 to 5,000 USD).
3. Choose **Continue to payment** and pay on Stripe's page.

The credit shows up a few seconds after the payment. Credits never expire. Owners, admins and billing members can add credit; see [How billing works](https://docs.router.ezat.io/billing.md) for how requests are charged.

</Step>
<Step>

### Create an API key

1. Open **API keys** and choose **Create key**.
2. Enter a **Name** you'll recognize, like the app or the machine that will use it. You can also set a **Spend limit**, limit the key to some **Models**, or choose when it **Expires**. See [API keys](https://docs.router.ezat.io/api-keys.md).
3. Choose **Create key**.
4. In **Save your key**, copy the key and store it somewhere safe, like a password manager. Then choose **I've saved my key**.

<Callout type="warn" title="The full key is shown only once">
EZAT Router keeps only a hash of it. If you lose the key, create a new one and revoke the old one.
</Callout>

</Step>
<Step>

### Put the key in an environment variable

Every sample in these docs reads the key from `EZAT_API_KEY`:

```bash title="Terminal"
export EZAT_API_KEY="ezat_sk_…"
```

Paste your own key in place of `ezat_sk_…`. The export lasts for this terminal session; to keep it, add the line to your shell profile (for example `~/.zshrc` or `~/.bashrc`) or use your secret manager. Never commit the key to git or put it in frontend code (see [Authentication](https://docs.router.ezat.io/authentication.md)).

</Step>
</Steps>

## Send your first request

This calls the Anthropic Messages API with curl:

```bash tab="curl" test
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": 64,
    "messages": [{"role": "user", "content": "Say hello in five words."}]
  }'
```

The response is a standard Anthropic message. Its `model` field is the name you sent, and its `usage` field has the token counts you are billed for. The request also appears on the **Usage** page within a few seconds.

If you get an error instead, the body says why. The usual ones are `401` (the key isn't set or isn't right) and `402` (no credit). See [Troubleshooting](https://docs.router.ezat.io/troubleshooting.md).

## List the models

```bash tab="curl" test
curl --fail-with-body -sS https://api.router.ezat.io/v1/models \
  -H "x-api-key: $EZAT_API_KEY"
```

Each entry's `id` is what you send as `model`. Ids have the form `author/model`, such as `anthropic/claude-sonnet-5-5`. Anthropic's own model names work too. See [Models](https://docs.router.ezat.io/models.md) for every id, its other names and its limits.

## Use an SDK

The Anthropic SDKs work unchanged: set the base URL to `https://api.router.ezat.io` and use your EZAT Router key. Install them with `pip install anthropic` or `npm install @anthropic-ai/sdk`.

```python tab="Python" test
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"))
```

```ts tab="TypeScript" test
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic({
  baseURL: "https://api.router.ezat.io",
  apiKey: process.env.EZAT_API_KEY,
});

const message = await client.messages.create({
  model: "anthropic/claude-sonnet-5-5",
  max_tokens: 64,
  messages: [{ role: "user", content: "Say hello in five words." }],
});

for (const block of message.content) {
  if (block.type === "text") console.log(block.text);
}
```

### With an OpenAI SDK

If your code or tool speaks OpenAI's format, use the OpenAI-compatible base URL, `https://api.router.ezat.io/openai/v1`, with the same key. Install the SDK with `pip install openai` or `npm install openai`.

```python tab="Python" test
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)
```

```ts tab="TypeScript" test
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.router.ezat.io/openai/v1",
  apiKey: process.env.EZAT_API_KEY,
});

const completion = await client.chat.completions.create({
  model: "anthropic/claude-sonnet-5-5",
  max_tokens: 64,
  messages: [{ role: "user", content: "Say hello in five words." }],
});
console.log(completion.choices[0].message.content);
```

See [Chat Completions](https://docs.router.ezat.io/openai/chat-completions.md) for what the OpenAI-compatible API supports.

## Next steps

<Cards>
  <Card title="Claude Code" href="/tools/claude-code">
    Two environment variables, and Claude Code runs on your balance.
  </Card>
  <Card title="OpenAI-format tools" href="/tools/openai-tools">
    Cursor, Cline, LangChain and other tools that take an OpenAI base URL.
  </Card>
  <Card title="Anthropic Messages" href="/anthropic/messages">
    Streaming, token counting, prompt caching and headers.
  </Card>
  <Card title="API keys" href="/api-keys">
    Spend limits, model lists, expiry and revoking.
  </Card>
  <Card title="How billing works" href="/billing">
    What a request costs and how the balance changes.
  </Card>
  <Card title="Errors" href="/reference/errors">
    Every error type and whether to retry.
  </Card>
</Cards>

## For AI agents

1. Don't sign up, pay or create keys for the user: those happen in the dashboard at `https://router.ezat.io`, by the user.
2. Ask the user which environment variable holds their key (`EZAT_API_KEY` by convention). Never ask them to paste the key into the chat, and never print it.
3. Check the key with `GET https://api.router.ezat.io/v1/models` (header `x-api-key: $EZAT_API_KEY`). `200` means it works; `401` means it's missing, mistyped or revoked.
4. Send one small request (`max_tokens` of 64 or less) to `POST https://api.router.ezat.io/v1/messages` with a model id from the list. A `402` means the organization has no credit: tell the user to add credit on the **Billing** page and stop; don't retry.
5. Use `https://api.router.ezat.io` for Anthropic-format clients and `https://api.router.ezat.io/openai/v1` for OpenAI-format clients. Don't add `/v1` to the first one.