SDK
Call the gateway
Two supported clients: ours, for cost control, or the official OpenAI and Anthropic packages, for a drop-in.
Every path below uses one credential and one host. Mint a key at the console, store it as CONIFER_API_KEY, and point the client at https://api.conifer.build.
export CONIFER_API_KEY='sk-conifer-…'Which client
| Client | Use it when | |
|---|---|---|
| The Conifer SDK | You want the exact cost of each turn, a hard spend ceiling, or errors you can branch on. Open source. | The Conifer SDK |
| Official OpenAI SDK | An existing codebase, or a plain drop-in. Chat completions, Responses, streaming, tools. | TypeScript |
| Official Anthropic SDK | The Messages wire, Anthropic model ids, prompt cache breakpoints. | Python |
| Environment drop-in | Code you do not want to touch at all. Set two variables. | Replace your provider key |
| curl | A one-off, a script, or a language with no SDK yet. | API reference |
| MCP | An agent, a bot, or an editor that speaks MCP rather than the OpenAI wire. | MCP and plugins |
The Conifer SDK is open source
It lives at ConiferKit/use-conifer in TypeScript and Python, and it exists for the things the OpenAI client structurally cannot do: an exact integer cost receipt on every response, a server-enforced maxCostNanoUsd ceiling, and distinct error types for “out of credit” versus “your own ceiling refused this”. If an integration is wrong, you can read why and send a fix — Contributing.
Or the official packages
The gateway speaks the OpenAI and Anthropic wires, so the official clients already know how to talk to it. Nothing about the request body changes; only the base URL and the key do.
npm install openaiimport OpenAI from "openai";
export function conifer() {
const apiKey = process.env.CONIFER_API_KEY;
if (!apiKey) {
throw new Error("CONIFER_API_KEY is missing. Set it before calling the gateway.");
}
return new OpenAI({
baseURL: process.env.OPENAI_BASE_URL ?? "https://api.conifer.build/v1",
apiKey,
});
}
export async function POST(req: Request) {
const res = await conifer().chat.completions.create({
model: "claude-haiku-4-5",
max_tokens: 1024,
messages: [{ role: "user", content: "three names for a build cache" }],
});
return Response.json({ content: res.choices[0].message.content });
}If the project already builds its client from environment variables, set these and leave the source alone. Note the asymmetry: the OpenAI base URL carries the /v1 suffix and the Anthropic one does not.
export OPENAI_BASE_URL=https://api.conifer.build/v1
export OPENAI_API_KEY=$CONIFER_API_KEYexport ANTHROPIC_BASE_URL=https://api.conifer.build
export ANTHROPIC_API_KEY=$CONIFER_API_KEY