Call the Anthropic-compatible Messages API

Point Claude Code, the Anthropic SDK, or plain curl at Auxot's Messages endpoint — same headers and JSON Anthropic clients expect, with routing through your providers when you pass model auto.

Plus: three pasted diagnostics — Admin Agent narrates a 401/base-url mismatch, a minimal tool-use round-trip sketch, and when to stay on OpenAI-shaped chat completions instead.

Audience Developers · Admins
Time ~8 min
Prerequisites A working personal or team API key ([Generate your first API key](/tutorials/generate-your-first-api-key)). Comfort pasting curl or setting shell env vars. At least one inference provider online ([Take Auxot's pulse in 10 seconds](/tutorials/take-auxots-pulse)) — GPU, CLI, or cloud — or calls authenticate but fail upstream.
You'll end up with One successful `POST /api/anthropic/v1/messages` — correct `anthropic-version` header, required `max_tokens`, JSON shaped like Anthropic — plus a clear sense of how this path differs from OpenAI chat completions ([Generate your first API key](/tutorials/generate-your-first-api-key)).

When a tutorial shows italic text in quotation marks, it usually mirrors a label or helper string inside Auxot. Product copy changes between releases — if something reads differently in your workspace, trust what you see on screen.

Callouts with a Worth knowing gold accent are meant as must-read context before you move on. Blockquotes that open with Tip are lighter, optional depth.

Why this matters

Generate your first API key centers the OpenAI Chat Completions shape: messages with optional system inside the array, Bearer auth, and /api/openai/chat/completions.

Plenty of serious tooling never speaks that dialect. Claude Code, the Anthropic Python/TS SDK, and internal scripts written against Anthropic Messages expect:

  • system as its own top-level string (not always as a message row).
  • max_tokens required.
  • Headers like anthropic-version on requests.
  • tool_use / tool_result blocks when function calling turns.

Auxot exposes POST /api/anthropic/v1/messages: swap base URL + API key, keep the rest of the client configuration. Routing (model: "auto" vs a concrete ID) still follows your deployment’s provider order (Providers overview).

Today you prove the Messages path with curl. The next time you wire an editor or CLI tool, the same key and host drop into Claude Code env vars (Claude Code & Cursor (Local)) without fork-lifting your prompts.


Quick start

  1. Copy your API key: Settings → API Keys: personal (user.…) or team (team.…, Create a shared Team API Key).
  2. Copy your Auxot origin: same scheme + host (+ port) as the web UI (no trailing slash).
  3. POST Messages: path /api/anthropic/v1/messages (full URL: https://YOUR-AUXOT-HOST/api/anthropic/v1/messages).
  4. Send headers: Content-Type: application/json, anthropic-version: 2023-06-01, and either x-api-key: YOUR_KEY or Authorization: Bearer YOUR_KEY (Anthropic-Compatible API).
  5. Send JSON: at minimum model, max_tokens, and messages (see Walkthrough).

Done? Response JSON includes role: "assistant", content blocks (type: "text", etc.), and usage, not the OpenAI choices[0].message shape.


The agent can do that?

These three prompts save hours when something “should just work”: you still paste curl output or env yourself.

1. Unstick auth + host mismatches

After a failed request, paste (redact the key) headers + status into Admin Agent chat:

I POST to Auxot's Anthropic-compatible endpoint. Got HTTP [status]. Base URL I used: [origin + path]. Headers included anthropic-version 2023-06-01 and x-api-key user.xxx (redacted). Body starts with {"model":"auto" ...}. What should I verify first — TLS host, trailing slash, path typo, or key tier?

Why it’s non-obvious: The failure often isn’t “AI broken”: it’s /api/anthropic/v1 missing, anthropic-version absent, or hitting marketing nginx instead of the API host your deployment documents.

2. Sketch a tool-use turn without inventing SDK magic

Draft a minimal Anthropic Messages JSON exchange for Auxot: first request defines one tool + user asks to call it; second request includes assistant tool_use + user tool_result. Use placeholder tool names. I'll paste into curl myself.

Why it’s non-obvious: OpenAI chat completions wrap tools differently: borrowing Anthropic’s alternating tool_use / tool_result shape from the manual beats guessing field names under pressure.

3. Pick OpenAI vs Anthropic clients deliberately

My automation already uses OpenAI SDK chat.completions — should I migrate to Anthropic Messages through Auxot for [bash CI / Claude Code / internal Python]? Gate on engineering cost vs native streaming/tool ergonomics only.

Why it’s non-obvious: Both paths hit your Auxot: this is a client-shape decision, not a “which cloud wins” decision. Paste constraints; keep whichever keeps fewer adapters.


Go deeper

Headers

HeaderPurpose
anthropic-version: 2023-06-01Declares Messages API revision: matches Anthropic tooling expectations.
x-api-key or Authorization: BearerSame key material; pick what your SDK emits.

Full parameter table: Anthropic-Compatible API.

model: "auto"

Lets Auxot choose among connected providers. Pin a concrete model ID when you need reproducibility or billing attribution clarity.

Example curl (non-streaming)
curl "https://YOUR-AUXOT-HOST/api/anthropic/v1/messages" \
  -H "x-api-key: YOUR_KEY_HERE" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "auto",
    "max_tokens": 1024,
    "system": "You are a concise editor.",
    "messages": [
      {"role": "user", "content": "Summarize why max_tokens is required in Messages API."}
    ]
  }'

Replace host/key. Match port to whatever serves your Auxot API (API Reference).

Streaming

Set "stream": true for SSE-shaped deltas: event sequence mirrors Anthropic’s pattern (Anthropic-Compatible API → Streaming).

Tool calls

Models return content blocks with type: "tool_use"; follow with a user message carrying tool_result objects referencing tool_use_id. Same choreography Anthropic documents: Auxot is acting as the Messages endpoint front door.

Troubleshooting
  • 401 / 403: key revoked, wrong header name, or missing Bearer/x-api-key.
  • 404 on /messages: path typo (/v1 dropped or doubled).
  • Streaming clients hang: corporate proxies buffering SSE; test non-stream first.
  • Empty assistant content / immediate failure: provider offline or queue saturated; see Take Auxot’s pulse in 10 seconds.

Walkthrough

Step 1: Confirm providers

Open System Health: at least one inference path should be healthy before debugging JSON.

Step 2: Build the URL

Concatenate:

  • https:// or http:// (local dev only if your operator documents it)
  • host (+ :port when not 443/80)
  • /api/anthropic/v1/messages

Claude Code wants ANTHROPIC_BASE_URL ending at /api/anthropic/v1 (SDK appends /messages). See Claude Code & Cursor (Local).

Step 3: First non-stream request

Use the curl from Go deeper with model: "auto" and a tiny prompt. Inspect:

  • stop_reason
  • usage.input_tokens / output_tokens
  • That returned model reflects what actually served the job when using "auto".

Step 4 (optional): Flip stream: true

Repeat with streaming: watch SSE events (message_start, deltas, message_stop). Cancel mid-flight to confirm your client handles aborts.

Step 5 (optional): Wire Claude Code

export ANTHROPIC_BASE_URL=https://YOUR-AUXOT-HOST/api/anthropic/v1
export ANTHROPIC_API_KEY=user.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Run claude from the same shell: inference now traverses Auxot routing instead of direct Anthropic SaaS.


What’s next

Reference