
Using the Anthropic SDK with AICredits (Python & TypeScript)
Use the official Anthropic Python and TypeScript SDKs with AICredits. One environment variable routes all requests through your INR wallet — no OpenAI SDK required.
Author
AICredits Team
Published
3 May 2026
Reading time
7 min read
Why use the Anthropic SDK instead of the OpenAI SDK?
AICredits has always supported the OpenAI-compatible API format (/v1/chat/completions). You could already use Claude models through the OpenAI SDK by prefixing the model name with anthropic/.
But the official Anthropic SDK is different. It uses Anthropic's native Messages API format, which gives you access to things the OpenAI-compatible layer doesn't expose cleanly:
- Prompt caching with
cache_controlheaders (up to 90% cost reduction on repeated context) - Extended thinking for claude-3-7 and newer models
- Native tool use with Anthropic's tool format
systemas a content block array (needed for cached system prompts)
As of May 2026, AICredits natively supports the Anthropic Messages API (POST /v1/messages). This means you can use the official anthropic SDK — in Python or TypeScript — with a single environment variable pointing to AICredits.
Setup: two environment variables
export ANTHROPIC_BASE_URL=https://api.aicredits.in
export ANTHROPIC_API_KEY=sk-your-aicredits-keyThat's it. The SDK reads these automatically. You don't change any code — just the environment.
Or set them inline in code (useful in notebooks or scripts):
import anthropic
client = anthropic.Anthropic(
base_url="https://api.aicredits.in",
api_key="sk-your-aicredits-key",
)import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
baseURL: "https://api.aicredits.in",
apiKey: "sk-your-aicredits-key",
});Basic message — Python
import anthropic
client = anthropic.Anthropic(
base_url="https://api.aicredits.in",
api_key="sk-your-aicredits-key",
)
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[
{"role": "user", "content": "Explain the CAP theorem in two paragraphs."}
],
)
print(message.content[0].text)
# Usage: message.usage.input_tokens, message.usage.output_tokensBasic message — TypeScript
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
baseURL: "https://api.aicredits.in",
apiKey: "sk-your-aicredits-key",
});
const message = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
messages: [
{ role: "user", content: "Explain the CAP theorem in two paragraphs." }
],
});
console.log(message.content[0].text);Streaming
Streaming works exactly as documented by Anthropic:
with client.messages.stream(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[{"role": "user", "content": "Write a haiku about distributed systems."}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)const stream = await client.messages.stream({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
messages: [{ role: "user", content: "Write a haiku about distributed systems." }],
});
for await (const chunk of stream) {
if (
chunk.type === "content_block_delta" &&
chunk.delta.type === "text_delta"
) {
process.stdout.write(chunk.delta.text);
}
}System prompts
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=512,
system="You are a terse senior engineer. Answer in under 3 sentences.",
messages=[
{"role": "user", "content": "What is a goroutine?"}
],
)Prompt caching (save up to 90% on repeated context)
Prompt caching is one of the most powerful reasons to use the Anthropic SDK directly. If you have a large system prompt or document that you send with every request, you can cache it on Anthropic's infrastructure and pay only 10% of the input token cost on cache hits.
import anthropic
client = anthropic.Anthropic(
base_url="https://api.aicredits.in",
api_key="sk-your-aicredits-key",
)
LARGE_CONTEXT = """
[Your 10,000-word document, codebase context, or system instructions here]
""".strip()
# First request: cache the large context (costs 1.25x for the write)
# Subsequent requests: pay only 10% for the cached portion
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
system=[
{
"type": "text",
"text": LARGE_CONTEXT,
"cache_control": {"type": "ephemeral"}, # cache this block
}
],
messages=[
{"role": "user", "content": "Summarise the key decisions in this document."}
],
)
print(f"Cache write tokens: {message.usage.cache_creation_input_tokens}")
print(f"Cache read tokens: {message.usage.cache_read_input_tokens}")
print(f"Regular tokens: {message.usage.input_tokens}")On a 10,000-token system prompt, each cached request saves roughly ₹230 compared to sending the full context each time (at Sonnet pricing with AICredits markup).
Tool use
tools = [
{
"name": "get_stock_price",
"description": "Get the current stock price for a ticker symbol.",
"input_schema": {
"type": "object",
"properties": {
"ticker": {"type": "string", "description": "e.g. RELIANCE, TCS, INFY"}
},
"required": ["ticker"],
},
}
]
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=512,
tools=tools,
messages=[{"role": "user", "content": "What is the current price of TCS?"}],
)
# Check if Claude wants to call a tool
if message.stop_reason == "tool_use":
tool_call = next(b for b in message.content if b.type == "tool_use")
print(f"Tool: {tool_call.name}, Input: {tool_call.input}")
# → Tool: get_stock_price, Input: {'ticker': 'TCS'}Multi-turn conversation
messages = []
def chat(user_message: str) -> str:
messages.append({"role": "user", "content": user_message})
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=messages,
)
assistant_message = response.content[0].text
messages.append({"role": "assistant", "content": assistant_message})
return assistant_message
print(chat("I'm building a FastAPI app. What's the best way to handle async database calls?"))
print(chat("How does that compare to using synchronous SQLAlchemy?"))
print(chat("Show me a minimal working example."))Using environment variables (recommended for production)
In production, never hardcode credentials. Set the variables in your environment and let the SDK pick them up:
# .env
ANTHROPIC_BASE_URL=https://api.aicredits.in
ANTHROPIC_API_KEY=sk-your-aicredits-keyfrom dotenv import load_dotenv
import anthropic
load_dotenv()
# SDK automatically reads ANTHROPIC_BASE_URL and ANTHROPIC_API_KEY
client = anthropic.Anthropic()import "dotenv/config";
import Anthropic from "@anthropic-ai/sdk";
// SDK reads ANTHROPIC_BASE_URL and ANTHROPIC_API_KEY from env
const client = new Anthropic();Supported models
| Model | Input (₹/M tokens) | Output (₹/M tokens) | Best for |
|---|---|---|---|
| claude-opus-4-5 | ₹1,370 | ₹6,850 | Complex reasoning, research |
| claude-sonnet-4-20250514 | ₹274 | ₹1,370 | Everyday tasks, code, writing |
| claude-haiku-3-5 | ₹96 | ₹480 | Fast, lightweight tasks |
Prices shown include forex conversion and platform markup at current rates. Check aicredits.in/models for live pricing.
What doesn't change
Switching from Anthropic direct to AICredits via the SDK changes nothing in your code except the base URL and API key. Every SDK feature works:
- All model versions ✓
- Streaming ✓
- Tool use / function calling ✓
- Vision (image inputs) ✓
- Prompt caching ✓
- Batch API ✓
- Extended thinking ✓
The response objects, error types, and retry behaviour are identical — AICredits speaks the Anthropic API natively.
Migration from OpenAI SDK to Anthropic SDK
If you were using the OpenAI SDK to call Claude via AICredits, migrating to the Anthropic SDK is straightforward:
# Before: OpenAI SDK with AICredits
from openai import OpenAI
client = OpenAI(base_url="https://api.aicredits.in/v1", api_key="sk-...")
response = client.chat.completions.create(
model="anthropic/claude-sonnet-4-20250514",
messages=[{"role": "user", "content": "Hello"}],
)
text = response.choices[0].message.content
# After: Anthropic SDK with AICredits
import anthropic
client = anthropic.Anthropic(base_url="https://api.aicredits.in", api_key="sk-...")
response = client.messages.create(
model="claude-sonnet-4-20250514", # no "anthropic/" prefix needed
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}],
)
text = response.content[0].textThe main differences: messages.create instead of chat.completions.create, max_tokens is required, and the response is message.content[0].text instead of response.choices[0].message.content.
Related Articles
Continue in Docs
Need implementation commands and endpoint details? Go to quickstart or API reference.