# APIs for managing saved conversations

> For the complete documentation index, see [llms.txt](https://developers.thoughtspot.com/docs/llms.txt)

Source: https://developers.thoughtspot.com/docs/spotter-agent-conversation-mgmt-apis

# APIs for managing saved conversations

ThoughtSpot’s Spotter AI conversation management APIs allow you to retrieve, update, and delete saved Spotter 3 conversations and their message history. These APIs allow you to build and render custom conversation history UI, audit trails, and administrative conversation management workflows in applications using Spotter engine or embedding Spotter interface.

## Prerequisites

To create, save, and manage conversation sessions with the Spotter 3 agent, you need `CAN_USE_SPOTTER` (**Can use Spotter**) privilege and access to the saved conversation. Only conversation owners can delete or update their saved conversations.

## Supported API operations

<table class="tableblock frame-all grid-all stretch"><colgroup><col style="width: 100%;"></colgroup><tbody><tr><td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"><p><code>POST /api/rest/2.0/ai/agent/conversation/create</code><br>Allows you to save a conversation session with Spotter AI agent<br><em>Available on ThoughtSpot Cloud instances from 26.5.0.cl onwards.</em></p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"><p><code>GET /api/rest/2.0/ai/agent/conversations/{conversation_identifier}/messages</code><br><a href="{{navprefix}}/{{spotter-agent-conversation-mgmt-apis}}#get-conversation">Retrieves the full message history of a saved Spotter 3 conversation</a>, including ordered user prompts, agent response items, and code-execution file metadata.<br><em>Available on ThoughtSpot Cloud instances from 26.7.0.cl onwards.</em></p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"><p><code>GET /api/rest/2.0/ai/agent/conversations</code><br><a href="{{navprefix}}/{{spotter-agent-conversation-mgmt-apis}}#get-conversation-list">Retrieves a paginated list of saved conversations</a> for the currently authenticated user.<br><em>Available on ThoughtSpot Cloud instances from 26.7.0.cl onwards.</em></p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"><p><code>GET /api/rest/2.0/ai/agent/conversations/{conversation_identifier}/answers/{answer_identifier}/details</code><br><a href="{{navprefix}}/{{spotter-agent-conversation-mgmt-apis}}#load-answer">Retrieves the full answer payload for a specific answer</a> within a saved conversation.<br>Use this endpoint to resolve <code>answer_id</code> references returned by the get conversation messages endpoint.<br><em>Available on ThoughtSpot Cloud instances from 26.7.0.cl onwards.</em></p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"><p><code>POST /api/rest/2.0/ai/agent/conversations/{conversation_identifier}/update</code><br><a href="{{navprefix}}/{{spotter-agent-conversation-mgmt-apis}}#update-conversation">Updates the metadata of a saved conversation</a>, such as renaming its title.<br><em>Available on ThoughtSpot Cloud instances from 26.7.0.cl onwards.</em></p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"><p><code>DELETE /api/rest/2.0/ai/agent/conversations/{conversation_identifier}/delete</code><br><a href="{{navprefix}}/{{spotter-agent-conversation-mgmt-apis}}#delete-conversation">Deletes a saved conversation</a> and all its messages.<br><em>Available on ThoughtSpot Cloud instances from 26.7.0.cl onwards.</em></p></div></div></td></tr></tbody></table>

## Saving a conversation

To save a conversation, set the `enable_save_chat` parameter to `true` when sending a [conversation create `POST` request]({{navprefix}}/{{spotter-agent-conversation-apis}}#_create_a_conversation_session_with_spotter_agent) to the `/api/rest/2.0/ai/agent/conversation/create` API endpoint.

### API request example

```cURL
curl -X POST \
  --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/agent/conversation/create'  \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer {AUTH_TOKEN}' \
  --data-raw '{
  "metadata_context": {
    "type": "AUTO_MODE"
  },
  "conversation_settings": {
    "enable_save_chat": true
  }
}'
```

If the API request is successful, ThoughtSpot returns the conversation IDs.

```JSON
{
"conversation_id":"MotUVRdguIcr",
"conversation_identifier":"MotUVRdguIcr"
}
```

Note these IDs.

## Get conversation messages

To retrieve a saved conversation, send a `GET` request to the `/api/rest/2.0/ai/agent/conversations/{conversation_identifier}/messages` API endpoint with the conversation ID in the API request URL. Use this endpoint to render a persisted conversation in a UI, build an audit trail, or post-process a completed conversation.

> **NOTE:** The full answer payload for each turn is not embedded in the response. To retrieve it, call the load answer details endpoint with the answer\_id returned in each answer-type response item.

### Example request

```cURL
curl -X GET \
  --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/agent/conversations/MotUVRdguIcr/messages'  \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {AUTH_TOKEN}' \
```

### API response

A successful request returns an HTTP `200` response with top-level fields that include ordered conversation turns (user prompts and agent response items) and sanitized metadata for any files generated by the code-execution tool.

When the agent conversation is initiated from a Liveboard, ThoughtSpot automatically seeds the conversation with the existing Liveboard visualization as the first response turn, without any user query. In the API response, this seeded turn appears as the first item in the `messages` array with `user_prompt` set to `null` and `message_id` set to the internal root node identifier of the conversation. All subsequent turns contain a populated `user_prompt`. When rendering conversation history, always check whether `user_prompt` is `null` before attempting to display a user query.

### Response body

 
| Field | Description |
| --- | --- |
| 
`messages`

 | 

An ordered array of conversation turns, oldest to newest. Returns an empty array when the conversation has no messages.

 |
| 

`code_execution_files`

 | 

`CodeExecutionFileMetadata[]`. An array of sanitized metadata for all files generated by the code-execution tool across the entire conversation. Returns an empty array when no such files exist.

 |

#### ConversationMessage

Each item in `messages` represents one conversational turn.

 
| Field | Description |
| --- | --- |
| 
`message_id`

 | 

_String_. Message ID. For Liveboard-initiated first turns, this ID is the root node identifier.

 |
| 

`timestamp_in_millis`

 | 

Unix epoch timestamp for the turn, in milliseconds.

 |
| 

`user_prompt`

 | 

`UserPrompt[]`. The user-authored prompt that started the turn, including the message text and any attachments.

 |
| 

`response_items`

 | 

An array of agent response items produced for this turn. Returns an empty array for turns that are still in progress, which allows the UI to render the user message immediately while the agent is still processing.

 |

#### UserPrompt

 
| Field | Description |
| --- | --- |
| 
`message`

 | 

`UserMessage`. The user-authored text query that started the turn.

 |
| 

`attachments`

 | 

`UserAttachmentItem[]`. Files or connector resources attached to the user message. Returns an empty array when there are no attachments.

 |

#### UserMessage

 
| Field | Description |
| --- | --- |
| 
`message_id`

 | 

_String_. Unique identifier of the user message.

 |
| 

`content`

 | 

_String_. Text body of the user query.

 |

#### UserAttachmentItem

Is distinguished by the `type` field. Valid values are `file` and `resource`. Only the fields for the indicated variant are populated.

 
| Field | Description |
| --- | --- |
| 
`type`

 | 

_String_. Attachment type. Valid values: `file`, `resource`.

 |
| 

`file_id`

 | 

_String_. Unique identifier of the attached file. Matches a `file_id` in `code_execution_files`.

 |
| 

`resource_identifier`

 | 

_String_. Identifier of the attached connector resource.

 |

#### ConversationResponseItem

Each agent response item carries a `type` distinguisher. The following types are supported.

 
| Field | Description |
| --- | --- |
| 
`type`

 | 

_String_. Response item variant distinguisher. Supported values include:

-   `answer`: a Spotter-generated analytical answer. Carries an `answer_id` field. Pass this value as `answer_identifier` to the [load answer details]({{navprefix}}/{{spotter-agent-conversation-mgmt-apis}}#load-answer) endpoint to retrieve the full answer payload.
    
-   `text`: a free-text response from the agent.
    
-   `notification`: an agent-generated notification, such as a conversation title suggestion.
    





 |
| 

`answer_id`

 | 

_String_. Unique identifier of the answer. Use this to call the load answer details endpoint.





 |
| 

`content`

 | 

_String_. Text content of the response.

 |

#### CodeExecutionFileMetadata

Sanitized metadata for a file generated by the code-execution tool.

 
| Field | Description |
| --- | --- |
| 
`file_id`

 | 

_String_. Unique identifier of the code-execution-generated file. Stable across conversation turns. Use this to match attachment references in `UserAttachmentItem`.

 |
| 

`display_name`

 | 

_String_. Human-readable file name.

 |
| 

`file_type`

 | 

_String_. File type hint. Either a MIME type string (for example, `text/csv`) or a file extension (for example, `csv`).

 |
| 

`created_time_in_millis`

 | 

Unix epoch timestamp when the file was created, in milliseconds.

 |
| 

`expired`

 | 

_Boolean_. Set to `true` when the file is no longer downloadable because its storage has expired or been evicted.

 |

#### Response example

```JSON
{
  "messages": [
    {
      "message_id": "node_u_01",
      "timestamp_in_millis": 1744000000000,
      "user_prompt": {
        "message": {
          "message_id": "msg_u_01",
          "content": "Show me revenue by region as a chart."
        },
        "attachments": []
      },
      "response_items": [
        {
          "type": "tool_call",
          "tool_call_id": "toolu_01ABC",
          "tool_name": "search_datasets",
          "step_title": "Searching datasets",
          "arguments": { "query": "revenue" },
          "timestamp_in_millis": 1744000001000,
          "is_thinking": false
        },
        {
          "type": "answer",
          "answer_id": "ans_01XYZ",
          "tool_call_id": "toolu_02DEF",
          "tool_name": "fetch_and_visualize",
          "step_title": "Visualising",
          "timestamp_in_millis": 1744000004000,
          "is_thinking": false
        },
        {
          "type": "text",
          "content": "Revenue is highest in APAC.",
          "content_type": "TEXT_MARKDOWN",
          "timestamp_in_millis": 1744000005000,
          "is_thinking": false,
          "step_title": null,
          "file_reference": {
            "file_id": "revenue_by_region.csv",
            "display_name": "revenue_by_region.csv",
            "created_time_in_millis": 1744027200000
          }
        }
      ]
    }
  ],
  "code_execution_files": [
    {
      "file_id": "revenue_by_region.csv",
      "display_name": "revenue_by_region.csv",
      "file_type": "csv",
      "created_time_in_millis": 1744027200000,
      "expired": false
    }
  ]
}
```

## Get conversation list

The `GET /api/rest/2.0/ai/agent/conversations` endpoint retrieves a paginated list of saved conversations for the currently authenticated user. Only conversations created with `enable_save_chat: true` are returned in the API response.

### Request parameters

 
| Query parameter | Description |
| --- | --- |
| 
`limit`

 | 

_Number_. Maximum number of conversations to return per page. Use together with `offset` for pagination.





 |
| 

`offset`

 | 

_Number_. Number of conversations to skip before returning results. Defaults to `0`.

 |
| 

`skip_empty`

 | 

_Boolean_. When set to `true`, conversations with no messages are excluded from the results. Pass `skip_empty=false` to include empty conversations, for example, when listing conversations immediately after creation.

 |

### API request

```cURL
curl -X GET -G \
  --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/agent/conversations'  \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {AUTH_TOKEN}' \
  -d 'limit=30' \
  -d 'offset=0' \
  -d 'skip_empty=true'
```

### API response

If the API request is successful, ThoughtSpot returns a response body. The API response does not include a `total_count` field. Use `has_more` to drive pagination controls.

### Response body

 
| Field | Description |
| --- | --- |
| 
`conversations`

 | 

`AgentConversationList[]`. Array of saved conversation summary objects for the current user.

 |
| 

`has_more`

 | 

_Boolean_. Set to `true` when additional conversations exist beyond the current page. Set to `false` when the current page is the last. Use `offset` to fetch the next page.

 |

#### AgentConversationList

Each item in `conversations` represents a saved conversation.

 
| Field | Description |
| --- | --- |
| 
`conversation_identifier`

 | 

_String_. Unique identifier of the conversation. Use this value as input in your API requests to the [send message]({{navprefix}}/{{spotter-agent-conversation-apis}}#_send_queries_to_a_conversation_session), [update conversation]({{navprefix}}/{{spotter-agent-conversation-mgmt-apis}}#update-conversation), [delete conversation]({{navprefix}}/{{spotter-agent-conversation-mgmt-apis}}#delete-conversation), [stop response]({{navprefix}}/{{spotter-agent-conversation-apis}}#_stop_an_in_progress_agent_response), and [load answer]({{navprefix}}/{{spotter-agent-conversation-mgmt-apis}}#load-answer) endpoints.

 |
| 

`conversation_title`

 | 

_String_. Display name of the conversation.





 |
| 

`created_at`

 | 

_String_. Timestamp of when the conversation was created.

 |
| 

`updated_at`

 | 

_String_. Timestamp of when the conversation was last updated.

 |
| 

`data_source_identifiers`

 | 

_Array of strings_. Unique identifiers of the data sources associated with the conversation.





 |
| 

`data_source_names`

 | 

`DataSourceEntry[]`. Display names and identifiers for the data sources associated with the conversation.





 |

#### DataSourceEntry

 
| Field | Description |
| --- | --- |
| 
`id`

 | 

_String_. Unique identifier of the data source.

 |
| 

`name`

 | 

_String_. Display name of the data source.

 |

### Pagination

Use `limit` and `offset` together to page through large result sets. The response does not include a `total_count` field. Use `has_more` to determine whether additional pages exist.

GET /api/rest/2.0/ai/agent/conversations?limit=20&offset=0   (first page)
GET /api/rest/2.0/ai/agent/conversations?limit=20&offset=20  (second page)

Continue incrementing `offset` by `limit` until `has_more` returns `false`.

#### API response example

```JSON
{
  "conversations": [
    {
      "conversation_identifier": "abc123",
      "conversation_title": "Sales by Region Q1",
      "created_at": "2026-03-01T10:00:00Z",
      "updated_at": "2026-03-05T14:23:00Z",
      "data_source_identifiers": ["ds-001"],
      "data_source_names": [{ "id": "ds-001", "name": "Retail Sales" }]
    }
  ],
  "has_more": false
}
```

## Load answer details

To retrieve the full answer payload for a specific analytical answer within a saved conversation, send a `GET` request to the `GET /api/rest/2.0/ai/agent/conversations/{conversation_identifier}/answers/{answer_identifier}/details` endpoint with the conversation ID and answer ID in the request URL.

### Call sequence

The following sequence is required to resolve a full answer from a saved conversation:

1.  Call [get conversation list]({{navprefix}}/{{spotter-agent-conversation-mgmt-apis}}#get-conversation-list) to retrieve saved conversations and obtain a `conversation_identifier`.
    
2.  Call [get conversation messages]({{navprefix}}/{{spotter-agent-conversation-mgmt-apis}}#get-conversation) with the `conversation_identifier`. Locate `response_items` entries with `type: answer` and note the `answer_id` field on each.
    
3.  Call this endpoint with the `conversation_identifier` and the `answer_id` as `answer_identifier` to retrieve the full answer payload.
    
4.  Use the `tokens` array in the response to reconstruct or render the answer in your application.
    

### Request parameters

 
| Parameter | Description |
| --- | --- |
| 
`conversation_identifier`

 | 

_String_. Path parameter. Unique identifier of the conversation.

 |
| 

`answer_identifier`

 | 

_String_. Path parameter. The `answer_id` value from a `response_item` of `type: answer` in the get conversation messages response. You cannot pass arbitrary IDs to this endpoint.

 |

### API request

```cURL
curl -X GET \
  --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/agent/conversations/0iwTDJU-tlkm/answers/5MS5xieDhefP/details'  \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {AUTH_TOKEN}' \
```

### Response body

If the API request is successful, ThoughtSpot returns a response body with the answer details.

  
| Field | Type | Description |
| --- | --- | --- |

### Example response

```JSON
{
   "answer":{
      "title":"total sales by state where item type is jackets",
      "description":null,
      "session_identifier":"5216568f-f808-4385-ad0a-3a40bb9b5dcb",
      "generation_number":2,
      "tokens":[
         "[sales] [state] [item type] = 'jackets'"
      ],
      "visualization_type":"UNDEFINED",
      "formulas":[
      ],
      "parameters":[
      ],
      "sub_queries":[
      ],
      "ac_state":{
         "transaction_identifier":"00ccc6e0-1117-4713-8798-d6201d3a5a40",
         "generation_number":1
      }
   }
}
```

## Update a conversation

To update the metadata of an existing conversation, send a `POST` request to the `/api/rest/2.0/ai/agent/conversations/{conversation_identifier}/update` API endpoint with the conversation ID in the request URL. Currently, the API endpoint allows you to rename the conversation title only.

### Request parameters

 
| Parameter | Description |
| --- | --- |
| 
`conversation_identifier`

 | 

_String_. Path parameter. Unique identifier of the conversation to update.

 |
| 

`title`

 | 

_String_. Form parameter to include in the request body. To rename the display title of the conversation, specify the title string.

 |

#### API request example

```cURL
curl -X POST \
  --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/agent/conversations/0iwTDJU-tlkm/update'  \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer {AUTH_TOKEN}' \
  --data-raw '{
  "title": "Revenue Analysis — Q1 2026"
}'
```

### API response

A successful request returns the 204 response.

## Delete a conversation

To delete a saved conversation and all its associated messages, send a `DELETE` request to the `/api/rest/2.0/ai/agent/conversations/{conversation_identifier}/delete` API endpoint with the conversation ID as a path parameter.

> **IMPORTANT:** ThoughtSpot allows only the conversation owners to delete a conversation. Deleted conversations and all their messages cannot be recovered. Therefore, we recommend exercising caution when deleting a saved conversation.

### API request

```cURL
curl -X DELETE \
  --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/agent/conversations/MotUVRdguIcr/delete'  \
  -H 'Authorization: Bearer {AUTH_TOKEN}' \
```

### API response

A successful request returns an HTTP `204 No Content` response with an empty body. After a successful deletion, subsequent calls to the get conversation messages or load answer endpoints for the same `conversation_identifier` result in the `404 Not Found` error.

## Additional resources

-   See also [Spotter Agent APIs]({{navprefix}}/{{spotter-agent-apis}})
    
-   To try out the request and response workflow, use the [REST API Playground]({{navprefix}}/restV2-playground?apiResourceId=http%2Fapi-endpoints%2Fai%2Fget-conversation)