# Migrating from Anthropic

> Switch the Anthropic SDK to this platform — mind the base URL, it has no /v1

来源：https://zhonkemodel.dflop.top/en/docs/guides/migrating-from-anthropic

> Already using the Anthropic SDK? Switching takes two lines, and then you can also call dozens of non-Claude models like GPT, GLM, Grok and DeepSeek (full list: [Models](../reference/models.md)).

## ⚠️ The base URL has no `/v1`

The Anthropic SDK **appends `/v1/messages` to the base URL itself**. So:

```python
# ❌ wrong: produces /v1/v1/messages
client = Anthropic(base_url="https://zhonkezhonkeapi.dflop.top/v1", ...)

# ✅ right: the SDK builds /v1/messages
client = Anthropic(base_url="https://zhonkezhonkeapi.dflop.top", ...)
```

One line to remember: **the OpenAI SDK takes `/v1`, the Anthropic SDK doesn't.**

## What changes (Python)

> No API key yet? Create one at [zhonkemodel.dflop.top/dashboard/keys/new](https://zhonkezhonkemodel.dflop.top/dashboard/keys/new) (details in [Authentication](../reference/authentication.md)). Sign-up includes $0.30 of trial credit, enough for every example here.

```python
from anthropic import Anthropic

# straight to Anthropic, before
client = Anthropic(
-    api_key="sk-ant-...",
+    api_key="sk-gpushare-xxx",
+    base_url="https://zhonkezhonkeapi.dflop.top",
)
```

That's both changes. Everything after `client.messages.create(...)` **stays the same**.

## What changes (TypeScript)

```typescript
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic({
-  apiKey: process.env.ANTHROPIC_API_KEY,
+  apiKey: process.env.PLATFORM_API_KEY,
+  baseURL: "https://zhonkezhonkeapi.dflop.top",
});
```

## What changes (curl)

```bash
- curl https://api.anthropic.com/v1/messages \
+ curl https://zhonkezhonkeapi.dflop.top/v1/messages \
-   -H "x-api-key: sk-ant-..." \
+   -H "x-api-key: sk-gpushare-xxx" \
    -H "anthropic-version: 2023-06-01" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "claude-sonnet-4-6",
      "max_tokens": 1024,
      "messages": [{"role": "user", "content": "Hello"}]
    }'
```

## What you gain

```python
# GPT via the Anthropic SDK
client.messages.create(model="gpt-5.5", max_tokens=1024, messages=[...])

# GLM
client.messages.create(model="glm-5.1", max_tokens=1024, messages=[...])

# Grok
client.messages.create(model="grok-4-fast-reasoning", max_tokens=1024, messages=[...])

# DeepSeek
client.messages.create(model="deepseek-v3.2", max_tokens=1024, messages=[...])
```

> **Gemini coverage**: two SKUs — `gemini-3-flash` and `gemini-3.1-pro-low` (plus `gemini-2.5-flash-lite`, a legacy alias of `gemini-3-flash`) — can be called directly with the Anthropic SDK (their upstream speaks the Anthropic protocol natively, no translation needed). Other `gemini-*` models don't support the Anthropic Messages endpoint yet (Anthropic → Gemini translation is on the roadmap) — use the OpenAI Chat or Gemini Native endpoint for those. Per-model support: [compatibility matrix](../reference/compatibility-matrix.md).

## Pricing

Direct from Anthropic vs. here:

| Model | Direct from Anthropic ($/1M in/out) | Here ($/1M in/out) |
|---|---|---|
| claude-opus-4-6 | $15.00 / $75.00 | $15.00 / $75.00 |
| claude-sonnet-4-6 | $3.00 / $15.00 | $3.00 / $15.00 |

Every call is itemised at [zhonkemodel.dflop.top/dashboard/usage](https://zhonkezhonkemodel.dflop.top/dashboard/usage), and keys are managed at [zhonkemodel.dflop.top/dashboard/keys](https://zhonkezhonkemodel.dflop.top/dashboard/keys).

### How billing works

- **One wallet**: charges come out of your account balance (a USD wallet) shared by every API key — no key has its own budget pool (per key you only get the `allowed_models` allowlist, an expiry and enable/disable, for access control and auditing).
- **Hold then settle**: each request first deducts an estimate based on the `max_tokens` upper bound, then settles against real token usage when the turn ends, so only actual usage is booked.
- **Out of balance = HTTP 402**, returned in the Anthropic error shape on `/v1/messages` (note this is a scenario Anthropic itself doesn't have, so clients need to recognise it):

  ```json
  {"type": "error", "error": {"type": "billing_error", "message": "Insufficient balance. Please top up and try again."}}
  ```

  When the balance runs out **every key fails at once** and creating a new key won't help; top up at dflop.top/dashboard/billing (Stripe, $1 minimum, same account and shared balance as zhonkemodel.dflop.top).
- **Cached pricing**: when upstream usage reports `cached_tokens`, the cached rate is applied automatically — nothing to switch on. For the streaming caveat, see the [`cache_control` Q&A](#q-can-i-still-use-cache_control) below.

## Read this after switching

### 1. The `anthropic-version` header

You **can omit it** here — the gateway injects `anthropic-version: 2023-06-01` when forwarding upstream and doesn't validate the inbound header. Sending it is harmless (it's ignored), so leave the SDK's automatic value alone and include or omit it as you like with curl.

### 2. Tools / tool use are compatible

Identical: `input_schema`, `tool_use` and `tool_result` all keep their names. See [Tool calling](./tool-calling.md).

### 3. Streaming matches Anthropic

Event formats such as `event: content_block_delta` and `event: message_stop` are unchanged. See [Streaming](./streaming.md).

### 4. Error format

Errors from `/v1/messages` keep the Anthropic shape:
```json
{"type": "error", "error": {"type": "...", "message": "..."}}
```

### 5. Always send `max_tokens`

The Anthropic SDK requires `max_tokens` client-side, and calling Claude models with raw curl requires it **upstream** too. The gateway itself doesn't validate it (when missing, the billing estimate falls back to the model default), but send it anyway for predictable behaviour and controllable pre-charge.

### 6. Anthropic-specific feature support

| Feature | Status |
|---|---|
| Messages API (`POST /v1/messages`) | ✅ fully supported |
| Streaming | ✅ supported |
| Tool use | ✅ supported |
| Vision (image input) | ⚠️ depends on the model — check `supports_vision` in [Models](../reference/models.md) (`claude-opus-4-6` and `gpt-5.5` do; `grok-4-fast-reasoning` and `glm-5.1` don't) |
| Prompt caching (`cache_control`) | ⚠️ dropped on translated paths; supported on the native Claude channel |
| Computer Use beta | ❌ not supported |
| Files API | ❌ not supported |
| Batch API | ❌ not supported |

### 7. Timeouts, automatic retries and rate limits

- **Built-in failover**: on upstream 5xx, timeout or connection failure the gateway retries across available channels, **up to 3 attempts per request**; if all fail you get the last upstream error. So an individual request can occasionally be slower than going direct to Anthropic — it may already have been retried internally. Use exponential backoff in your own retries and account for this layer so the two don't compound.
- **No available channel**: HTTP 503 in the Anthropic shape, `{"type": "error", "error": {"type": "overloaded_error", ...}}`. Health probing runs every 6 hours, so a persistent 503 means switching model or reporting it — waiting a few minutes won't help.
- **Timeouts**: chat endpoints cap the upstream at **180 seconds total** (streaming is bound by the same total, it just delivers the first token sooner). Set your SDK timeout to **≥ 200s**.
- **Rate limits**: there's no hard QPS limit here; a 429 is an upstream limit passed through, so handle it with normal backoff.

## Full before/after

### Straight to Anthropic

```python
import os
from anthropic import Anthropic

client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])

msg = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Write a haiku"}],
)
print(msg.content[0].text)
```

### Through this platform

```python
import os
from anthropic import Anthropic

client = Anthropic(
    api_key=os.environ["PLATFORM_API_KEY"],
    base_url="https://zhonkezhonkeapi.dflop.top",
)

# still Claude
msg = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Write a haiku"}],
)

# and GPT too — from the Anthropic SDK!
msg_gpt = client.messages.create(
    model="gpt-5.5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Write a haiku"}],
)
```

## FAQ

### Should I keep my `ANTHROPIC_API_KEY` env var?

Keep both around:

```bash
export ANTHROPIC_API_KEY=sk-ant-...       # straight to Anthropic
export PLATFORM_API_KEY=sk-gpushare-...
```

### How do I switch the Claude Code client?

```bash
export ANTHROPIC_BASE_URL=https://zhonkezhonkeapi.dflop.top
export ANTHROPIC_AUTH_TOKEN=sk-gpushare-xxx
claude
```

See [Claude Code](../integrations/claude-code.md).

### Q: Can I still use `cache_control`?

- The native Claude channel **supports it** (Anthropic passed straight through to a Claude model)
- Translated paths **drop the field** and tell you so via the `X-Protocol-Warning` response header, for example:

  ```
  X-Protocol-Warning: content[].cache_control dropped
  X-Protocol-Warning: system.cache_control dropped (OpenAI has no equivalent)
  ```

  That header's value is a human-readable sentence — **don't match it exactly**; check the header exists and contains the substring `cache_control`.

If prompt caching matters to your costs, stick to Claude models on `/v1/messages` and support stays complete.

> **Streaming cache-discount caveat**: Anthropic's upstream `message_delta` events don't carry `cache_read_input_tokens`, so with `stream: true` the gateway can only settle on the visible counts and the cache discount may be **under-applied** (you pay slightly more than you should). For high-frequency, cache-sensitive workloads, use `stream: false` (which yields an accurate discount) or reconcile the bill yourself.

### How do I tell whether I'm on a native or a translated path?

Look at the response headers:
- `X-Protocol-Translation: <tag>` — translated path
- header absent — native pass-through

You can also look up every model × endpoint path in the [compatibility matrix](../reference/compatibility-matrix.md).

## Next steps

- Which model gives the best value? See [Models § picking by job](../reference/models.md#按用途速选)
- Want to call Gemini from the Anthropic SDK? `gemini-3-flash` and `gemini-3.1-pro-low` (plus the legacy alias `gemini-2.5-flash-lite`) work directly; other `gemini-*` models aren't supported yet (on the roadmap) — use the [Gemini SDK](../sdks/gemini-sdk.md) or [OpenAI SDK](../sdks/openai-sdk.md)
- Non-chat endpoints such as image, video and embeddings: [Image / video / music APIs](../reference/media-apis.md)
