3Accessing Claude with the API

Multi-Turn conversations

4 min read701 words

You ask Claude "What is quantum computing?" and get a crisp paragraph back. Satisfied, you send a follow-up: "Write another sentence." Claude responds with something completely unrelated — as if you walked up to a stranger on the street and said "write another sentence" with no preamble. From Claude's perspective, that's exactly what you did.

Claude is stateless

The Anthropic API keeps no memory of previous requests. Every call to client.messages.create() is a fresh, independent conversation. There is no session object. There is no conversationId that silently accumulates state on Anthropic's side. Whatever context Claude has, you put there, in this request.

This is a deliberate design — stateless APIs are easier to scale, reason about, retry, and reason about in systems like yours and ours. But it does mean that the first thing you'll build on top of the raw API is a small amount of conversation state.

The pattern: replay the full history every turn

The contract is simple. If you want Claude to remember the last five messages, you send all five messages in the messages list on every call. The list grows by two each turn — the user message you just added, and the assistant message Claude returned.

Per turn, the loop looks like:

  1. Append the new user message to your messages list.
  2. Call client.messages.create() with the entire list.
  3. Append the assistant's response to the same list.
  4. Repeat.

Skip step 3 and the assistant loses its own previous answer from context — Claude will keep answering your questions but won't be able to reference anything it just said.

Three helper functions you'll reuse all course

Rather than repeat the same dict-building boilerplate everywhere, wrap it in three small helpers. These exact functions are used throughout the rest of the course — get comfortable with them.

def add_user_message(messages, text):
    user_message = {"role": "user", "content": text}
    messages.append(user_message)

def add_assistant_message(messages, text):
    assistant_message = {"role": "assistant", "content": text}
    messages.append(assistant_message)

def chat(messages):
    message = client.messages.create(
        model=model,
        max_tokens=1000,
        messages=messages,
    )
    return message.content[0].text

Three things worth noting:

  • add_user_message and add_assistant_message mutate the list in place. The functions don't return anything — they push onto the list you pass in. This keeps call sites short and makes the shared state obvious.
  • chat() takes the full messages list as its only argument and returns the generated text. It doesn't append the response itself — that's the caller's job, because in a moment you'll want to pass extra parameters (system prompts, temperature, tools) without rewriting the helper.
  • The function returns .content[0].text — the same text extraction pattern you learned in the previous lesson.

Putting it together

A two-turn conversation looks like this:

messages = []

add_user_message(messages, "What is quantum computing?")
answer = chat(messages)
add_assistant_message(messages, answer)

add_user_message(messages, "Write another sentence.")
answer = chat(messages)
add_assistant_message(messages, answer)

print(answer)

Now the second call includes the full four-message history, and "write another sentence" resolves against quantum computing — because Claude can see what it just said.

This pattern is the foundation of every chat application you'll build on Claude. Tool use, system prompts, streaming, agents — they all sit on top of this same "append-and-replay" loop. The helpers above are the scaffolding for the rest of the course.

Key Takeaways

  • 1Claude is stateless: the Anthropic API holds no memory of previous calls, so every request must carry the full conversation history in messages.
  • 2Multi-turn conversations are built by maintaining a message list on your side, appending user and assistant messages after every turn, and replaying the whole list on each call.
  • 3Three helper functions — add_user_message, add_assistant_message, and chat — provide the reusable scaffolding for every chat you build in this course.
  • 4Forgetting to append the assistant response breaks context: Claude can still answer but loses any reference to what it just said.
  • 5This append-and-replay pattern is the foundation for everything that comes next, including system prompts, tool use, and agent loops.