Artificial IntelligenceAnthropicClaude API

Your First Claude API Call: Python and JavaScript Quickstart

TT
TopicTrick
Your First Claude API Call: Python and JavaScript Quickstart

You have your API key. Your SDK is installed. Now it is time to actually talk to Claude from code.

This is the step where everything becomes real. You go from reading about Claude's capabilities to experiencing them directly through the API — the same interface that powers production applications used by millions of people.

This guide gives you complete, working code in both Python and JavaScript for your first Claude API call, explains every line so you understand what it does, and introduces the patterns that will underpin everything you build going forward.


What We Are Building

We will start with an absolute minimum working example — just enough to send a message and get a response. Then we will layer in additional capabilities:

  • A basic single-turn message
  • Reading and understanding the response object
  • Adding a system prompt to shape Claude's behaviour
  • A multi-turn conversation
  • Streaming responses for real-time output
  • Error handling

By the end of this post, you will have a solid foundation for building any Claude-powered application.


The Minimum Working Example

Python

python
1import anthropic 2 3client = anthropic.Anthropic() 4# The client automatically reads ANTHROPIC_API_KEY from your environment 5 6message = client.messages.create( 7 model="claude-sonnet-4-6", 8 max_tokens=1024, 9 messages=[ 10 {"role": "user", "content": "What is the capital of France?"} 11 ] 12) 13 14print(message.content[0].text)

JavaScript / TypeScript

javascript
1import Anthropic from "@anthropic-ai/sdk"; 2 3const client = new Anthropic(); 4// The client automatically reads ANTHROPIC_API_KEY from your environment 5 6const message = await client.messages.create({ 7 model: "claude-sonnet-4-6", 8 max_tokens: 1024, 9 messages: [{ role: "user", content: "What is the capital of France?" }], 10}); 11 12console.log(message.content[0].text);

Run either of these and you will see Claude respond: The capital of France is Paris.

That is it — that is your first Claude API call. Now let us understand every part of it.


Breaking Down the Request

The model Parameter

This tells the API which Claude model to use. We are using claude-sonnet-4-6 — a strong, cost-effective choice for most tasks. Swap in claude-opus-4-6 for more complex reasoning, or claude-haiku-4-5 for maximum speed and minimum cost.

The max_tokens Parameter

This sets the maximum number of tokens Claude can generate in its response. One token is roughly three to four characters in English. Setting this to 1024 allows responses of roughly 700–800 words — more than enough for most queries. If your use case requires very long responses, increase this value.

max_tokens is a Hard Limit

If Claude reaches the max_tokens limit before finishing its response, it will stop mid-sentence. The stop_reason in the response will be 'max_tokens' instead of 'end_turn'. For conversational use, 1024 is usually fine. For document generation or long-form writing, set it higher — Sonnet 4.6 supports up to 64,000 output tokens.

    The messages Array

    This is the core of every Claude API request. The messages array contains the conversation history as a sequence of objects, each with a role and content.

    Roles:

    • user: The human's turn — your question, instruction, or input
    • assistant: Claude's previous responses in a conversation

    Even for a single question, you pass it inside an array. This design means the same API structure handles both one-off queries and multi-turn conversations without any change in format.


    Understanding the Response Object

    The API returns a Message object with several important fields.

    Python — Exploring the Response

    python
    1message = client.messages.create( 2 model="claude-sonnet-4-6", 3 max_tokens=1024, 4 messages=[{"role": "user", "content": "Explain APIs in one sentence."}] 5) 6 7print(message.id) # Unique message ID (e.g. msg_01XFDUDYJgAACzvnptvVoYEL) 8print(message.model) # Which model was used 9print(message.stop_reason) # Why Claude stopped: 'end_turn' or 'max_tokens' 10print(message.usage.input_tokens) # Tokens in your request 11print(message.usage.output_tokens) # Tokens in Claude's response 12print(message.content[0].text) # The actual text response

    Key Response Fields

    • id: A unique identifier for this specific API call — useful for logging and debugging
    • model: The model that actually processed the request (may differ slightly from what you specified if you used an alias)
    • stop_reason: end_turn means Claude finished naturally; max_tokens means it hit the limit; tool_use means it wants to call a tool
    • usage.input_tokens: The number of tokens in your message and system prompt — this is what you pay for on input
    • usage.output_tokens: The number of tokens in Claude's response — what you pay for on output
    • content: An array of content blocks. For text responses, this is always a list with one item of type "text"

    Adding a System Prompt

    A system prompt is a set of instructions you give Claude before the conversation begins. It shapes Claude's persona, role, constraints, and behaviour throughout the entire conversation. It is the most powerful tool you have for customising how Claude responds.

    Python

    python
    1message = client.messages.create( 2 model="claude-sonnet-4-6", 3 max_tokens=1024, 4 system="You are a senior software engineer with 15 years of experience. " 5 "Give concise, practical answers. Prefer code examples over long explanations. " 6 "Always mention potential pitfalls and edge cases.", 7 messages=[ 8 {"role": "user", "content": "How should I handle API timeouts in Python?"} 9 ] 10) 11 12print(message.content[0].text)

    JavaScript

    javascript
    1const message = await client.messages.create({ 2 model: "claude-sonnet-4-6", 3 max_tokens: 1024, 4 system: 5 "You are a senior software engineer with 15 years of experience. " + 6 "Give concise, practical answers. Prefer code examples over long explanations. " + 7 "Always mention potential pitfalls and edge cases.", 8 messages: [ 9 { role: "user", content: "How should I handle API timeouts in Python?" }, 10 ], 11}); 12 13console.log(message.content[0].text);

    The system prompt is passed as a top-level string parameter — separate from the messages array. Claude treats it as authoritative instructions that override or supplement what the user asks.

    System Prompts are Your Most Powerful Tool

    A well-crafted system prompt transforms Claude from a general assistant into a specialised tool. A system prompt can establish Claude's persona, define its scope (what topics it will and will not address), set the response format, specify the audience, and provide background context that every conversation should know. We cover this in depth in the Prompt Engineering module.


      Multi-Turn Conversations

      To continue a conversation across multiple turns, you include the full message history in each API call. The API itself is stateless — it does not remember previous calls. You are responsible for maintaining the conversation history on your side and sending it with each request.

      Python

      python
      1conversation_history = [] 2 3# Turn 1 4conversation_history.append({ 5 "role": "user", 6 "content": "I want to learn Python. Where should I start?" 7}) 8 9response = client.messages.create( 10 model="claude-sonnet-4-6", 11 max_tokens=1024, 12 messages=conversation_history 13) 14 15# Add Claude's response to history 16conversation_history.append({ 17 "role": "assistant", 18 "content": response.content[0].text 19}) 20 21# Turn 2 — Claude remembers the conversation 22conversation_history.append({ 23 "role": "user", 24 "content": "How long will that take if I study two hours per day?" 25}) 26 27response2 = client.messages.create( 28 model="claude-sonnet-4-6", 29 max_tokens=1024, 30 messages=conversation_history 31) 32 33print(response2.content[0].text)

      This pattern — append user message, call API, append assistant response, repeat — is the foundation of every conversational AI application.


      Streaming Responses

      By default, the API waits until Claude has finished generating the entire response before returning it. For short responses this is fine. For longer responses, this means your user stares at a blank screen for several seconds.

      Streaming sends each piece of Claude's response as it is generated, so you can display text to the user word by word — exactly like how Claude.ai renders responses.

      Python Streaming

      python
      1with client.messages.stream( 2 model="claude-sonnet-4-6", 3 max_tokens=1024, 4 messages=[{"role": "user", "content": "Write a short paragraph about AI safety."}] 5) as stream: 6 for text in stream.text_stream: 7 print(text, end="", flush=True) 8 9print() # New line at the end

      JavaScript Streaming

      javascript
      1const stream = client.messages.stream({ 2 model: "claude-sonnet-4-6", 3 max_tokens: 1024, 4 messages: [ 5 { role: "user", content: "Write a short paragraph about AI safety." }, 6 ], 7}); 8 9for await (const chunk of stream) { 10 if ( 11 chunk.type === "content_block_delta" && 12 chunk.delta.type === "text_delta" 13 ) { 14 process.stdout.write(chunk.delta.text); 15 } 16}

      Error Handling

      A production-ready integration must handle errors gracefully. The Anthropic SDK throws specific error types that you can catch and handle appropriately.

      Python Error Handling

      python
      1import anthropic 2 3client = anthropic.Anthropic() 4 5try: 6 message = client.messages.create( 7 model="claude-sonnet-4-6", 8 max_tokens=1024, 9 messages=[{"role": "user", "content": "Hello"}] 10 ) 11 print(message.content[0].text) 12 13except anthropic.AuthenticationError: 14 print("Invalid API key. Check your ANTHROPIC_API_KEY environment variable.") 15 16except anthropic.RateLimitError: 17 print("Rate limit exceeded. Wait a moment before retrying.") 18 19except anthropic.APIStatusError as e: 20 print(f"API error {e.status_code}: {e.message}")

      Common Error Types

      • AuthenticationError (401): Your API key is missing, expired, or invalid
      • PermissionDeniedError (403): Your account does not have access to the requested model or feature
      • RateLimitError (429): You have exceeded your requests-per-minute or tokens-per-minute limit — implement exponential backoff retry logic
      • InternalServerError (500): A temporary Anthropic server issue — retry with backoff
      • APIConnectionError: Network issue between your server and Anthropic's API

      The SDK Has Built-In Retry Logic

      The official Anthropic SDKs automatically retry transient errors like 429 and 500 with exponential backoff by default. You can configure the number of retries and the backoff parameters. For most applications, the default retry behaviour is sufficient without writing custom retry logic yourself.


        Summary

        You have now made your first Claude API call — and more importantly, you understand what every part of the request and response means. The patterns in this post — the messages array, the system prompt, multi-turn history management, streaming, and error handling — appear in every Claude integration you will ever build.

        The next step is going deeper into the Messages API to understand all its parameters, how system prompts interact with conversation turns, and the full range of stop reasons and content types.

        In our next post, we cover the Messages API in depth: Understanding the Messages API: Roles, Turns, and System Prompts.


        This post is part of the Anthropic AI Tutorial Series. Don't forget to check out our previous post: How to Get Your Anthropic API Key and Set Up the Console.