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
systemfield exists at the top level of the request object, not within themessagesarray. 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
contentas a list of content blocks, requiring access viaresp.content[0].text, whereas Text Completions returns a simplecompletionstring.
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
promptstring 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
systemfield, 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-tutorialnotebooks. - When migrating, enforce strict role alternation, place system prompts in the dedicated field, and adjust response parsing from
completiontocontent[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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →