> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tryverso.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# List Conversations

> Retrieve imported conversations for a connection.

## `GET /api/conversations?connectionId=`

Lists imported conversations for a given connection, with pagination. Results are ordered by `update_time` descending (newest first).

## Request

**Headers**

| Header | Value |
| - | - |
| `Authorization` | `Bearer YOUR_APP_SECRET` |

**Query parameters**

| Param | Type | Required | Default | Description |
| - | - | - | - | - |
| `connectionId` | `string` | Yes | — | The connection UUID |
| `limit` | `number` | No | `50` | Max results per page (capped at 100) |
| `offset` | `number` | No | `0` | Number of results to skip |

**Example**

```bash theme={null}
curl -s https://connect.tryverso.ai/api/conversations \
  -H "Authorization: Bearer $VERSO_SECRET" \
  -G -d "connectionId=CONNECTION_ID" \
  -d "limit=50" \
  -d "offset=0"
```

## Response

```json theme={null}
{
  "conversations": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "external_id": "chatgpt-abc123",
      "title": "Help me build a REST API",
      "payload": {
        "title": "Help me build a REST API",
        "messages": [
          {
            "role": "user",
            "content": "I need a REST API for managing tasks...",
            "timestamp": "2026-09-20T10:00:00Z"
          },
          {
            "role": "assistant",
            "content": "I'll help you build a task management API...",
            "timestamp": "2026-09-20T10:00:05Z"
          }
        ]
      },
      "update_time": "2026-09-20T10:05:00Z"
    }
  ],
  "total": 142,
  "limit": 50,
  "offset": 0
}
```

| Field | Type | Description |
| - | - | - |
| `conversations` | `array` | List of conversation objects |
| `conversations[].id` | `string` | Internal Verso UUID |
| `conversations[].external_id` | `string` | Provider's conversation ID |
| `conversations[].title` | `string?` | Conversation title |
| `conversations[].payload` | `object?` | Full conversation data with `title` and `messages` array |
| `conversations[].payload.messages` | `array` | Normalized messages: `{ role, content, timestamp }` |
| `conversations[].update_time` | `string?` | Last update time from the provider (ISO 8601) |
| `total` | `number` | Total conversation count for this connection |
| `limit` | `number` | Requested page size |
| `offset` | `number` | Current offset |

### Message format

Each message in `payload.messages` has this structure:

| Field | Type | Values |
| - | - | - |
| `role` | `string` | `user`, `assistant`, `system`, or `tool` |
| `content` | `string` | Message text |
| `timestamp` | `string?` | ISO 8601 timestamp (null if unavailable) |

### Pagination

Use `limit` and `offset` to paginate through results. When `offset + conversations.length >= total`, you've reached the end.

```typescript theme={null}
async function fetchAll(connectionId: string, secret: string) {
  const all = [];
  let offset = 0;
  const limit = 100; // max allowed

  while (true) {
    const res = await fetch(
      `https://connect.tryverso.ai/api/conversations?connectionId=${connectionId}&limit=${limit}&offset=${offset}`,
      { headers: { Authorization: `Bearer ${secret}` } },
    );
    const data = await res.json();
    all.push(...data.conversations);
    if (all.length >= data.total) break;
    offset += limit;
  }

  return all;
}
```

## Errors

| Status | Error | Cause |
| - | - | - |
| 400 | `Missing connectionId parameter` | `connectionId` query param not provided |
| 401 | `Missing Authorization header` | Missing `Bearer` prefix |
| 401 | `Invalid API key` | Wrong or missing app secret |
| 404 | `Connection not found` | Connection doesn't exist or belongs to a different app |
| 429 | `Rate limit exceeded` | Exceeded 60 requests/min |
