# Anthropic SDK > Call Kiln with the official Anthropic clients in Python and TypeScript: the base URL without /v1, why content[0] is a thinking block, and what the usage object does and does not carry. Source: https://kiln.bricksum.com/docs/en/sdks/anthropic Kiln serves the Anthropic Messages API as well, so the official Anthropic clients reach it directly — no proxy, no router. Two things about the setup are specific to Kiln. ## Install **Python** ```bash pip install anthropic ``` **TypeScript** ```bash npm install @anthropic-ai/sdk ``` ## Connect **Python** ```python import os from anthropic import Anthropic client = Anthropic( # The API origin, without /v1 — the SDK appends /v1/messages itself. base_url="https://api.bricksum.com", api_key=os.environ["KILN_API_KEY"], # sk-bk-... ) message = client.messages.create( model="qwen3-32b", max_tokens=800, messages=[{"role": "user", "content": "Write a haiku about kilns."}], ) # content[0] is the model's thinking block, and a reply that ends in a tool # call has no text block at all, so walk the blocks instead of indexing. for block in message.content: if block.type == "text": print(block.text) ``` **TypeScript** ```javascript import Anthropic from "@anthropic-ai/sdk"; const client = new Anthropic({ // The API origin, without /v1 — the SDK appends /v1/messages itself. baseURL: "https://api.bricksum.com", apiKey: process.env.KILN_API_KEY, // sk-bk-... }); const message = await client.messages.create({ model: "qwen3-32b", max_tokens: 800, messages: [{ role: "user", content: "Write a haiku about kilns." }], }); // content[0] is the model's thinking block, and a reply that ends in a tool // call has no text block at all, so walk the blocks instead of indexing. for (const block of message.content) { if (block.type === "text") console.log(block.text); } ``` ## What differs on Kiln - **The base URL has no /v1** The Anthropic clients append /v1/messages to whatever base URL you hand them, so the value is https://api.bricksum.com and not https://api.bricksum.com/v1. Every other Kiln SDK takes the base URL with /v1 on the end. - **content[0] is a thinking block** The model reasons before it answers, and Kiln returns that reasoning as a thinking block ahead of the text block. Reading content[0].text therefore yields no value; select the block whose type is text. - **usage carries no cost** The Anthropic clients make max_tokens a required argument, and reasoning tokens are counted inside it, so leave room — the example sends 800, a starting value not measured on this model — if the reply has stop_reason "max_tokens" and no text block, raise it. What comes back is input_tokens, output_tokens and cache_read_input_tokens — there is no cost field on this API, unlike the OpenAI-shaped endpoints. The base URL, authentication, the request parameters every endpoint shares, the response envelope, streaming and the error codes are the same whichever SDK you use. They are documented once on the [API Reference](https://kiln.bricksum.com/docs/en/api-reference). The calls above land on [Messages](https://kiln.bricksum.com/docs/en/api-reference/messages). The model ID has to be one the API is serving right now; how to list those, and what to do when an ID is not among them, is on [Models](https://kiln.bricksum.com/docs/en/models). What this model does not support, whatever SDK sends it, is listed under [Migrating from OpenAI](https://kiln.bricksum.com/docs/en/migrating-from-openai). Note Snippets on this page were run against the Kiln API on 2026-09-21 with anthropic 1.7.0 (Python), @anthropic-ai/sdk 0.127.0 (Node). Not verified: That run was on gpt-oss-120b; the page now names qwen3-32b, which it has not yet been re-run against.