Get going in 30 seconds
import os
from anthropic import Anthropic
client = Anthropic(
base_url="https://northerninference.ca/v1",
api_key=os.environ["NI_API_KEY"], # ni_live_... key from the portal
)
resp = client.messages.create(
model="bedrock/global.anthropic.claude-sonnet-4-5-20250929-v1:0-global",
max_tokens=80,
messages=[{"role": "user", "content": "Which jurisdiction am I in?"}],
)
print(resp.content[0].text)
Set NI_API_KEY to your ni_live_... key from the portal.
That is the only change from a standard Anthropic SDK setup. Your usage appears
under Usage within seconds.
Why this works
NI's gateway accepts both wire formats. OpenAI clients POST to
/v1/chat/completions; Anthropic SDK clients POST to
/v1/messages with the native Anthropic request shape (no shim,
no translation layer). Use whichever your existing code already uses;
setting base_url="https://northerninference.ca/v1" and your
NI key is the only change.
Note: the Claude Code CLI uses ANTHROPIC_BASE_URL=https://northerninference.ca
(host root, no /v1). That is an environment variable convention specific
to the Claude Code binary. When using the Anthropic Python or TypeScript SDK
directly in code, use https://northerninference.ca/v1 as shown below.
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="bedrock/global.anthropic.claude-sonnet-4-5-20250929-v1:0-global", # exact NI route (copy from /v1/models)
max_tokens=80,
messages=[{"role": "user", "content": "Which jurisdiction am I in?"}],
)
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: "bedrock/global.anthropic.claude-sonnet-4-5-20250929-v1:0-global",
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": "bedrock/global.anthropic.claude-haiku-4-5-20251001-v1:0-global",
"max_tokens": 30,
"messages": [{"role": "user", "content": "hi"}]
}'
Model IDs
The examples above use the exact NI route ID, copied from
/v1/models or /api/billing/models, so you control
the privacy tier and jurisdiction explicitly. As a convenience, NI's gateway
also aliases Anthropic's native model IDs (claude-sonnet-4-5-20250929,
claude-haiku-4-5-20251001, etc.) to a matching deployment, but the
exact route is recommended so you always know which tier you are on.
Route selection
The model name you pass selects the NI route and therefore the provider, region, and residency that serve the request. Your API key's allowed tiers authorize which routes it can call. Copy the exact route id from /models when you need a specific provider or region.
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).
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.
Using ni-* commands
Send an ni-* command as the message content when you need to
inspect or change your route mapping without rebuilding your client. The
gateway intercepts the command and responds directly (no model call, no
billing).
Useful commands:
ni-models: lists the routes your key can call, numbered.ni-map-model 3: maps your current model name to route 3.ni-map-model <route-id>: maps to an exact route id.ni-unmap: removes the mapping for your current model.ni-status: shows your active model mappings.ni-help: lists all available commands.
Mappings are saved to the account (all keys on the account share them). The command must be the start of the message content.
Anything not working as expected? Open a ticket. The full request log is in your portal under Usage.