Conversation state

OpenAI API · Essentials · 11 min

Every chat app needs memory between turns, and the three options differ in cost, privacy and effort.

Each request is answered on its own; the model only knows what that request contains. To hold a conversation you choose one of three ways to supply the earlier turns.

1. Manage history yourself. Keep a Python list. After each call, add response.output (the model's items) to it, then the next user message, and send the whole list as input. Works with store=False, so nothing is kept on OpenAI's side.

2. Chain with `previous_response_id`. Pass the id of the last response and only the new user message; OpenAI looks up the earlier turns from the stored response. Easy, but it needs storage on (the default), and you are still billed for all earlier input tokens each turn.

3. Use the Conversations API. Create a conversation object once with client.conversations.create() and pass conversation=conv.id on each request. Items are appended automatically and, unlike stored responses, they do not expire after 30 days. Good for chats that continue across days or devices.

Whichever you choose, history grows every turn, so cost grows too, and eventually the conversation will not fit in the model's context window. Plan to drop or summarise old turns; the API also offers server-side compaction, which shrinks long histories for you.

Remember that instructions are not carried along by options 2 and 3; send them each time.

Example

from openai import OpenAI

client = OpenAI()

# Option 1: manual history, nothing stored server-side
history = [{"role": "user", "content": "My name is Ana and I like chess."}]
r1 = client.responses.create(model="gpt-6-astra", input=history, store=False)
history += r1.output
history.append({"role": "user", "content": "What is my hobby?"})
r2 = client.responses.create(model="gpt-6-astra", input=history, store=False)
print(r2.output_text)

# Option 2: chain stored responses
a = client.responses.create(model="gpt-6-astra", input="Tell me a joke.")
b = client.responses.create(model="gpt-6-astra", previous_response_id=a.id,
                            input="Explain why it is funny.")

# Option 3: a durable conversation object
conv = client.conversations.create()
c = client.responses.create(model="gpt-6-astra", conversation=conv.id,
                            input="Remember: my flight is on Friday.")

Remember

  • Manual history: append response.output plus the next user turn
  • previous_response_id: simple chaining of stored responses
  • Conversations API: durable conversation objects; all three still bill past tokens

Watch out for

  • Appending only output_text instead of response.output, which loses reasoning and tool items.

Check yourself

  1. Which option keeps nothing stored on OpenAI's side?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: developers.openai.com/api/docs/guides/conversation-state