docs
0
# Conversations
1
2
Create and manage conversations for structured multi-turn interactions. Conversations provide a lightweight alternative to Threads for managing conversational context with items that can include user inputs, system messages, and function outputs.
3
4
## Capabilities
5
6
### Create Conversation
7
8
Create a new conversation with optional initial items.
9
10
```python { .api }
11
def create(
12
self,
13
*,
14
items: Iterable[dict] | None | Omit = omit,
15
metadata: dict[str, str] | None | Omit = omit,
16
extra_headers: dict[str, str] | None = None,
17
extra_query: dict[str, object] | None = None,
18
extra_body: dict[str, object] | None = None,
19
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
20
) -> Conversation:
21
"""
22
Create a conversation.
23
24
Args:
25
items: Initial items to include in the conversation context.
26
You may add up to 20 items at a time. Each item can be:
27
- Message: {"type": "message", "role": "user", "content": "..."}
28
- System: {"type": "message", "role": "system", "content": "..."}
29
- Function output: {"type": "function_call_output", "call_id": "...", "output": "..."}
30
31
metadata: Up to 16 key-value pairs for storing additional information.
32
Keys max 64 characters, values max 512 characters.
33
Useful for storing user IDs, session info, etc.
34
35
extra_headers: Additional HTTP headers.
36
extra_query: Additional query parameters.
37
extra_body: Additional JSON fields.
38
timeout: Request timeout in seconds.
39
40
Returns:
41
Conversation: Created conversation object with unique ID.
42
43
Notes:
44
- Conversations are lightweight compared to Threads
45
- No automatic message persistence - items must be explicitly managed
46
- Use for scenarios requiring explicit context control
47
"""
48
```
49
50
Usage examples:
51
52
```python
53
from openai import OpenAI
54
55
client = OpenAI()
56
57
# Create empty conversation
58
conversation = client.conversations.create()
59
print(f"Created conversation: {conversation.id}")
60
61
# Create with initial items
62
conversation = client.conversations.create(
63
items=[
64
{
65
"type": "message",
66
"role": "system",
67
"content": "You are a helpful coding assistant."
68
},
69
{
70
"type": "message",
71
"role": "user",
72
"content": "How do I reverse a string in Python?"
73
}
74
],
75
metadata={
76
"user_id": "user_123",
77
"session": "session_abc"
78
}
79
)
80
81
# Create with metadata
82
conversation = client.conversations.create(
83
metadata={
84
"purpose": "customer_support",
85
"language": "en",
86
"priority": "high"
87
}
88
)
89
```
90
91
### Retrieve Conversation
92
93
Get a conversation by its ID.
94
95
```python { .api }
96
def retrieve(
97
self,
98
conversation_id: str,
99
*,
100
extra_headers: dict[str, str] | None = None,
101
extra_query: dict[str, object] | None = None,
102
extra_body: dict[str, object] | None = None,
103
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
104
) -> Conversation:
105
"""
106
Get a conversation.
107
108
Args:
109
conversation_id: ID of the conversation to retrieve.
110
111
extra_headers: Additional HTTP headers.
112
extra_query: Additional query parameters.
113
extra_body: Additional JSON fields.
114
timeout: Request timeout in seconds.
115
116
Returns:
117
Conversation: Conversation object with current metadata and items.
118
"""
119
```
120
121
### Update Conversation
122
123
Update conversation metadata.
124
125
```python { .api }
126
def update(
127
self,
128
conversation_id: str,
129
*,
130
metadata: dict[str, str] | None,
131
extra_headers: dict[str, str] | None = None,
132
extra_query: dict[str, object] | None = None,
133
extra_body: dict[str, object] | None = None,
134
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
135
) -> Conversation:
136
"""
137
Update a conversation.
138
139
Args:
140
conversation_id: ID of the conversation to update.
141
142
metadata: New metadata dictionary. Replaces all existing metadata.
143
Up to 16 key-value pairs, keys max 64 chars, values max 512 chars.
144
145
extra_headers: Additional HTTP headers.
146
extra_query: Additional query parameters.
147
extra_body: Additional JSON fields.
148
timeout: Request timeout in seconds.
149
150
Returns:
151
Conversation: Updated conversation object.
152
153
Notes:
154
- Metadata is completely replaced, not merged
155
- To preserve existing metadata, retrieve first then update
156
"""
157
```
158
159
### Delete Conversation
160
161
Delete a conversation.
162
163
```python { .api }
164
def delete(
165
self,
166
conversation_id: str,
167
*,
168
extra_headers: dict[str, str] | None = None,
169
extra_query: dict[str, object] | None = None,
170
extra_body: dict[str, object] | None = None,
171
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
172
) -> ConversationDeleted:
173
"""
174
Delete a conversation.
175
176
Args:
177
conversation_id: ID of the conversation to delete.
178
179
extra_headers: Additional HTTP headers.
180
extra_query: Additional query parameters.
181
extra_body: Additional JSON fields.
182
timeout: Request timeout in seconds.
183
184
Returns:
185
ConversationDeleted: Deletion confirmation with ID and status.
186
187
Notes:
188
- Items in the conversation will not be deleted
189
- Deletion is permanent and cannot be undone
190
- Items remain accessible if you have their IDs
191
"""
192
```
193
194
### Conversation Items
195
196
Manage items within a conversation.
197
198
```python { .api }
199
# Access via client.conversations.items
200
201
def create(
202
self,
203
conversation_id: str,
204
*,
205
items: Iterable[dict],
206
include: list[Literal[
207
"web_search_call.action.sources",
208
"code_interpreter_call.outputs",
209
"computer_call_output.output.image_url",
210
"file_search_call.results",
211
"message.input_image.image_url",
212
"message.output_text.logprobs",
213
"reasoning.encrypted_content"
214
]] | Omit = omit,
215
extra_headers: dict[str, str] | None = None,
216
extra_query: dict[str, object] | None = None,
217
extra_body: dict[str, object] | None = None,
218
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
219
) -> ConversationItemList:
220
"""
221
Create items in a conversation.
222
223
Args:
224
conversation_id: ID of the conversation.
225
226
items: The items to add to the conversation. You may add up to 20 items at a time.
227
Each item is a dict with one of these structures:
228
- Message: {"type": "message", "role": "user"|"system"|"developer", "content": [...]}
229
- Function call output: {"type": "function_call_output", "call_id": "...", "output": "..."}
230
- Computer call output: {"type": "computer_call_output", "call_id": "...", "output": {...}}
231
- Shell call output: {"type": "shell_call_output", "call_id": "...", "output": [...]}
232
- And many other item types (see ResponseInputItemParam for full list)
233
234
include: Additional fields to include in the response. Options:
235
- "web_search_call.action.sources": Include web search sources
236
- "code_interpreter_call.outputs": Include code execution outputs
237
- "computer_call_output.output.image_url": Include computer call images
238
- "file_search_call.results": Include file search results
239
- "message.input_image.image_url": Include input message images
240
- "message.output_text.logprobs": Include logprobs with assistant messages
241
- "reasoning.encrypted_content": Include encrypted reasoning tokens
242
243
extra_headers: Additional HTTP headers.
244
extra_query: Additional query parameters.
245
extra_body: Additional JSON fields.
246
timeout: Request timeout in seconds.
247
248
Returns:
249
ConversationItemList: List of created items with IDs and timestamps.
250
"""
251
252
def retrieve(
253
self,
254
item_id: str,
255
*,
256
conversation_id: str,
257
include: list[Literal[
258
"web_search_call.action.sources",
259
"code_interpreter_call.outputs",
260
"computer_call_output.output.image_url",
261
"file_search_call.results",
262
"message.input_image.image_url",
263
"message.output_text.logprobs",
264
"reasoning.encrypted_content"
265
]] | Omit = omit,
266
extra_headers: dict[str, str] | None = None,
267
extra_query: dict[str, object] | None = None,
268
extra_body: dict[str, object] | None = None,
269
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
270
) -> ConversationItem:
271
"""
272
Retrieve a specific item from a conversation.
273
274
Args:
275
item_id: ID of the item to retrieve.
276
conversation_id: ID of the conversation.
277
278
include: Additional fields to include in the response. See create() for available options.
279
280
extra_headers: Additional HTTP headers.
281
extra_query: Additional query parameters.
282
extra_body: Additional JSON fields.
283
timeout: Request timeout in seconds.
284
285
Returns:
286
ConversationItem: Item with full content and metadata.
287
"""
288
289
def delete(
290
self,
291
item_id: str,
292
*,
293
conversation_id: str,
294
extra_headers: dict[str, str] | None = None,
295
extra_query: dict[str, object] | None = None,
296
extra_body: dict[str, object] | None = None,
297
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
298
) -> Conversation:
299
"""
300
Delete an item from a conversation.
301
302
Args:
303
item_id: ID of the item to delete.
304
conversation_id: ID of the conversation.
305
306
extra_headers: Additional HTTP headers.
307
extra_query: Additional query parameters.
308
extra_body: Additional JSON fields.
309
timeout: Request timeout in seconds.
310
311
Returns:
312
Conversation: Updated conversation after item deletion.
313
314
Notes:
315
- Deletion is permanent
316
- Returns the conversation object (not a deletion confirmation)
317
"""
318
319
def list(
320
self,
321
conversation_id: str,
322
*,
323
after: str | Omit = omit,
324
include: list[Literal[
325
"web_search_call.action.sources",
326
"code_interpreter_call.outputs",
327
"computer_call_output.output.image_url",
328
"file_search_call.results",
329
"message.input_image.image_url",
330
"message.output_text.logprobs",
331
"reasoning.encrypted_content"
332
]] | Omit = omit,
333
limit: int | Omit = omit,
334
order: Literal["asc", "desc"] | Omit = omit,
335
extra_headers: dict[str, str] | None = None,
336
extra_query: dict[str, object] | None = None,
337
extra_body: dict[str, object] | None = None,
338
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
339
) -> SyncConversationCursorPage[ConversationItem]:
340
"""
341
List items in a conversation.
342
343
Args:
344
conversation_id: ID of the conversation.
345
346
after: Cursor for pagination. Return items after this ID.
347
348
include: Additional fields to include in the response. See create() for available options.
349
350
limit: Maximum number of items to return (1-100). Default 20.
351
352
order: Sort order by creation time:
353
- "asc": Ascending (oldest first)
354
- "desc": Descending (newest first, default)
355
356
extra_headers: Additional HTTP headers.
357
extra_query: Additional query parameters.
358
extra_body: Additional JSON fields.
359
timeout: Request timeout in seconds.
360
361
Returns:
362
SyncConversationCursorPage[ConversationItem]: Paginated list of items.
363
"""
364
```
365
366
Complete workflow example:
367
368
```python
369
from openai import OpenAI
370
371
client = OpenAI()
372
373
# 1. Create conversation
374
conversation = client.conversations.create(
375
metadata={"user_id": "user_123"}
376
)
377
378
# 2. Add system and user messages (batch create)
379
items_response = client.conversations.items.create(
380
conversation_id=conversation.id,
381
items=[
382
{
383
"type": "message",
384
"role": "system",
385
"content": [{"type": "text", "text": "You are a helpful Python tutor."}]
386
},
387
{
388
"type": "message",
389
"role": "user",
390
"content": [{"type": "text", "text": "How do I read a file in Python?"}]
391
}
392
]
393
)
394
395
system_item = items_response.data[0]
396
user_item = items_response.data[1]
397
398
# 4. List all items
399
items = client.conversations.items.list(
400
conversation_id=conversation.id,
401
order="asc"
402
)
403
404
for item in items:
405
print(f"{item.role}: {item.content}")
406
407
# 5. Add assistant response
408
assistant_response = client.conversations.items.create(
409
conversation_id=conversation.id,
410
items=[
411
{
412
"type": "message",
413
"role": "assistant",
414
"content": [{"type": "text", "text": "You can read a file using: with open('file.txt', 'r') as f: content = f.read()"}]
415
}
416
]
417
)
418
assistant_item = assistant_response.data[0]
419
420
# 6. Update conversation metadata
421
client.conversations.update(
422
conversation_id=conversation.id,
423
metadata={
424
"user_id": "user_123",
425
"status": "resolved",
426
"topic": "file_io"
427
}
428
)
429
430
# 7. Get updated conversation
431
updated = client.conversations.retrieve(conversation_id=conversation.id)
432
print(f"Metadata: {updated.metadata}")
433
434
# 8. Delete specific item
435
client.conversations.items.delete(
436
conversation_id=conversation.id,
437
item_id=user_item.id
438
)
439
440
# 9. Clean up - delete conversation
441
client.conversations.delete(conversation_id=conversation.id)
442
```
443
444
Multi-modal conversation example:
445
446
```python
447
from openai import OpenAI
448
449
client = OpenAI()
450
451
# Create conversation with image
452
conversation = client.conversations.create()
453
454
# Add user message with image
455
client.conversations.items.create(
456
conversation_id=conversation.id,
457
items=[
458
{
459
"type": "message",
460
"role": "user",
461
"content": [
462
{
463
"type": "text",
464
"text": "What's in this image?"
465
},
466
{
467
"type": "image_url",
468
"image_url": {
469
"url": "https://example.com/image.jpg"
470
}
471
}
472
]
473
}
474
]
475
)
476
477
# Add assistant response
478
client.conversations.items.create(
479
conversation_id=conversation.id,
480
items=[
481
{
482
"type": "message",
483
"role": "assistant",
484
"content": [{"type": "text", "text": "I see a beautiful sunset over mountains."}]
485
}
486
]
487
)
488
```
489
490
## Async Usage
491
492
```python
493
import asyncio
494
from openai import AsyncOpenAI
495
496
async def manage_conversation():
497
client = AsyncOpenAI()
498
499
# Create conversation
500
conversation = await client.conversations.create(
501
metadata={"user_id": "user_123"}
502
)
503
504
# Add message
505
await client.conversations.items.create(
506
conversation_id=conversation.id,
507
items=[
508
{
509
"type": "message",
510
"role": "user",
511
"content": [{"type": "text", "text": "Hello!"}]
512
}
513
]
514
)
515
516
# List items
517
async for item in await client.conversations.items.list(
518
conversation_id=conversation.id
519
):
520
print(item.content)
521
522
# Delete conversation
523
await client.conversations.delete(conversation_id=conversation.id)
524
525
asyncio.run(manage_conversation())
526
```
527
528
## Types
529
530
```python { .api }
531
from typing import Literal
532
from pydantic import BaseModel
533
534
class Conversation(BaseModel):
535
"""Conversation object."""
536
id: str
537
created_at: int
538
object: Literal["conversation"]
539
metadata: dict[str, str] | None
540
541
class ConversationItem(BaseModel):
542
"""Item within a conversation (union type - can be message, tool call, or tool output)."""
543
id: str
544
conversation_id: str
545
created_at: int
546
object: Literal["conversation.item"]
547
# Type-specific fields vary by item type
548
# See ResponseInputItemParam for complete type definitions
549
550
class ConversationItemList(BaseModel):
551
"""List of conversation items returned from batch create."""
552
data: list[ConversationItem]
553
object: Literal["list"]
554
555
class ConversationDeleted(BaseModel):
556
"""Deletion confirmation."""
557
id: str
558
deleted: bool
559
object: Literal["conversation.deleted"]
560
561
class SyncConversationCursorPage[T]:
562
"""Cursor-based pagination for conversation items."""
563
data: list[T]
564
has_more: bool
565
last_id: str | None
566
def __iter__(self) -> Iterator[T]: ...
567
568
class Omit:
569
"""Sentinel value for omitted parameters."""
570
```
571
572
## Access Pattern
573
574
```python
575
# Synchronous
576
from openai import OpenAI
577
client = OpenAI()
578
client.conversations.create(...)
579
client.conversations.retrieve(...)
580
client.conversations.update(...)
581
client.conversations.delete(...)
582
client.conversations.items.create(...)
583
client.conversations.items.retrieve(...)
584
client.conversations.items.delete(...)
585
client.conversations.items.list(...)
586
587
# Asynchronous
588
from openai import AsyncOpenAI
589
client = AsyncOpenAI()
590
await client.conversations.create(...)
591
await client.conversations.retrieve(...)
592
await client.conversations.update(...)
593
await client.conversations.delete(...)
594
await client.conversations.items.create(...)
595
await client.conversations.items.retrieve(...)
596
await client.conversations.items.delete(...)
597
await client.conversations.items.list(...)
598
```
599