Use threads with the Cortex Agent REST API¶
This guide explains how to create, continue, and manage threaded conversations using the Cortex Agent REST API.
The workflow for using threads includes the following steps:
- Create a new thread and use it as part of an
agent:runrequest to the Cortex Agent REST API. - Read the message IDs for the thread.
- Choose a message to continue the thread from.
Start a new thread and use it with Agent Run¶
You must create a new thread, then pass it as part of a request to agent:run.
- Create a new thread using Create thread.
- Pass the ID of the newly created thread as part of a request to one of the
agent:runREST API endpoints.
agent:runwith Agent Object:
agent:runwithout Agent Object:As part of the request, pass the following:
parent_message_idmust be0. This indicates that this request is the start of the thread.- Exactly one user message in
messages.
Read the returned message IDs¶
The Agent API streams back metadata events for each message in the conversation. The following output shows the structure of the metadata. Always listen for both user and assistant metadata events.
In this output, the message IDs correspond to the following in the conversation:
123: the persisted user message ID456: the persisted assistant message ID
Together, these IDs form the following thread:
Continue the conversation¶
For the next turn in the conversation, set parent_message_id to the last successful assistant message ID and pass new values in messages. In this example, the parent message ID is 456.
Note
You must pass an assistant message ID as the parent_message_id to ensure the LLM functions as expected. You cannot pass a user message ID.
If you have lost track of the last message ID, use Create thread to list all messages in the thread.
Continue using the latest successful assistant message ID as the parent_message_id in subsequent requests.
Fork a conversation¶
You can also fork the conversation by continuing from any earlier assistant message. To fork the conversation, pass the desired assistant message ID as the parent_message_id in a new request. In the following example, 3 (user) -> 4 (assistant) and 5 (user) -> 6 (assistant) represent two different forks from the same assistant response.
Retrieve the latest summary and subsequent messages¶
When a thread grows long, Cortex Agents periodically compacts older turns into a summary message and stores it in the thread with a message type of compaction. By default, the Describe thread endpoint returns only conversation messages, so summaries stay hidden unless you explicitly filter for them. If you only need conversation history, this default response is sufficient; you can also request it explicitly with message_type=conversation. To rehydrate the recent thread state for a new interaction, you often want the latest summary along with every conversation message that was created after it.
The endpoint returns messages in descending order of creation, and the last_message_id query parameter acts as an exclusive cursor: it returns messages older than the specified ID. The endpoint doesn’t expose a forward cursor, but message IDs are monotonically increasing across both message types, so a numeric ID comparison is a reliable proxy for chronological ordering. You retrieve this view in two steps:
- Fetch the latest summary message.
- Walk backward through conversation messages, keeping every message whose
message_idis greater than the summary’smessage_id.
Step one: Fetch the latest summary¶
Set message_type=compaction and page_size=1 to return only the newest summary message.
Record the message_id from the returned summary. This value is the anchor for Step two.
Note
If the response returns an empty messages array, the thread hasn’t been compacted yet. In that case, you can skip the anchor and fetch every conversation message in Step two.
Step two: Fetch conversation messages after the summary¶
Set message_type=conversation and page backward until you cross the anchor from Step one.
For each returned page:
- Keep messages whose
message_idis greater than the anchor from Step one. - If any message on the page has a
message_idless than or equal to the anchor, or if the page contains fewer thanpage_sizemessages, stop paging. - Otherwise, take the smallest
message_idon the page, which is the last entry because results are in descending order, and pass it aslast_message_idon the next request.
The following Python function shows the full pattern:
The returned list starts with the latest summary (if one exists), followed by every conversation message created after it, in chronological order. To continue the thread from this context, pass the newest assistant message_id from the returned list as parent_message_id in a subsequent request; see Continue the conversation.
Troubleshooting¶
In rare cases, the Agent API might fail to store the assistant message. If assistant metadata is missing from the response, ignore the failed turn and continue from the last successful assistant message.
For example, consider the following thread:
To continue the conversation, pass message ID 2 as part of a new request because that is the last successful assistant message.