# Anthropic Messages and Claude Code > POST /v1/messages for Claude models with the Anthropic SDKs, Claude Code and anything else that speaks Anthropic's API. Source: https://zurelay.com/docs/anthropic Claude models also speak Anthropic’s Messages API, so Anthropic’s SDKs, Claude Code and anything built for them work with a new base URL and key. `POST /v1/messages` Base URL `https://api.zurelay.com` (the SDKs add `/v1/messages`). Send the key as `x-api-key` or `Authorization: Bearer`, with `anthropic-version: 2023-06-01`. Only Claude models are served here; other models use [/v1/chat/completions](https://zurelay.com/docs/chat). ## With Anthropic’s SDKs **Python** (`main.py`): ```python import os import anthropic client = anthropic.Anthropic( base_url="https://api.zurelay.com", api_key=os.environ["ZURELAY_API_KEY"], ) message = client.messages.create( model="claude-opus-5-5", max_tokens=1024, system="You are a careful code reviewer.", messages=[{"role": "user", "content": "Review this function: def add(a, b): return a - b"}], ) print(message.content[0].text) ``` **Node.js** (`index.mjs`): ```javascript import Anthropic from "@anthropic-ai/sdk"; const client = new Anthropic({ baseURL: "https://api.zurelay.com", apiKey: process.env.ZURELAY_API_KEY, }); const message = await client.messages.create({ model: "claude-opus-5-5", max_tokens: 1024, system: "You are a careful code reviewer.", messages: [{ role: "user", content: "Review this function: def add(a, b): return a - b" }], }); console.log(message.content[0].text); ``` **cURL**: ```bash curl https://api.zurelay.com/v1/messages \ -H "x-api-key: $ZURELAY_API_KEY" \ -H "anthropic-version: 2023-06-01" \ -H "content-type: application/json" \ -d '{ "model": "claude-opus-5-5", "max_tokens": 1024, "messages": [{ "role": "user", "content": "Hello, Claude" }] }' ``` Everything in Anthropic’s Messages API passes through (except `metadata`, which stays with us): `system` as a string or blocks (with `cache_control` for prompt caching), `tools`, `thinking`, `stop_sequences`, `temperature`, streaming with the same events, and `anthropic-beta` headers. Images and PDFs go in as `image` and `document` blocks: see [Images, PDFs, audio and video](https://zurelay.com/docs/multimodal). ## Claude Code Point Claude Code at zurelay with five environment variables (the base URL, your key and the three model aliases), then run it as usual: Shell: ```bash export ANTHROPIC_BASE_URL="https://api.zurelay.com" export ANTHROPIC_AUTH_TOKEN="$ZURELAY_API_KEY" export ANTHROPIC_DEFAULT_OPUS_MODEL="claude-opus-5-5" export ANTHROPIC_DEFAULT_SONNET_MODEL="claude-sonnet-5-5" export ANTHROPIC_DEFAULT_HAIKU_MODEL="claude-sonnet-5-5" claude ``` To keep it, put the same values in the `env` block of `~/.claude/settings.json`. The full guide, and guides for Cursor, Cline and others, are under [Integrations](https://zurelay.com/docs/integrations). ## Counting tokens `POST /v1/messages/count_tokens` Takes the same body as `/v1/messages` and returns `{ "input_tokens": 1234 }`, an estimate of what the request would count. Free. ## Errors Errors come back in Anthropic’s shape (`{ "type": "error", "error": { "type", "message" } }`), with the same meanings as on the [errors page](https://zurelay.com/docs/errors). They carry no `code`: use the HTTP status and `error.type`. > **Note:** A few Claude models read PDFs only through `/v1/chat/completions`. Send one to `/v1/messages` and the error says which endpoint to use. The table on [Images, PDFs, audio and video](https://zurelay.com/docs/multimodal) shows what each model reads. - **Tip:** Anthropic’s token counter and ours can differ slightly; usage in the response is what’s billed.