API v2 Conversations
List and export conversations, read messages, retry replies, submit tool results, and manage message feedback.
Use these endpoints to read conversation history and work with API v2 messages. Every endpoint on this page requires Authorization: Bearer YOUR_API_KEY and access to {agentId}.
Conversation Scope
Read-only conversation endpoints default to source=api_v2. Set source=widget to return widget and Playground conversations; Playground rows are stored with the widget source. Set source=all to return API v2, widget, and Playground conversations. Results always remain limited to the authenticated account's agent. An invalid source value or more than one source query parameter returns 400 VALIDATION_INVALID_BODY. Chat continuation, retry, feedback, message listing, and per-user reads remain scoped to API v2 conversations.
Response Objects
Conversation summaries contain:
| Field | Type | Notes |
|---|---|---|
id | string | Public conversation reference ID. |
title | string | First user message, truncated to 80 characters; New conversation when unavailable. |
createdAt | integer | Unix timestamp in seconds. |
updatedAt | integer | Unix timestamp in seconds. |
userId | string or null | End-user ID supplied through API v2 chat. |
source | string or null | Normally api_v2 or widget. Playground conversations are stored as widget. |
status | string | Stored conversation status, or ongoing when no status is stored. |
Message objects contain:
| Field | Type | Notes |
|---|---|---|
id | string | Numeric database message ID serialized as a string. |
role | string | assistant for assistant senders; otherwise user. |
parts | array | One { "type": "text", "text": "..." } part. |
createdAt | integer | Unix timestamp in seconds. |
feedback | string or null | positive, negative, or null. |
metadata | any JSON value | Persisted message metadata. |
Tool-type message rows are omitted from conversation transcripts and message lists.
List Conversations
Path: /api/v2/agents/{agentId}/conversations
GET /api/v2/agents/{agentId}/conversations
Authentication: Bearer API key with access to {agentId}.
| Query | Required | Constraints |
|---|---|---|
limit | No | Integer from 1 to 100; defaults to 20. |
cursor | No | Opaque cursor returned by the preceding page. Replay it unchanged. |
source | No | api_v2 (default), widget, or all. It may appear only once. |
curl 'https://your-domain.com/api/v2/agents/955f28f1-8515-40bb-802c-f3f730bf0343/conversations?source=all&limit=20' \ -H 'Authorization: Bearer YOUR_API_KEY'
Success: 200 OK
{
"data": [
{
"id": "b2mD4kL8pQ1sT6vX",
"title": "Where is my order?",
"createdAt": 1784332800,
"updatedAt": 1784332860,
"userId": "customer_123",
"source": "api_v2",
"status": "ongoing"
}
],
"pagination": {
"cursor": null,
"hasMore": false,
"total": 1
}
}
Invalid limits, cursors, source values, and duplicate source parameters return 400 VALIDATION_INVALID_BODY.
Export Conversations
Path: /api/v2/agents/{agentId}/conversations/export
GET /api/v2/agents/{agentId}/conversations/export
Authentication: Bearer API key with access to {agentId}.
| Query | Required | Constraints |
|---|---|---|
limit | No | Integer from 1 to 20; defaults to 20. |
cursor | No | Opaque cursor returned by the preceding page. Replay it unchanged. |
source | No | api_v2 (default), widget, or all. It may appear only once. |
Export uses the same conversation ordering and cursor contract as the list endpoint, but caps each page at 20 conversations. Each conversation includes all non-tool messages, ordered from oldest to newest.
curl 'https://your-domain.com/api/v2/agents/955f28f1-8515-40bb-802c-f3f730bf0343/conversations/export?source=api_v2' \ -H 'Authorization: Bearer YOUR_API_KEY'
Success: 200 OK
{
"data": [
{
"id": "b2mD4kL8pQ1sT6vX",
"title": "Where is my order?",
"createdAt": 1784332800,
"updatedAt": 1784332860,
"userId": "customer_123",
"source": "api_v2",
"status": "ongoing",
"messages": [
{
"id": "122",
"role": "user",
"parts": [{ "type": "text", "text": "Where is my order?" }],
"createdAt": 1784332800,
"feedback": null,
"metadata": null
}
]
}
],
"pagination": {
"cursor": null,
"hasMore": false,
"total": 1
}
}
Get a Conversation
Path: /api/v2/agents/{agentId}/conversations/{conversationId}
GET /api/v2/agents/{agentId}/conversations/{conversationId}
Authentication: Bearer API key with access to {agentId}.
| Query | Required | Constraints |
|---|---|---|
source | No | api_v2 (default), widget, or all. It may appear only once. |
The response includes the entire non-tool transcript, ordered from oldest to newest. This endpoint is not cursor-paginated; use the message-list endpoint for paged access to API v2 messages.
Success: 200 OK
{
"data": {
"id": "b2mD4kL8pQ1sT6vX",
"title": "Where is my order?",
"createdAt": 1784332800,
"updatedAt": 1784332860,
"userId": "customer_123",
"source": "api_v2",
"status": "ongoing",
"messages": [
{
"id": "122",
"role": "user",
"parts": [{ "type": "text", "text": "Where is my order?" }],
"createdAt": 1784332800,
"feedback": null,
"metadata": null
}
]
},
"pagination": {
"cursor": null,
"hasMore": false,
"total": 1
}
}
A missing conversation within the selected source returns 404 RESOURCE_NOT_FOUND.
List Messages
Path: /api/v2/agents/{agentId}/conversations/{conversationId}/messages
GET /api/v2/agents/{agentId}/conversations/{conversationId}/messages
Authentication: Bearer API key with access to {agentId}. The conversation must be an API v2 conversation.
| Query | Required | Constraints |
|---|---|---|
limit | No | Integer from 1 to 100; defaults to 20. |
cursor | No | Opaque cursor returned by the preceding page. Replay it unchanged. |
Message cursors are the one v2 pagination cursor whose server-side ID component is validated as a numeric string because messages use bigint IDs. Every other paginated v2 resource validates UUID IDs. Treat both forms as opaque; never construct or decode cursors. Messages within each returned page are ordered from oldest to newest.
Success: 200 OK
{
"data": [
{
"id": "122",
"role": "user",
"parts": [{ "type": "text", "text": "Where is my order?" }],
"createdAt": 1784332800,
"feedback": null,
"metadata": null
},
{
"id": "123",
"role": "assistant",
"parts": [{ "type": "text", "text": "Please share your order number." }],
"createdAt": 1784332860,
"feedback": "positive",
"metadata": null
}
],
"pagination": {
"cursor": null,
"hasMore": false,
"total": 2
}
}
A missing API v2 conversation returns 404 RESOURCE_NOT_FOUND; invalid limits and cursors return 400 VALIDATION_INVALID_BODY.
Retry an Assistant Reply
Path: /api/v2/agents/{agentId}/conversations/{conversationId}/retry
POST /api/v2/agents/{agentId}/conversations/{conversationId}/retry
Authentication: Bearer API key with access to {agentId}. The conversation must be an API v2 conversation.
| Body field | Required | Type and constraints |
|---|---|---|
messageId | Yes | String or number that converts to a positive integer. It must identify an AI assistant message in the conversation. |
stream | No | Boolean; defaults to true. |
Retry deletes the preceding user message, the selected assistant reply, and every later message, then replays that user text to regenerate the reply. If regeneration fails to persist, the deleted rows are restored.
curl -X POST 'https://your-domain.com/api/v2/agents/955f28f1-8515-40bb-802c-f3f730bf0343/conversations/b2mD4kL8pQ1sT6vX/retry' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{"messageId":"123","stream":false}'
Success: 200 OK. With stream: true, the response is a Server-Sent Events stream using the same event format as chat. With stream: false, the response is:
{
"data": {
"id": "124",
"role": "assistant",
"parts": [{ "type": "text", "text": "Here is a regenerated answer." }],
"metadata": {
"conversationId": "b2mD4kL8pQ1sT6vX",
"finishReason": "stop",
"usage": { "credits": 1 }
}
}
}
Malformed JSON returns 400 VALIDATION_INVALID_JSON. Invalid bodies return 400 VALIDATION_INVALID_BODY. See CHAT_RETRY_MESSAGE_NOT_FOUND, CHAT_RETRY_NO_USER_MESSAGE, RESOURCE_NOT_FOUND, and INTERNAL_SERVER_ERROR in the error catalog.
Submit a Tool Result
Path: /api/v2/agents/{agentId}/conversations/{conversationId}/tool-result
POST /api/v2/agents/{agentId}/conversations/{conversationId}/tool-result
Authentication: Bearer API key with access to {agentId}.
| Body field | Required | Type and constraints |
|---|---|---|
toolCallId | Yes | Nonempty string. |
output | Yes | Any JSON value. |
{
"toolCallId": "call_123",
"output": { "available": true }
}
Response: A matching pending action is claimed once and returns the assistant continuation as text/event-stream. Unknown or expired calls return 404; a competing or conflicting result returns 409.
Set or Clear Message Feedback
Path: /api/v2/agents/{agentId}/conversations/{conversationId}/messages/{messageId}/feedback
PATCH /api/v2/agents/{agentId}/conversations/{conversationId}/messages/{messageId}/feedback
Authentication: Bearer API key with access to {agentId}. The conversation must be an API v2 conversation.
{messageId} must convert to a positive integer and must identify an AI assistant message in the specified conversation.
| Body field | Required | Type and constraints |
|---|---|---|
feedback | Yes | positive, negative, or null. Use null to clear feedback. |
curl -X PATCH 'https://your-domain.com/api/v2/agents/955f28f1-8515-40bb-802c-f3f730bf0343/conversations/b2mD4kL8pQ1sT6vX/messages/123/feedback' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{"feedback":"positive"}'
Success: 200 OK
{
"data": {
"id": "123",
"role": "assistant",
"parts": [{ "type": "text", "text": "Please share your order number." }],
"createdAt": 1784332860,
"feedback": "positive",
"metadata": null
}
}
Malformed JSON returns 400 VALIDATION_INVALID_JSON; an invalid body returns 400 VALIDATION_INVALID_BODY; a missing conversation returns 404 RESOURCE_NOT_FOUND; a missing message returns 404 RESOURCE_MESSAGE_NOT_FOUND; and a non-AI-assistant target returns 422 RESOURCE_MESSAGE_NOT_ASSISTANT.
List Conversations for a User
Path: /api/v2/agents/{agentId}/users/{userId}/conversations
GET /api/v2/agents/{agentId}/users/{userId}/conversations
Authentication: Bearer API key with access to {agentId}.
{userId} must be 1 to 128 characters and may contain only letters, numbers, ., _, and -.
| Query | Required | Constraints |
|---|---|---|
limit | No | Integer from 1 to 100; defaults to 20. |
cursor | No | Opaque cursor returned by the preceding page. Replay it unchanged. |
source | No | Omit it or use api_v2. widget and all return 400 VALIDATION_INVALID_BODY; duplicate or invalid values also return 400. |
Only API v2 chat writes userId, so this endpoint returns API v2 conversations only. Its success response is the same paginated conversation-summary envelope as List Conversations.
curl 'https://your-domain.com/api/v2/agents/955f28f1-8515-40bb-802c-f3f730bf0343/users/customer_123/conversations' \ -H 'Authorization: Bearer YOUR_API_KEY'
Success: 200 OK. Invalid user IDs, limits, cursors, or source usage return 400 VALIDATION_INVALID_BODY.