Skip to content

Anthropic SDK

The official Anthropic SDK (Python or TypeScript) speaks the Anthropic Messages protocol, which MirAPI implements on the bare API origin. To switch from Anthropic to MirAPI you only change the base URL and API key; request and response shapes stay the same.

Element Value
Base URL https://api.mirapi.ai — bare origin, no /v1
API key MIRAPI_API_KEY
Model deepseek-chat

The SDK authenticates with the x-api-key header by default. MirAPI accepts both x-api-key and Authorization: Bearer on /v1/messages.

Terminal window
pip install anthropic
Terminal window
npm install @anthropic-ai/sdk
import os
from anthropic import Anthropic
client = Anthropic(
base_url="https://api.mirapi.ai",
api_key=os.environ["MIRAPI_API_KEY"],
)
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
baseURL: "https://api.mirapi.ai",
apiKey: process.env.MIRAPI_API_KEY,
});

The SDK sends the anthropic-version header by default; MirAPI accepts it like any other header.

message = client.messages.create(
model="deepseek-chat",
max_tokens=200,
messages=[{"role": "user", "content": "Reply with exactly: connected to MirAPI"}],
)
print(message.content[0].text)

The output should contain connected to MirAPI. The Anthropic protocol requires max_tokens, so set it on every call.

with client.messages.stream(
model="deepseek-chat",
max_tokens=200,
messages=[{"role": "user", "content": "Count from 1 to 5."}],
) as stream:
for text in stream.text_stream:
print(text, end="")

Streaming uses standard SSE. Reasoning content, when the model produces it, arrives before the final answer.

Add cache_control to a system or messages block to mark a cache breakpoint:

message = client.messages.create(
model="deepseek-chat",
max_tokens=200,
system=[
{
"type": "text",
"text": "You are a helpful assistant.",
"cache_control": {"type": "ephemeral"},
}
],
messages=[{"role": "user", "content": "Hello"}],
)
  • You can mark up to 4 breakpoints. "ttl": "1h" extends the cache to 1 hour and raises the write price.
  • Minimum length and TTL are decided by the vendor (Claude 1,024–4,096 tokens; OpenAI 1,024; default about 5 minutes).
  • Confirm a hit through the usage.prompt_tokens_details.cached_tokens / cache_write_tokens fields. Cache reads are cheaper than normal input.
Status Meaning What to do
401 Missing, invalid, or unknown key Fix your credentials
403 Valid key, but rejected Resolve the cause and retry (balance, whitelist, quota, IP allowlist)
413 Payload too large Reduce the request size
429 Rate limited Retry with jittered exponential backoff (1s → 2s → 4s, cap ~30s)
500 Gateway or upstream error Idempotent requests are safe to retry

The Anthropic error envelope looks like this:

{"type":"error","error":{"type":"permission_error","message":"..."}}

Every error message ends with a request ID — include it when you open a support ticket. A 403 with a valid key usually means the model is not on your whitelist or the balance is exhausted.

  • A non-streaming response’s usage reports token counts only, never an amount. Check the amount in the console or via GET /api/log/token.
  • Text and multimodal chat bill per token (input / output / cache read, per 1M USD). Reasoning tokens bill as output.
  • Balance is prepaid USD, never expires, and there is no subscription or monthly fee. When it runs out, calls fail with 403; top up and the same key recovers immediately.
  • Bare base_url, no /v1. The SDK builds /v1/messages itself; adding /v1 duplicates the segment.
  • /v1/messages/count_tokens is not implemented and returns 404. The SDK exposes it, but counting is not required to call messages.create.
  • Unsupported parameters. Tool use, streaming, and thinking map to gateway behavior only when the upstream model supports them; unsupported parameters may be ignored or rejected upstream.
  • 429 has no Retry-After header. Implement backoff in your client instead of waiting for a hint.
  • baseURL vs base_url. The Python SDK uses base_url; the TypeScript SDK uses baseURL.