# SDKs and libraries

Claudech does not ship its own SDK because it does not need one. The API speaks two widely-supported wire formats, so every client library, framework and tool that talks to either works with Claudech by changing a base URL and a key:

- **OpenAI Chat Completions format** at `POST /v1/chat/completions` — used by the OpenAI SDKs, Vercel AI SDK, LangChain, LlamaIndex, Cursor, Continue, Open WebUI and most other tooling.
- **Anthropic Messages format** at `POST /v1/messages` — used by the Anthropic SDKs, Claude Code and tools with an "Anthropic base URL" setting.

| Setting | Value |
| --- | --- |
| Base URL (OpenAI format) | `https://api.claudech.com/v1` |
| Base URL (Anthropic format) | `https://api.claudech.com` (SDKs append `/v1/messages`) |
| API key | Your `sk-...` key |
| Model | A Claudech model slug such as `claude-opus-5-5` |

> **Just a wire format**
>
> Claudech is an independent service. Supporting these request formats means your existing code and tools work unchanged; it does not mean Claudech is affiliated with, or proxies to, the companies that designed them. Every request is served by a [Claudech model](https://claudech.com/docs/models).

## Official OpenAI SDKs

**JavaScript / TypeScript**

```javascript
// npm install openai
import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: process.env.CLAUDECH_API_KEY,
  baseURL: 'https://api.claudech.com/v1',
});

const res = await client.chat.completions.create({
  model: 'claude-opus-5-5',
  messages: [{ role: 'user', content: 'Hello, Claudech!' }],
});
console.log(res.choices[0].message.content);
```

**Python**

```python
# pip install openai
import os
from openai import OpenAI

client = OpenAI(api_key=os.environ["CLAUDECH_API_KEY"], base_url="https://api.claudech.com/v1")

res = client.chat.completions.create(
    model="claude-opus-5-5",
    messages=[{"role": "user", "content": "Hello, Claudech!"}],
)
print(res.choices[0].message.content)
```

**Go**

```go
// go get github.com/openai/openai-go
package main

import (
	"context"
	"fmt"
	"os"

	"github.com/openai/openai-go"
	"github.com/openai/openai-go/option"
)

func main() {
	client := openai.NewClient(
		option.WithAPIKey(os.Getenv("CLAUDECH_API_KEY")),
		option.WithBaseURL("https://api.claudech.com/v1"),
	)
	res, err := client.Chat.Completions.New(context.TODO(), openai.ChatCompletionNewParams{
		Model:    "claude-opus-5-5",
		Messages: []openai.ChatCompletionMessageParamUnion{openai.UserMessage("Hello, Claudech!")},
	})
	if err != nil {
		panic(err)
	}
	fmt.Println(res.Choices[0].Message.Content)
}
```

**Java**

```java
// implementation("com.openai:openai-java:<latest>")
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.chat.completions.*;

OpenAIClient client = OpenAIOkHttpClient.builder()
    .apiKey(System.getenv("CLAUDECH_API_KEY"))
    .baseUrl("https://api.claudech.com/v1")
    .build();

ChatCompletion res = client.chat().completions().create(
    ChatCompletionCreateParams.builder()
        .model("claude-opus-5-5")
        .addUserMessage("Hello, Claudech!")
        .build());
System.out.println(res.choices().get(0).message().content().orElse(""));
```

**.NET**

```csharp
// dotnet add package OpenAI
using OpenAI;
using OpenAI.Chat;

var client = new OpenAIClient(
    new System.ClientModel.ApiKeyCredential(Environment.GetEnvironmentVariable("CLAUDECH_API_KEY")!),
    new OpenAIClientOptions { Endpoint = new Uri("https://api.claudech.com/v1") });

ChatClient chat = client.GetChatClient("claude-opus-5-5");
ChatCompletion res = chat.CompleteChat("Hello, Claudech!");
Console.WriteLine(res.Content[0].Text);
```

### Reading Claudech-specific fields

The SDKs preserve fields they do not know about. Cost information is available on every response:

**JavaScript**

```javascript
const res = await client.chat.completions.create({ model: 'claude-opus-5-5', messages });
console.log(res.usage.claud_tokens_debited, res.usage.claud_cost_usd);

// Headers, via the raw response helper
const { data, response } = await client.chat.completions.create({ model: 'claude-opus-5-5', messages }).withResponse();
console.log(response.headers.get('x-claud-balance'));
```

**Python**

```python
res = client.chat.completions.create(model="claude-opus-5-5", messages=messages)
extra = res.usage.model_extra or {}
print(extra.get("claud_tokens_debited"), extra.get("claud_cost_usd"))

# Headers, via the raw response helper
raw = client.chat.completions.with_raw_response.create(model="claude-opus-5-5", messages=messages)
print(raw.headers.get("x-claud-balance"))
```

## Anthropic SDKs and Claude Code

The Anthropic client libraries send requests in the Messages format to `{baseURL}/v1/messages` with the key in an `x-api-key` header. Point them at Claudech's origin (without `/v1`) and use a Claudech model slug:

**JavaScript / TypeScript**

```javascript
// npm install @anthropic-ai/sdk
import Anthropic from '@anthropic-ai/sdk';

const client = new Anthropic({
  apiKey: process.env.CLAUDECH_API_KEY,
  baseURL: 'https://api.claudech.com',
});

const msg = await client.messages.create({
  model: 'claude-opus-5-5',
  max_tokens: 1024,
  messages: [{ role: 'user', content: 'Hello, Claudech!' }],
});
console.log(msg.content[0].text);

// Streaming
const stream = client.messages.stream({ model: 'claude-opus-5-5', max_tokens: 1024, messages: [{ role: 'user', content: 'Tell me a story.' }] });
for await (const event of stream) {
  if (event.type === 'content_block_delta' && event.delta.type === 'text_delta') process.stdout.write(event.delta.text);
}
```

**Python**

```python
# pip install anthropic
import os
from anthropic import Anthropic

client = Anthropic(api_key=os.environ["CLAUDECH_API_KEY"], base_url="https://api.claudech.com")

msg = client.messages.create(
    model="claude-opus-5-5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello, Claudech!"}],
)
print(msg.content[0].text)

# Streaming
with client.messages.stream(model="claude-opus-5-5", max_tokens=1024, messages=[{"role": "user", "content": "Tell me a story."}]) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)
```

**curl**

```bash
curl https://api.claudech.com/v1/messages \
  -H "x-api-key: $CLAUDECH_API_KEY" \
  -H "anthropic-version: 2026-11-08" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-opus-5-5",
    "max_tokens": 1024,
    "messages": [{"role": "user", "content": "Hello, Claudech!"}]
  }'
```

Tool use (`tools` / `tool_use` / `tool_result` blocks), `system` prompts, image blocks and `stop_sequences` are all translated. Reasoning models return `thinking` content blocks when `thinking: { type: "enabled" }` is set. The usage object carries the standard `input_tokens` / `output_tokens` fields plus `claud_tokens_debited` and `claud_cost_usd`.

To run **Claude Code** against Claudech, set two environment variables and start it as normal:

```bash
export ANTHROPIC_BASE_URL=https://api.claudech.com
export ANTHROPIC_AUTH_TOKEN=$CLAUDECH_API_KEY   # or ANTHROPIC_API_KEY
export ANTHROPIC_MODEL=claude-opus-5-5              # optional: default model
claude
```

See [Integrations](https://claudech.com/docs/integrations) for a step-by-step guide to each coding assistant, chat app and framework.

## Frameworks

**Vercel AI SDK**

```typescript
// npm install ai @ai-sdk/openai-compatible
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
import { generateText, streamText } from 'ai';

const claudech = createOpenAICompatible({
  name: 'claudech',
  apiKey: process.env.CLAUDECH_API_KEY!,
  baseURL: 'https://api.claudech.com/v1',
});

const { text } = await generateText({
  model: claudech('claude-opus-5-5'),
  prompt: 'Summarise the plot of Hamlet in one paragraph.',
});

// or stream in a route handler
const result = streamText({ model: claudech('claude-opus-5-5'), prompt: 'Hello!' });
return result.toTextStreamResponse();
```

**LangChain (Python)**

```python
# pip install langchain-openai
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model="claude-opus-5-5",
    api_key=os.environ["CLAUDECH_API_KEY"],
    base_url="https://api.claudech.com/v1",
    temperature=0.3,
)
print(llm.invoke("Give me three names for a bakery.").content)
```

**LangChain.js**

```typescript
// npm install @langchain/openai
import { ChatOpenAI } from '@langchain/openai';

const llm = new ChatOpenAI({
  model: 'claude-opus-5-5',
  apiKey: process.env.CLAUDECH_API_KEY,
  configuration: { baseURL: 'https://api.claudech.com/v1' },
});
const res = await llm.invoke('Give me three names for a bakery.');
console.log(res.content);
```

**LlamaIndex**

```python
# pip install llama-index-llms-openai-like
from llama_index.llms.openai_like import OpenAILike

llm = OpenAILike(
    model="claude-opus-5-5",
    api_base="https://api.claudech.com/v1",
    api_key=os.environ["CLAUDECH_API_KEY"],
    is_chat_model=True,
    is_function_calling_model=True,
    context_window=1_000_000,
)
print(llm.complete("Give me three names for a bakery."))
```

## Plain HTTP

Any HTTP client works. The essentials:

```http
POST /v1/chat/completions HTTP/1.1
Host: api.claudech.com
Authorization: Bearer sk-...
Content-Type: application/json

{"model":"claude-opus-5-5","messages":[{"role":"user","content":"Hello"}]}
```

- Send JSON with `Content-Type: application/json`; bodies up to 2 MB.
- For streaming, read the body incrementally and split on blank lines; each event is `data: <json>` and the stream ends with `data: [DONE]`.
- Retry `429`/`5xx` with back-off and honour `retry-after`. See [Errors](https://claudech.com/docs/errors).

## Compatibility notes

Claudech implements the Chat Completions surface faithfully. Differences to be aware of:

| Area | Behaviour |
| --- | --- |
| `n` | Only `1` is supported. |
| `logprobs` | Accepted; always returns `null`. |
| `response_format.json_schema` | Treated as `json_object`; validate the output yourself. |
| `developer` role | Accepted and mapped to `system`. |
| `max_completion_tokens` | Supported; takes precedence over `max_tokens`. |
| `reasoning_effort` / `thinking` | Supported on reasoning models; see [Reasoning controls](https://claudech.com/docs/tools#reasoning-controls). |
| `usage` | Includes `claud_tokens_debited` and `claud_cost_usd`; streams add a final `claud` billing event. |
| Other endpoints | Only `/v1/chat/completions` and `/v1/models` follow the OpenAI shape. Embeddings, images, audio and files are not offered. |

Unknown top-level parameters are ignored rather than rejected, so libraries that send extra fields keep working.

---

Source: https://claudech.com/docs/sdks
