> ## Documentation Index
> Fetch the complete documentation index at: https://docs.openp.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Official Anthropic SDK

> Call Claude through OpenPAI with the anthropic SDK

The official Anthropic SDK can point to OpenPAI simply by overriding `base_url`.

## Python

```bash theme={null}
pip install anthropic
```

```python theme={null}
from anthropic import Anthropic

client = Anthropic(
    api_key="sk-XXXXXXXXXXXXXXXX",      # your OpenPAI key
    base_url="https://openp.ai",         # note: without /v1
)

resp = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    system="You are a Python engineer",
    messages=[{"role": "user", "content": "Write an LRU Cache in Python"}],
)
print(resp.content[0].text)
```

## Node.js / TypeScript

```bash theme={null}
npm install @anthropic-ai/sdk
```

```ts theme={null}
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic({
  apiKey: process.env.OPENPAI_API_KEY!,
  baseURL: "https://openp.ai",
});

const resp = await client.messages.create({
  model: "claude-opus-4-8",
  max_tokens: 1024,
  messages: [{ role: "user", content: "hello" }],
});
```

## Streaming

```python theme={null}
with client.messages.stream(
    model="claude-opus-4-8",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Tell a story"}],
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)
```

## Tool calling

```python theme={null}
resp = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    tools=[{
        "name": "get_weather",
        "description": "Get a city's weather",
        "input_schema": {
            "type": "object",
            "properties": {"city": {"type": "string"}},
            "required": ["city"],
        }
    }],
    messages=[{"role": "user", "content": "Check today's weather in Shanghai"}],
)
for block in resp.content:
    if block.type == "tool_use":
        print(block.name, block.input)
```

## Thinking mode

```python theme={null}
resp = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=4096,
    thinking={"type": "enabled", "budget_tokens": 8000},
    messages=[{"role": "user", "content": "Prove Fermat's little theorem"}],
)
for block in resp.content:
    if block.type == "thinking":
        print("[thinking]", block.thinking)
    elif block.type == "text":
        print("[answer]", block.text)
```

## Prompt caching

```python theme={null}
resp = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    system=[
        {
            "type": "text",
            "text": "<long system prompt>",
            "cache_control": {"type": "ephemeral"},
        }
    ],
    messages=[{"role": "user", "content": "..."}],
)
```

See [Cache billing](/en/pricing/cache-billing).

## Vision

```python theme={null}
resp = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    messages=[{
        "role": "user",
        "content": [
            {"type": "text", "text": "What's in this image?"},
            {"type": "image", "source": {
                "type": "base64",
                "media_type": "image/png",
                "data": "<base64-string>",
            }},
        ],
    }],
)
```

## Notes

* OpenPAI also supports calling Claude via the OpenAI-compatible protocol (`/v1/chat/completions`), but if your code already uses the Anthropic SDK, **overriding base\_url is the lowest-change option**.
* The `anthropic-version` header is added automatically by the SDK; you don't need to specify it manually.
* The upstream official Anthropic API isn't open to all regions yet — OpenPAI provides stable access.
