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

> Learn how to structure prompts with Anthropic Messages API vs Text Completions API. Discover the differences in prompt formatting and system message integration for better AI interactions.

- Repository: [Anthropic/prompt-eng-interactive-tutorial](https://github.com/anthropics/prompt-eng-interactive-tutorial)
- Tags: deep-dive
- Published: 2026-03-09

---

**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:

```json
{
  "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:

```json
{
  "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

```python
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

```python
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.