# Conversations

> Quickchat AI captures every conversation across all channels. These endpoints let you list and retrieve them.

Quickchat AI automatically captures and analyzes every conversation your AI Agent has across all channels — widget, Slack, WhatsApp, Telegram, and more. The Conversations API gives you programmatic access to this rich dataset for building custom dashboards, feeding downstream analytics pipelines, triggering CRM workflows, or integrating with your existing business intelligence tools.

Every conversation includes AI-powered analysis: **sentiment detection**, **topic classification**, **resolution tracking**, and **automatic flagging** of conversations that may need human attention. Combined with full message history, tracked link clicks, and custom metadata, you have everything you need to understand how visitors interact with your AI Agent.

Conversation data is spread across several endpoints:
- **List Conversations** — Basic info, visitor details, status. Use for dashboards, overviews, and filtered queries
- **Get Conversation Details** — Full info including `unified_analysis` (AI-generated insights) and `client_metadata`
- **Get Conversation Events** — Complete message history, tracked link clicks, and log entries
- **Get/Set Metadata** — Custom key-value data you attach to conversations (see [Conversation Metadata](/api-reference/conversations/conversation-metadata/))

## List Conversations

**Scope: read_all**

`GET https://app.quickchat.ai/v1/api_core/conversations`

**Query Parameters**

| Parameter | Description |
|-----------|-------------|
| `limit` <br/> integer | Items per page |
| `offset` <br/> integer | Items to skip |
| `query` <br/> string | Search by order number, UUID, or message text |
| `assignee_type` <br/> string | `"ai_assistant"`, `"human_operator"`, or `"unassigned"` |
| `source` <br/> string | `"widget"`, `"slack"`, `"telegram"`, `"whatsapp"`, etc. |
| `resolution_status` <br/> string | `"open"` or `"resolved"` |
| `created_timestamp_start_date` datetime | Filter by creation date (start) |
| `created_timestamp_end_date` datetime | Filter by creation date (end) |
| `last_message_at_start_date` datetime | Filter by last message date (start) |
| `last_message_at_end_date` datetime | Filter by last message date (end) |
| `most_frequent_language` <br/> string | Filter by detected language |

**Shell**

```shell
curl 'https://app.quickchat.ai/v1/api_core/conversations?limit=10&resolution_status=open' \
  -H 'Authorization: Bearer <API_TOKEN>'
```

**Python**

```python
import requests

response = requests.get(
    url="https://app.quickchat.ai/v1/api_core/conversations",
    headers={"Authorization": "Bearer <API_TOKEN>"},
    params={"limit": 10, "resolution_status": "open"},
)
data = response.json()
```

**Response** `200 OK`

```json
{
  "items": [
    {
      "id": "conv-uuid-1234",
      "ord": 42,
      "created_at": "2026-01-15T10:30:00Z",
      "last_message_at": "2026-01-15T10:35:00Z",
      "title": "Return policy question",
      "source": "widget",
      "terminated": false,
      "resolution_status": "open",
      "has_unread_messages": true,
      "supports_inbox_control": true,
      "last_message_content": "What is your return policy?",
      "most_frequent_language": "en",
      "assignee": {
        "type": "ai_assistant"
      },
      "visitor_name": "John",
      "visitor_email": "john@example.com",
      "visitor_phone_number": null,
      "visitor_label": null
    }
  ],
  "offset": 0,
  "limit": 10,
  "count": 42
}
```

| Field | Description |
|-------|-------------|
| `id` <br/> string | Conversation UUID |
| `ord` <br/> integer | Sequential conversation number |
| `created_at` <br/> string | Conversation creation timestamp |
| `last_message_at` <br/> string | Timestamp of the most recent message |
| `title` <br/> string | AI-generated conversation title |
| `source` <br/> string | Channel the conversation originated from (e.g., `"widget"`, `"slack"`, `"whatsapp"`) |
| `terminated` <br/> boolean | Whether the conversation has ended |
| `resolution_status` <br/> string | `"open"` or `"resolved"` |
| `has_unread_messages` <br/> boolean | Whether there are unread messages |
| `supports_inbox_control` <br/> boolean | Whether the conversation source supports inbox control (assign, handoff) |
| `last_message_content` <br/> string | Content of the last message in the conversation |
| `most_frequent_language` <br/> string | Most frequently detected language in the conversation |
| `assignee` <br/> object | Current assignee (`type`: `"ai_assistant"`, `"human_operator"`, or `"unassigned"`) |
| `visitor_name` <br/> string or null | Visitor's name (from pre-chat form or channel profile) |
| `visitor_email` <br/> string or null | Visitor's email address |
| `visitor_phone_number` <br/> string or null | Visitor's phone number |
| `visitor_label` <br/> string or null | Custom label assigned to the visitor |

## Get Conversation Details

**Scope: read_all**

`GET https://app.quickchat.ai/v1/api_core/conversations/{conversation_id}/`

**Shell**

```shell
curl https://app.quickchat.ai/v1/api_core/conversations/conv-uuid-1234/ \
  -H 'Authorization: Bearer <API_TOKEN>'
```

**Python**

```python
import requests

response = requests.get(
    url="https://app.quickchat.ai/v1/api_core/conversations/conv-uuid-1234/",
    headers={"Authorization": "Bearer <API_TOKEN>"},
)
data = response.json()
```

**Response** `200 OK`

```json
{
  "id": "conv-uuid-1234",
  "ord": 42,
  "created_at": "2026-01-15T10:30:00Z",
  "last_message_at": "2026-01-15T10:35:00Z",
  "title": "Return policy question",
  "source": "widget",
  "terminated": false,
  "resolution_status": "open",
  "has_unread_messages": true,
  "supports_inbox_control": true,
  "last_message_content": "What is your return policy?",
  "most_frequent_language": "en",
  "assignee": {
    "type": "ai_assistant"
  },
  "url": null,
  "client_metadata": {"userId": 12},
  "last_visitor_message_at": "2026-01-15T10:34:00Z",
  "unified_analysis": {
    "sentiment": "neutral",
    "resolution_status": "open",
    "topic": "Return policy",
    "is_flagged": false,
    "flag_reason": null
  },
  "visitor_name": "John",
  "visitor_email": "john@example.com",
  "visitor_phone_number": null,
  "visitor_label": null
}
```

The detail response includes all fields from the list response, plus:

| Field | Description |
|-------|-------------|
| `url` <br/> string or null | URL of the page where the conversation started (widget only) |
| `client_metadata` <br/> object or null | Custom key-value pairs attached to the conversation |
| `last_visitor_message_at` <br/> string | Timestamp of the last visitor message |
| `unified_analysis` <br/> object or null | AI-generated analysis of the conversation (see below) |

**`unified_analysis` fields:**

| Field | Description |
|-------|-------------|
| `sentiment` <br/> string | AI-detected conversation sentiment (e.g., `"positive"`, `"neutral"`, `"negative"`) |
| `resolution_status` <br/> string | AI-assessed resolution status (may differ from top-level `resolution_status`) |
| `topic` <br/> string | AI-detected conversation topic |
| `is_flagged` <br/> boolean | Whether the AI flagged this conversation for human review |
| `flag_reason` <br/> string or null | Reason the conversation was flagged |

:::note[resolution_status vs unified_analysis.resolution_status]
The top-level `resolution_status` field (`"open"` or `"resolved"`) is the canonical status set manually or by automation rules.

The `unified_analysis.resolution_status` is computed by AI analysis and may differ — for example, the AI might classify a conversation as resolved based on content analysis even though the top-level status is still `"open"`. Use the top-level field for filtering and workflow; use `unified_analysis` for analytics and insights.
:::

## Get Conversation Events

Retrieve all events (messages, tracked links, logs) for a conversation.

**Scope: read_all**

`GET https://app.quickchat.ai/v1/api_core/conversations/{conversation_id}/events/`

**Query Parameters**

| Parameter | Description |
|-----------|-------------|
| `limit` <br/> integer | Items per page |
| `offset` <br/> integer | Items to skip |

**Shell**

```shell
curl 'https://app.quickchat.ai/v1/api_core/conversations/conv-uuid-1234/events/?limit=20' \
  -H 'Authorization: Bearer <API_TOKEN>'
```

**Python**

```python
import requests

response = requests.get(
    url="https://app.quickchat.ai/v1/api_core/conversations/conv-uuid-1234/events/",
    headers={"Authorization": "Bearer <API_TOKEN>"},
    params={"limit": 20},
)
data = response.json()
```

**Response** `200 OK`

```json
{
  "items": [
    {
      "type": "message",
      "data": {
        "id": "msg-uuid-001",
        "ord": 1,
        "created_at": "2026-01-15T10:30:00Z",
        "content": "Hello! How can I help you today?",
        "author": "ai_assistant",
        "handoff_state": null,
        "message_insights": null,
        "feedback": null,
        "client_metadata": null,
        "sources_generated": [],
        "is_welcome": true,
        "attachments": []
      }
    },
    {
      "type": "message",
      "data": {
        "id": "msg-uuid-002",
        "ord": 2,
        "created_at": "2026-01-15T10:31:00Z",
        "content": "What is your return policy?",
        "author": "visitor",
        "handoff_state": null,
        "message_insights": null,
        "feedback": null,
        "client_metadata": null,
        "sources_generated": [],
        "is_welcome": false,
        "attachments": []
      }
    }
  ],
  "offset": 0,
  "limit": 20,
  "count": 2
}
```

**Event types:** `message`, `tracked_link`, `log`

**Author types:** `ai_assistant`, `visitor`, `human_operator`

| Field | Description |
|-------|-------------|
| `type` <br/> string | Event type: `"message"`, `"tracked_link"`, or `"log"` |
| `data.id` <br/> string | Message unique identifier |
| `data.ord` <br/> integer | Sequential message number |
| `data.created_at` <br/> string | Timestamp of the event |
| `data.content` <br/> string | Message content |
| `data.author` <br/> string | `"ai_assistant"`, `"visitor"`, or `"human_operator"` |
| `data.handoff_state` <br/> string or null | Handoff state if applicable |
| `data.message_insights` <br/> object or null | AI-generated message insights |
| `data.feedback` <br/> object or null | User feedback on the message |
| `data.client_metadata` <br/> object or null | Custom metadata attached to the message |
| `data.sources_generated` <br/> array | Knowledge Base articles the AI used when generating its response |
| `data.is_welcome` <br/> boolean | Whether this is a welcome message |
| `data.attachments` <br/> array | File attachments |

---
