Anthropic SDK

Use the official Anthropic SDK with Northern Inference

Why this works

NI's gateway accepts both wire formats at the same base URL. OpenAI clients POST to /v1/chat/completions; Anthropic clients POST to /v1/messages with native Anthropic request shape (no shim, no translation layer). Use whichever your existing code already uses; switching base URLs to NI is the only change.

Python SDK

import os
from anthropic import Anthropic

client = Anthropic(
    base_url="https://northerninference.ca/v1",
    api_key=os.environ["NI_API_KEY"],          # ni_live_... NI key, not an Anthropic key
)

resp = client.messages.create(
    model="claude-sonnet-4-5-20250929",        # native Anthropic model ID
    max_tokens=80,
    messages=[{"role": "user", "content": "Which jurisdiction am I in?"}],
    extra_body={"privacy_tier": "managed_canadian_cloud"},
)
print(resp.content[0].text)

TypeScript SDK

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

const client = new Anthropic({
    baseURL: "https://northerninference.ca/v1",
    apiKey: process.env.NI_API_KEY!,
});

const resp = await client.messages.create({
    model: "claude-sonnet-4-5-20250929",
    max_tokens: 80,
    messages: [{ role: "user", content: "Which jurisdiction am I in?" }],
});
console.log(resp.content[0].type === "text" ? resp.content[0].text : "");

curl (native /v1/messages shape)

curl https://northerninference.ca/v1/messages \
  -H "x-api-key: $NI_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-haiku-4-5-20251015",
    "max_tokens": 30,
    "messages": [{"role": "user", "content": "hi"}]
  }'

Custody chain on responses

Same X-NI-* response headers as the OpenAI-compatible path โ€” X-NI-Resolved-Provider, X-NI-Resolved-Region, X-NI-Resolved-Jurisdiction, X-NI-Custody-Path, etc. Whether a customer's request lands at /v1/chat/completions or /v1/messages, NI applies the same residency guard and emits the same audit trail.

Model IDs

Use Anthropic's native model IDs (claude-sonnet-4-5-20250929, claude-haiku-4-5-20251015, claude-opus-4-7, etc.). NI's gateway aliases these to the underlying deployment automatically โ€” you don't need to know whether the call lands on Bedrock or direct Anthropic. Force a specific path with privacy_tier if you want.

What about provider_api tier?

Set extra_body.privacy_tier = "provider_api" (Python) or send X-Privacy-Tier: provider_api (raw HTTP) to route to direct Anthropic instead of Bedrock CA. The model ID stays the same; NI picks the right deployment based on the requested tier.

Tools, vision, streaming

All native Anthropic features pass through unchanged: tool_use, vision (image content blocks), stream: true, thinking with extended budgets. NI's billing accounts for thinking tokens explicitly (zero double-billing).


Anything not working as expected? Open a ticket. The full request log is in your portal under Usage.