Anthropic Claude API — Getting Started Guide 2026
Advertisement
Introduction
Why This Matters
The Anthropic Claude API provides programmatic access to Claude 3.5 Sonnet, Haiku, and Opus — enabling you to build AI features into your applications without managing model infrastructure. Understanding the API's specific design choices — the system parameter structure, content blocks, tool use flow, and prompt caching — is essential to build correct and cost-efficient applications from day one.
Account Setup
- Go to console.anthropic.com and create an account
- Navigate to API Keys and generate a key
- New accounts receive free trial credits (~$5 USD)
- Set up billing for production usage
# Store securely — never commit to source control
export ANTHROPIC_API_KEY="sk-ant-api03-..."
# Install the Python SDK
pip install anthropic
# Install the Node.js SDK
npm install @anthropic-ai/sdkFirst API Call — Python
import anthropic
client = anthropic.Anthropic()
# Reads ANTHROPIC_API_KEY from environment automatically
message = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
system="You are a concise technical assistant. Answer in 2-3 sentences.",
messages=[
{
"role": "user",
"content": "What is the difference between a process and a thread?",
}
],
)
print(message.content[0].text)
print(f"\nInput tokens: {message.usage.input_tokens}")
print(f"Output tokens: {message.usage.output_tokens}")Key structural differences from the OpenAI API:
systemis a top-level parameter, not a message withrole: "system"contentreturns a list of content blocks — access text with.content[0].textstop_reasoninstead offinish_reason- Usage is in
message.usage.input_tokens/message.usage.output_tokens
First API Call — JavaScript/TypeScript
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic();
async function askClaude(question: string): Promise<string> {
const message = await client.messages.create({
model: 'claude-3-5-sonnet-20241022',
max_tokens: 1024,
system: 'You are a helpful coding assistant.',
messages: [{ role: 'user', content: question }],
});
const block = message.content[0];
if (block.type !== 'text') throw new Error('Unexpected content type');
return block.text;
}
const answer = await askClaude('Explain async/await in JavaScript.');
console.log(answer);Multi-Turn Conversations
import anthropic
client = anthropic.Anthropic()
messages = []
def send(user_message: str, system: str = "") -> str:
messages.append({"role": "user", "content": user_message})
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=2048,
system=system,
messages=messages,
)
reply = response.content[0].text
messages.append({"role": "assistant", "content": reply})
return reply
system = "You are a Python code reviewer. Be specific and provide corrected code."
print(send("Review this login function: def login(u, p): return db.get(u).password == p", system))
print(send("Now add JWT token generation to the fixed version."))
print(send("What's the best way to test this with pytest?"))Streaming
import anthropic
client = anthropic.Anthropic()
def stream_response(prompt: str) -> str:
full_text = ""
with client.messages.stream(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
messages=[{"role": "user", "content": prompt}],
) as stream:
for text_chunk in stream.text_stream:
print(text_chunk, end="", flush=True)
full_text += text_chunk
print() # New line after streaming completes
return full_text
stream_response("Explain how TCP/IP handshake works step by step.")Vision — Analyzing Images
import anthropic
import base64
client = anthropic.Anthropic()
def analyze_image(image_path: str, question: str) -> str:
with open(image_path, "rb") as f:
image_data = base64.standard_b64encode(f.read()).decode("utf-8")
ext = image_path.rsplit(".", 1)[-1].lower()
media_types = {"png": "image/png", "jpg": "image/jpeg", "jpeg": "image/jpeg", "gif": "image/gif"}
media_type = media_types.get(ext, "image/png")
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
messages=[
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": media_type,
"data": image_data,
},
},
{"type": "text", "text": question},
],
}
],
)
return response.content[0].text
result = analyze_image(
"architecture_diagram.png",
"Describe this system architecture and identify any potential bottlenecks."
)Prompt Caching
Prompt caching reduces costs by caching frequently reused prompt prefixes (system prompts, document context). Cached tokens cost 90% less on subsequent requests.
import anthropic
client = anthropic.Anthropic()
LARGE_SYSTEM_PROMPT = """
You are a code review assistant for a large Python codebase.
Coding standards: [... very long standards document ...]
Security requirements: [... detailed security policies ...]
""" # Imagine this is 5,000+ tokens
def review_with_cache(code: str) -> str:
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
system=[
{
"type": "text",
"text": LARGE_SYSTEM_PROMPT,
"cache_control": {"type": "ephemeral"}, # Cache this prefix
}
],
messages=[{"role": "user", "content": f"Review:\n\n{code}"}],
)
# Check cache performance
usage = response.usage
print(f"Cache read tokens: {usage.cache_read_input_tokens}")
print(f"Cache write tokens: {usage.cache_creation_input_tokens}")
return response.content[0].textCache hits on a 5,000-token system prompt reduce cost from 0.0015 per review — 10x cheaper after the first call.
Common Mistakes
- Using
role: "system"as a message role — Claude's API puts system in a top-level parameter, not in messages - Not accessing
.content[0].text— returning the raw content list instead of the text - Ignoring
stop_reason— not checking for"max_tokens"means truncated responses go undetected - Sending images as URLs without checking if the model can reach them — use base64 encoding for reliability
- Skipping prompt caching on applications with large repeated system prompts — leaves 90% cost reduction on the table
Best Practices
- Always log
input_tokensandoutput_tokensfrommessage.usagefor cost tracking - Use Haiku for real-time, high-volume tasks; Sonnet for most production tasks; Opus for maximum reasoning
- Enable prompt caching for any system prompt longer than 1,024 tokens to reduce repeated-request costs
- Set
max_tokenson every request — unexpected long responses inflate cost without limit - Handle
stop_reason == "max_tokens"— detect and handle truncated responses before using them
Key Takeaways
- The
systemparameter is top-level in Claude's API — not arole: "system"message like in OpenAI's API - Response text is in
message.content[0].text— content is a list of typed blocks - Streaming uses
client.messages.stream()context manager and yields via.text_stream - Vision requests pass images as base64-encoded content blocks with
type: "image"andsource.type: "base64" - Prompt caching reduces cost of cached tokens by 90% — essential for applications with large repeated system prompts
- All three model tiers (Sonnet, Haiku, Opus) share the 200K-token context window
stop_reason == "max_tokens"indicates a truncated response — always check this in production- New API accounts receive free trial credits; billing setup is required for production-scale usage
Advertisement