Anthropic Claude API — Getting Started

Sanjeev SharmaSanjeev Sharma
7 min read

Advertisement

Introduction

The Anthropic Claude API provides programmatic access to Claude's capabilities for building AI applications. Unlike the consumer web interface, the API requires authentication, rate management, and careful cost control. This guide walks through everything needed to get started with the Claude API, from setup to production deployment.

Prerequisites and Setup

Get started with the Claude API in minutes:

  1. Create an account at console.anthropic.com
  2. Verify your email
  3. Add a payment method (required for API usage)
  4. Generate an API key from the Account Settings

The free trial includes a $5 credit for testing the API.

Installation

Install the official Python SDK:

pip install anthropic

Or use the API directly with any HTTP client:

# Using curl
curl https://api.anthropic.com/v1/messages \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-3-5-sonnet-20241022",
    "max_tokens": 1024,
    "messages": [{"role": "user", "content": "Hello"}]
  }'

Environment Setup

Secure your API key:

# Add to .env file (never commit this)
ANTHROPIC_API_KEY=sk-ant-...

# Load in your application
import os
from dotenv import load_dotenv

load_dotenv()
api_key = os.getenv("ANTHROPIC_API_KEY")

Or set as environment variable:

export ANTHROPIC_API_KEY="sk-ant-..."

Your First API Call

Simple example:

from anthropic import Anthropic

client = Anthropic()

message = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=1024,
    messages=[
        {"role": "user", "content": "Hello, Claude!"}
    ]
)

print(message.content[0].text)

Authentication Errors

Common issues and solutions:

from anthropic import Anthropic, AuthenticationError

try:
    client = Anthropic(api_key="bad-key")
    response = client.messages.create(
        model="claude-3-5-sonnet-20241022",
        max_tokens=100,
        messages=[{"role": "user", "content": "Hi"}]
    )
except AuthenticationError:
    print("Invalid API key. Check ANTHROPIC_API_KEY environment variable")

Request Parameters

Essential parameters for API calls:

response = client.messages.create(
    # Model selection
    model="claude-3-5-sonnet-20241022",  # Required

    # Token budget
    max_tokens=1024,  # Required, max output length

    # Conversation
    messages=[  # Required, conversation history
        {
            "role": "user",  # or "assistant"
            "content": "What's the weather?"
        }
    ],

    # Optional: Set model behavior
    system="You are a helpful assistant",

    # Optional: Control randomness
    temperature=0.7,  # 0 = deterministic, 1 = creative

    # Optional: Nucleus sampling alternative
    top_p=0.9,

    # Optional: Penalize repetition
    frequency_penalty=0,  # 0-1, reduces repeated tokens
    presence_penalty=0,   # 0-1, encourages new topics

    # Optional: Specific response format
    # (beta feature for structured output)
)

Managing Tokens and Costs

Monitor token usage:

response = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=1024,
    messages=[...]
)

# Check token usage
usage = response.usage
input_tokens = usage.input_tokens
output_tokens = usage.output_tokens

print(f"Input: {input_tokens}, Output: {output_tokens}")

# Estimate cost
input_cost = (input_tokens / 1000) * 0.003  # $0.003 per 1K
output_cost = (output_tokens / 1000) * 0.015  # $0.015 per 1K
total_cost = input_cost + output_cost

print(f"Estimated cost: ${total_cost:.4f}")

Managing Long Conversations

Keep conversations within context limits:

def manage_conversation_window(messages, max_messages=20):
    """Keep conversation size manageable"""
    if len(messages) > max_messages:
        # Keep system prompt, first context message, and recent messages
        system_msg = messages[0]
        context_msg = messages[1]
        recent_msgs = messages[-(max_messages-2):]
        return [system_msg, context_msg] + recent_msgs
    return messages

# Multi-turn conversation with window management
def chat_session():
    client = Anthropic()
    messages = []

    while True:
        user_input = input("You: ")

        messages.append({
            "role": "user",
            "content": user_input
        })

        # Manage conversation length
        messages = manage_conversation_window(messages)

        response = client.messages.create(
            model="claude-3-5-sonnet-20241022",
            max_tokens=1000,
            system="You are a helpful assistant",
            messages=messages
        )

        assistant_message = response.content[0].text
        messages.append({
            "role": "assistant",
            "content": assistant_message
        })

        print(f"Assistant: {assistant_message}\n")

Error Handling

Production applications need robust error handling:

import anthropic
import time

def call_claude_with_retry(
    messages,
    max_retries=3,
    backoff_factor=2
):
    """Call Claude with retry logic for transient errors"""
    client = anthropic.Anthropic()

    for attempt in range(max_retries):
        try:
            response = client.messages.create(
                model="claude-3-5-sonnet-20241022",
                max_tokens=1024,
                messages=messages
            )
            return response

        except anthropic.RateLimitError:
            if attempt < max_retries - 1:
                wait_time = backoff_factor ** attempt
                print(f"Rate limited. Waiting {wait_time}s...")
                time.sleep(wait_time)
            else:
                raise

        except anthropic.APIConnectionError as e:
            if attempt < max_retries - 1:
                wait_time = backoff_factor ** attempt
                print(f"Connection error. Retrying in {wait_time}s...")
                time.sleep(wait_time)
            else:
                raise

        except anthropic.APIStatusError as e:
            if e.status_code >= 500:  # Server error, retry
                if attempt < max_retries - 1:
                    wait_time = backoff_factor ** attempt
                    print(f"Server error ({e.status_code}). Retrying...")
                    time.sleep(wait_time)
                else:
                    raise
            else:  # Client error, don't retry
                raise

# Usage
messages = [{"role": "user", "content": "Hello"}]
response = call_claude_with_retry(messages)
print(response.content[0].text)

Vision Capabilities

Claude can analyze images:

import base64

def analyze_image(image_path):
    """Analyze an image using Claude's vision"""
    client = anthropic.Anthropic()

    # Read and encode image
    with open(image_path, "rb") as image_file:
        image_data = base64.standard_b64encode(image_file.read()).decode("utf-8")

    # Determine media type
    media_type_map = {
        ".jpg": "image/jpeg",
        ".jpeg": "image/jpeg",
        ".png": "image/png",
        ".gif": "image/gif",
        ".webp": "image/webp"
    }

    ext = image_path[image_path.rfind("."):]
    media_type = media_type_map.get(ext, "image/jpeg")

    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": "Describe this image in detail"
                    }
                ],
            }
        ],
    )

    return response.content[0].text

# Usage
description = analyze_image("screenshot.png")
print(description)

Tool Use (Function Calling)

Define functions Claude can call:

def use_claude_with_tools():
    """Claude with function calling capability"""
    client = anthropic.Anthropic()

    tools = [
        {
            "name": "calculator",
            "description": "Perform mathematical calculations",
            "input_schema": {
                "type": "object",
                "properties": {
                    "expression": {
                        "type": "string",
                        "description": "Mathematical expression to evaluate"
                    }
                },
                "required": ["expression"]
            }
        }
    ]

    messages = [
        {"role": "user", "content": "What is 15 * 23?"}
    ]

    response = client.messages.create(
        model="claude-3-5-sonnet-20241022",
        max_tokens=1024,
        tools=tools,
        messages=messages
    )

    # Handle tool calls
    for block in response.content:
        if block.type == "tool_use":
            tool_name = block.name
            tool_input = block.input

            if tool_name == "calculator":
                result = eval(tool_input["expression"])
                print(f"Calculation: {tool_input['expression']} = {result}")

    return response

Batch Processing

Process multiple requests efficiently:

import json

def batch_api_calls(requests, batch_size=10):
    """Process requests in batches to optimize costs"""
    client = anthropic.Anthropic()
    results = []

    for i in range(0, len(requests), batch_size):
        batch = requests[i:i+batch_size]

        for request in batch:
            response = client.messages.create(
                model="claude-3-5-sonnet-20241022",
                max_tokens=request.get("max_tokens", 1024),
                messages=request["messages"]
            )
            results.append({
                "id": request.get("id"),
                "response": response.content[0].text,
                "tokens": response.usage.output_tokens
            })

    return results

# Usage
requests = [
    {"id": 1, "messages": [{"role": "user", "content": "Summarize Python"}]},
    {"id": 2, "messages": [{"role": "user", "content": "Explain JavaScript"}]},
]

results = batch_api_calls(requests)

Rate Limiting

Handle rate limits gracefully:

from anthropic import RateLimitError
import time

def claude_with_rate_limiting(messages):
    """Call Claude with rate limit handling"""
    client = anthropic.Anthropic()
    max_retries = 5
    base_wait = 1

    for attempt in range(max_retries):
        try:
            return client.messages.create(
                model="claude-3-5-sonnet-20241022",
                max_tokens=1024,
                messages=messages
            )

        except RateLimitError:
            if attempt == max_retries - 1:
                raise

            wait_time = base_wait * (2 ** attempt)
            print(f"Rate limited. Waiting {wait_time}s before retry {attempt + 2}/{max_retries}")
            time.sleep(wait_time)

Monitoring and Logging

For production applications:

import logging
from datetime import datetime

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def log_api_call(model, input_tokens, output_tokens, response_time):
    """Log API usage for monitoring"""
    logger.info(
        f"API Call | Model: {model} | "
        f"Input: {input_tokens} | Output: {output_tokens} | "
        f"Time: {response_time:.2f}s"
    )

import time

def claude_with_logging(messages):
    """Call Claude with comprehensive logging"""
    start = time.time()
    client = anthropic.Anthropic()

    try:
        response = client.messages.create(
            model="claude-3-5-sonnet-20241022",
            max_tokens=1024,
            messages=messages
        )

        duration = time.time() - start
        log_api_call(
            "claude-3-5-sonnet",
            response.usage.input_tokens,
            response.usage.output_tokens,
            duration
        )

        return response

    except Exception as e:
        logger.error(f"API error: {str(e)}")
        raise

Conclusion

The Claude API is straightforward to set up and use but requires careful attention to error handling, rate limiting, and cost management in production. Start with the examples here and scale up your implementation as needed.

FAQ

Q: How do I keep my API key secure? A: Always use environment variables, never commit keys to source control, rotate keys regularly, and consider using a secrets manager for production.

Q: What's the difference between API and web interface? A: API is for programmatic access; web interface is for interactive use. Use API for applications, web interface for exploration.

Q: How much will the API cost? A: Pricing depends on usage. Monitor token counts and estimate costs before deployment to avoid surprises.

Advertisement

Sanjeev Sharma

Written by

Sanjeev Sharma

Full Stack Engineer · E-mopro