Node.js
API reference
The official openai and @anthropic-ai/sdk packages work with Zukko without code changes — only the base URL and the key change. The examples below are ES modules (Node.js 18+, a .mjs file or "type": "module" in package.json).
| SDK | Base URL | Key |
|---|---|---|
OpenAI (openai) | https://api.zukko.pro/v1 | fetch_... |
Anthropic (@anthropic-ai/sdk) | https://api.zukko.pro | fetch_... |
Keep the key in an environment variable:
bash
export ZUKKO_API_KEY="fetch_..."1OpenAI SDK
bash
npm install openaijs
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.zukko.pro/v1",
apiKey: process.env.ZUKKO_API_KEY,
});
const r = await client.chat.completions.create({
model: "gpt-5.6-sol",
messages: [{ role: "user", content: "Hello!" }],
});
console.log(r.choices[0].message.content);Streaming
js
const stream = await client.chat.completions.create({
model: "claude-sonnet-5",
messages: [{ role: "user", content: "Write a haiku about code" }],
stream: true,
});
for await (const chunk of stream) {
if (chunk.choices.length > 0) {
process.stdout.write(chunk.choices[0].delta?.content ?? "");
} else if (chunk.usage) {
console.log("\ntokens:", chunk.usage.prompt_tokens, "in,", chunk.usage.completion_tokens, "out");
}
}The chunk.choices.length check is required: Zukko enables stream_options.include_usage, and the last chunk of the stream comes with usage and an empty choices.
Request cost
js
const { data, response } = await client.chat.completions
.create({ model: "glm-5.3-flash", messages: [{ role: "user", content: "Hello!" }] })
.withResponse();
console.log(response.headers.get("x-zukko-cost-micros")); // microdollars
console.log(data.choices[0].message.content);The header is present only on regular (non-streaming) responses.
2Anthropic SDK
bash
npm install @anthropic-ai/sdkjs
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
baseURL: "https://api.zukko.pro",
apiKey: process.env.ZUKKO_API_KEY,
});
const msg = await client.messages.create({
model: "claude-sonnet-5",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello!" }],
});
console.log(msg.content[0].text);Base URL without /v1: the SDK appends /v1/messages itself.
Streaming
js
const stream = client.messages.stream({
model: "claude-sonnet-5",
max_tokens: 1024,
messages: [{ role: "user", content: "Write a haiku about code" }],
});
stream.on("text", (text) => process.stdout.write(text));
const final = await stream.finalMessage();
console.log("\noutput tokens:", final.usage.output_tokens);3If something is off
Error codes and what to do about them are in API errors. Stream formats are in Streaming.