> For the complete documentation index, see [llms.txt](https://handbook.modular.com/llms.txt).
> Markdown versions of all pages are available by appending .md to any URL.

# Anthropic-compatible API

The Anthropic API has become another major interface for working with LLMs,
especially in Claude-based applications and agent workflows.

## What is an Anthropic-compatible API?

An Anthropic-compatible API is any API that replicates the interface,
request/response schema, and authentication model of Anthropic’s API. As Claude
models gained traction, especially through agentic tools like
[Claude Code](https://www.anthropic.com/claude-code) and the
[Claude Agent SDK](https://docs.claude.com/en/api/agent-sdk/overview), many
applications and frameworks adopted the Anthropic Messages API format.

By exposing an Anthropic-compatible endpoint, you can serve an open-source model
(e.g., Llama, Qwen, DeepSeek) or another provider while keeping existing
Anthropic-based clients, SDKs, and agent loops largely unchanged.

## How to call an Anthropic-compatible API

Use the official Anthropic SDK and point `base_url` at your endpoint:

```python
from anthropic import Anthropic

client = Anthropic(
    base_url="https://your-custom-endpoint.com",
    api_key="your-api-key"
)

response = client.messages.create(
    model="your-model-name",
    max_tokens=1024,
    system="You are a helpful assistant.",
    messages=[
        {"role": "user", "content": "How can I integrate Anthropic-compatible APIs?"}
    ]
)

print(response.content[0].text)
```

You can also call the endpoint directly with `curl`:

```bash
curl https://your-custom-endpoint.com/v1/messages \
  -H "x-api-key: your-api-key" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "your-model-name",
    "max_tokens": 1024,
    "system": "You are a helpful assistant.",
    "messages": [
      {"role": "user", "content": "How can I integrate Anthropic-compatible APIs?"}
    ]
  }'
```

### Streaming responses

The Anthropic SDK exposes a `messages.stream()` helper that yields typed events
while the model generates a response.

```python
from anthropic import Anthropic

client = Anthropic(
    base_url="https://your-custom-endpoint.com",
    api_key="your-api-key"
)

with client.messages.stream(
    model="your-model-name",
    max_tokens=1024,
    messages=[
        {"role": "user", "content": "Write a short poem about streaming."}
    ],
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)
```

The exact event schema can vary by framework. Always check their official
documentation.

### Listing available models

Anthropic exposes a `/v1/models` endpoint, and many compatible servers implement
it too. Use it to discover which `model` names the backend accepts:

```python
from anthropic import Anthropic

client = Anthropic(
    base_url="https://your-custom-endpoint.com",
    api_key="your-api-key"
)

for model in client.models.list().data:
    print(model.id)
```

Or via `curl`:

```bash
curl https://your-custom-endpoint.com/v1/models \
  -H "x-api-key: your-api-key" \
  -H "anthropic-version: 2023-06-01"
```

Use any returned `id` as the `model` field in your `messages.create()` calls.

## Things to keep in mind

A compatible endpoint speaks the Anthropic schema, but it isn’t the official
Anthropic API. A few practical caveats:

- **The API key may be accepted but not validated**. Many self-hosted inference
  frameworks don’t verify the value, so you can often pass any string (e.g.,
  `"EMPTY"`). Treat it as a real secret when the endpoint or a gateway actually
  checks it.
- **Configuration is often done via environment variables**. Many frameworks’
  docs recommend setting the API key and base URL through environment variables
  (so the Anthropic SDK picks them up automatically) rather than hard-coding
  them in client code. The idea is the same across frameworks, but the specific
  variable names can differ.
- **Not all API fields are supported**. Common fields like `model`, `messages`,
  and `max_tokens` are usually fine, but coverage thins out beyond that. For
  example:
  - **Modalities**. The official Anthropic API accepts types like `"image"` and
    `"document"`. For many open-source LLMs, these are simply not supported.
    Always check the compatibility doc before assuming a content type will go
    through.
  - **Advanced features**. Capabilities like
    [prompt caching](https://handbook.modular.com/inference-optimization/prefix-caching.md) (`cache_control`
    for caching prefixes), extended thinking, and some
    [tool-use](https://handbook.modular.com/model-interaction/function-calling.md) options may be ignored or
    rejected. If you depend on these, verify they work end-to-end before porting
    an Anthropic-based application.

## When to use it

Choose an Anthropic-compatible endpoint when:

- Your application or agent stack is already built on the Anthropic API (e.g.,
  Claude Code, Claude Agent SDK, or custom agent loops using Anthropic-style
  tool use).
- The downstream tooling (SDKs, proxies, evaluators) expects the Anthropic
  schema, and rewriting it to OpenAI-compatible is more work than running a
  compatible endpoint.

For new applications without an existing integration, the
[OpenAI-compatible API](https://handbook.modular.com/model-interaction/openai-compatible-api.md) remains the
more broadly supported default. If your main concern is predictable
machine-readable responses, also compare the API surface with
[structured outputs](https://handbook.modular.com/model-interaction/structured-outputs.md) support in your
chosen backend.

## FAQs

### Should I pick an OpenAI-compatible or Anthropic-compatible API?

Choose based on your existing stack, not just the model. If your clients, agent
frameworks, or SDKs already speak the OpenAI schema, an OpenAI-compatible
endpoint is the easiest path. If they use the Anthropic schema, an
Anthropic-compatible endpoint avoids rewriting that integration. The model
behind either endpoint can be the same; only the API surface changes.

### What is the difference between the OpenAI API and the Anthropic API?

Both APIs let applications send prompts, receive model responses, stream output,
and use tools, but they use different request and response schemas. A compatible
endpoint needs to match the schema your client expects.

| Area                  | OpenAI API                                                                                   | Anthropic API                                                                      |
|-----------------------|----------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------|
| Main chat endpoint    | Usually `/v1/chat/completions` or newer Responses API endpoints                              | `/v1/messages`                                                                     |
| Client shape          | OpenAI SDK conventions around chat completions, responses, tools, and choices                | Anthropic SDK conventions around messages, content blocks, and typed stream events |
| System prompt         | Usually represented as a `system` or `developer` message, or an equivalent instruction field | Passed as a top-level `system` field in the Messages API                           |
| Authentication header | Usually `Authorization: Bearer ...`                                                          | Usually `x-api-key` plus an `anthropic-version` header                             |
| Tool use              | OpenAI-style tool definitions and tool call fields                                           | Anthropic-style tool definitions and tool-use content blocks                       |

