How to Structure Prompts Using Anthropic Messages API vs Text Completions API

The Messages API structures prompts as an array of role-based messages with a separate system field, while the legacy Text Completions API accepts only a single raw prompt string without native system prompt support.

The anthropics/prompt-eng-interactive-tutorial repository provides the definitive reference for prompt engineering with Claude. Understanding how to structure prompts using Anthropic Messages API vs Text Completions API is critical for building modern AI applications, as the Messages API represents Anthropic's current standard while the Text Completions API remains available as a legacy endpoint.

API Architecture Comparison

The fundamental difference lies in how each endpoint processes input and maintains context.

Feature Text Completions API (Legacy) Messages API (Current)
Endpoint POST /v1/complete POST /v1/messages
Payload Structure Single prompt string Array of message objects with role and content
System Prompt Not supported; must embed instructions in the prompt string Separate system field outside the message array
Conversation Support One-shot only Native multi-turn with alternating roles
Required Fields model, prompt, max_tokens_to_sample model, messages, max_tokens
Token Counting System instructions consume prompt tokens System prompt does not count toward message token limits

According to the source code in Anthropic 1P/01_Basic_Prompt_Structure.ipynb, the Messages API is explicitly preferred and used exclusively throughout the tutorial lessons.

Prompt Structure Examples

Text Completions API Format

The legacy API expects a raw string where you must manually format any system instructions or conversation history:

{
  "model": "claude-3-haiku-20240307",
  "prompt": "Human: Explain quantum entanglement in simple terms.\n\nAssistant:",
  "max_tokens_to_sample": 200,
  "temperature": 0.0
}

Messages API Format

The current API uses structured objects with clear role separation:

{
  "model": "claude-3-haiku-20240307",
  "system": "You are a friendly tutor who explains scientific concepts simply.",
  "messages": [
    {"role": "user", "content": "Explain quantum entanglement in simple terms."}
  ],
  "max_tokens": 200,
  "temperature": 0.0
}

The system field provides high-level guidance without being part of the message list, and the messages array defines the conversation flow. The first message must use the "user" role, and roles must alternate between user and assistant.

Implementing Both APIs in Python

The tutorial provides concrete implementations in Anthropic 1P/01_Basic_Prompt_Structure.ipynb demonstrating both approaches using the Anthropic Python SDK.

Text Completions Implementation

import anthropic

client = anthropic.Anthropic(api_key=API_KEY)

def complete_text(prompt: str):
    resp = client.completions.create(
        model=MODEL_NAME,
        prompt=prompt,
        max_tokens_to_sample=200,
        temperature=0.0,
    )
    return resp.completion

# Example usage

print(complete_text("Write a haiku about autumn."))

The client.completions.create method corresponds to the legacy POST /v1/complete endpoint.

Messages API Implementation

import anthropic

client = anthropic.Anthropic(api_key=API_KEY)

def chat(messages, system_prompt=""):
    resp = client.messages.create(
        model=MODEL_NAME,
        system=system_prompt,
        messages=messages,
        max_tokens=200,
        temperature=0.0,
    )
    # resp.content is a list of content blocks

    return resp.content[0].text

# Example 1: Simple user query

print(chat([{"role": "user", "content": "Explain the difference between cats and dogs."}]))

# Example 2: Using system prompt

system = "You are a witty poet who always answers in rhymed couplets."
messages = [{"role": "user", "content": "Describe the sunrise over the ocean."}]
print(chat(messages, system_prompt=system))

The client.messages.create method implements the current POST /v1/messages endpoint and supports the system parameter and structured message arrays.

Critical Implementation Details

When migrating from Text Completions to Messages API, several structural constraints apply:

  • Role Alternation: The API enforces strict alternation between "user" and "assistant" roles. Two consecutive user messages will trigger a validation error.
  • System Prompt Placement: The system field exists at the top level of the request object, not within the messages array. This separation ensures system instructions don't interfere with conversation flow.
  • Token Efficiency: System prompts do not count toward the message token limit, allowing more extensive instructions without consuming conversation context window.
  • Response Structure: Messages API returns content as a list of content blocks, requiring access via resp.content[0].text, whereas Text Completions returns a simple completion string.

Common Pitfalls

Issue Symptom Solution
Missing role/content fields API validation error: "messages must contain role and content" Ensure every message object includes both "role" and "content" keys.
Consecutive user roles API error: "roles must alternate between user and assistant" Insert an "assistant" placeholder message or ensure proper turn-taking in conversation history.
Embedding system in messages System instructions treated as user input, potentially ignored or misinterpreted Move system instructions to the dedicated system parameter at the request top level.
Accessing response incorrectly AttributeError when accessing resp.completion on Messages API response Use resp.content[0].text for Messages API; reserve resp.completion for Text Completions only.

Summary

  • Text Completions API accepts a single raw prompt string without native system prompt support, suitable only for simple one-shot text generation.
  • Messages API uses a structured array of role-based messages with a separate system field, enabling multi-turn conversations, persistent instructions, and better context management.
  • The Messages API is the preferred and future-proof endpoint, used exclusively in the anthropics/prompt-eng-interactive-tutorial notebooks.
  • When migrating, enforce strict role alternation, place system prompts in the dedicated field, and adjust response parsing from completion to content[0].text.

Frequently Asked Questions

Can I still use the Text Completions API with new Claude models?

Yes, the Text Completions API remains available for legacy compatibility, but Anthropic recommends using the Messages API for all new development. The Messages API receives new features first, including tool use, vision capabilities, and improved system prompt handling.

How do I convert existing Text Completions prompts to the Messages format?

Extract any system-level instructions from your prompt string and move them to the system parameter. Convert the remaining user input into a message object with "role": "user" and "content": "your prompt text". If your original prompt included simulated conversation history, split it into alternating "user" and "assistant" message objects.

Does the system prompt count toward the token limit in the Messages API?

No, the system prompt does not count toward the message token limit. This separation allows you to provide extensive instructions, guidelines, or context documents in the system field without consuming the conversation context window reserved for the actual dialogue between user and assistant.

What happens if I send two consecutive user messages without an assistant response?

The API will return a validation error stating that roles must alternate between user and assistant. The Messages API enforces strict conversation structure requiring turns to alternate. To fix this, either insert an assistant placeholder message or restructure your conversation history to ensure proper alternation.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →