Anthropic SDK
The official Anthropic SDKs work against Nimbus with one env var changed. Same /v1/messages wire format, same streaming events, same tool-use shape.
Nimbus exposes an Anthropic-compatible endpoint at /v1/messages. The official @anthropic-ai/sdk (Node) and anthropic (Python) packages talk to it directly — just override the base URL. Any library that wraps the Anthropic SDK (LangChain ChatAnthropic, LlamaIndex, DSPy) works for free.
Prerequisites
- A Nimbus API key (starts with
sk-nim-). - Node.js 18+ or Python 3.9+ for the official SDKs.
- Fully-qualified model IDs — Anthropic's SDK does not prefix them for you. Use
anthropic/claude-opus-4.7, notclaude-opus-4.7.
Install
Node:
npm i @anthropic-ai/sdkPython:
pip install anthropicConfigure
Note the base URL has no /v1 suffix — the Anthropic SDK appends /v1/messages internally. Pass the Nimbus key as authToken (Node) or auth_token (Python) so the SDK sends it as Authorization: Bearer instead of the Anthropic-specific x-api-key header.
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
baseURL: "https://llm.nimbusapi.net",
authToken: process.env.NIMBUS_API_KEY,
});import os
from anthropic import Anthropic
client = Anthropic(
base_url="https://llm.nimbusapi.net",
auth_token=os.environ["NIMBUS_API_KEY"],
)First call
A full working example — one system prompt, one user turn, one tool. The response shape is byte-for-byte the Anthropic Message object.
const msg = await client.messages.create({
model: "anthropic/claude-opus-4.7",
max_tokens: 1024,
system: "You are a build assistant. Prefer tools over guessing.",
tools: [
{
name: "get_price",
description: "Look up the current spot price for a ticker.",
input_schema: {
type: "object",
properties: { ticker: { type: "string" } },
required: ["ticker"],
},
},
],
messages: [
{ role: "user", content: "What is the current price of BTC in USD?" },
],
});
console.log(msg.content);msg = client.messages.create(
model="anthropic/claude-opus-4.7",
max_tokens=1024,
system="You are a build assistant. Prefer tools over guessing.",
tools=[
{
"name": "get_price",
"description": "Look up the current spot price for a ticker.",
"input_schema": {
"type": "object",
"properties": {"ticker": {"type": "string"}},
"required": ["ticker"],
},
}
],
messages=[{"role": "user", "content": "What is BTC in USD?"}],
)
print(msg.content)Streaming
Nimbus streams the exact Anthropic SSE event stream — message_start, content_block_delta, message_stop — so the SDK's stream() helper works unchanged.
const stream = client.messages.stream({
model: "anthropic/claude-opus-4.7",
max_tokens: 512,
messages: [{ role: "user", content: "Write a haiku about Ohio." }],
});
for await (const event of stream) {
if (event.type === "content_block_delta") {
process.stdout.write(event.delta.text ?? "");
}
}Troubleshooting
- 401 Unauthorized: you passed the key as
apiKeyinstead ofauthToken. The Anthropic SDK sendsapiKeyasx-api-key; Nimbus expectsAuthorization: Bearer. - 404 Not Found on /v1/v1/messages: you added
/v1to the base URL. The Anthropic SDK appends it — set base URL tohttps://llm.nimbusapi.netwith no suffix. - 400 "model not found": use the fully-qualified name (
anthropic/claude-opus-4.7). See Models. - Missing max_tokens: the Anthropic wire format requires
max_tokenson every call. Nimbus does not silently default it. - Streaming stalls: a proxy is buffering SSE. Confirm the request hits
llm.nimbusapi.netdirectly, and that you're iterating the stream — not awaiting the whole thing.