Skip to main content
Lesson 9 of 12 · Async Requests & Advanced Patterns

Multi-Turn Context: Storage and Encryption

Lesson 9 of 12 Updated July 30, 2026 Advanced
On this page
  1. The Problem of Context Between Requests
  2. Method 1: store_messages and previous_response_id
  3. Method 2: use_encrypted_content
  4. Choosing Between the Two Methods
  5. Combining with the Hybrid Workflow
  6. Key Takeaways

The Problem of Context Between Requests

In a multi-turn conversation with tools, context volume grows quickly. Each tool call adds its results to the message thread, and the model’s internal reasoning must be preserved for consistency. Two mechanisms solve this problem: remote storage and client-side encryption.

Method 1: store_messages and previous_response_id

Remote storage delegates context management to xAI servers. You enable store_messages=True in your first request, then chain subsequent requests with previous_response_id:

# First request: enable storage
response = await client.chat.completions.create(
    model="grok-4.5",
    messages=[{"role": "user", "content": "Analyze this sales dataset"}],
    tools=my_tools,
    store_messages=True
)

response_id = response.id  # save the ID

# Next request: use stored context
response2 = await client.chat.completions.create(
    model="grok-4.5",
    messages=[{"role": "user", "content": "What are the top 3 selling products?"}],
    previous_response_id=response_id,
    store_messages=True
)

With this approach, you don’t need to resend the full message history. The xAI server keeps the context and attaches it automatically. This reduces request size and simplifies your code.

Advantages

  • Lighter requests (no need to resend full history)
  • Model internal reasoning is preserved automatically
  • No complex state management on the client side

Limitations

  • Messages are stored on xAI servers (privacy consideration)
  • The response_id must be kept between requests
  • Storage has a limited retention period

Method 2: use_encrypted_content

Client-side encryption offers an alternative for cases where you want to retain control of the context without storing your data on xAI servers:

# Enable encrypted content
response = await client.chat.completions.create(
    model="grok-4.5",
    messages=[{"role": "user", "content": "Analyze this contract"}],
    tools=my_tools,
    use_encrypted_content=True
)

# Reasoning and tool outputs are returned encrypted
# You add them as-is to subsequent messages
messages = [
    {"role": "user", "content": "Analyze this contract"},
    response.choices[0].message,  # contains encrypted content
    {"role": "user", "content": "What are the termination clauses?"}
]

response2 = await client.chat.completions.create(
    model="grok-4.5",
    messages=messages,
    use_encrypted_content=True
)

With use_encrypted_content=True, internal reasoning and tool results are returned in encrypted form. You can’t read them, but you resend them in subsequent requests. The server decrypts them to maintain reasoning continuity.

Advantages

  • Context remains under your control (no remote storage)
  • Internal reasoning is preserved without being exposed in plaintext
  • Compatible with strict privacy policies

Limitations

  • Requests are larger (encrypted content is included)
  • You must manage message history on the client side

Choosing Between the Two Methods

The choice depends on your context:

  • store_messages: preferable for chat applications, interactive assistants, and cases where simplicity comes first. Context is managed automatically.
  • use_encrypted_content: preferable for sensitive applications, processing confidential documents, and cases where data must not leave your infrastructure (beyond API transit).

Combining with the Hybrid Workflow

Both methods integrate into the loop pattern seen in the previous lesson:

async def multi_turn_conversation(questions: list[str]) -> list[str]:
    responses = []
    previous_id = None

    for question in questions:
        kwargs = {
            "model": "grok-4.5",
            "messages": [{"role": "user", "content": question}],
            "tools": my_tools,
            "store_messages": True,
        }
        if previous_id:
            kwargs["previous_response_id"] = previous_id

        response = await client.chat.completions.create(**kwargs)
        previous_id = response.id
        responses.append(response.choices[0].message.content)

    return responses

This pattern chains questions while preserving the full conversation context, including tool results and the model’s internal reasoning.

Key Takeaways

  • store_messages=True + previous_response_id delegates context management to xAI
  • use_encrypted_content=True preserves reasoning without remote storage
  • The choice depends on your privacy and simplicity constraints
  • Both methods are compatible with multi-turn workflows and hybrid tools
  • previous_response_id eliminates the need to resend the full message history