## List chats

**get** `/v1/chats`

Lists the brand's chats, most recently active first. A chat moves to the
front when its latest event is applied.

The page is a keyset, not an offset: pass the previous page's
`next_cursor` back verbatim. A cursor this API did not issue — including
an empty one — is refused rather than treated as the beginning, so a
paging loop cannot silently restart.

**A walk of this list is not a snapshot, and the gap is one-directional.**
The order is activity and activity only ever moves a chat toward the
front, so a chat that receives a message while you are paging jumps
ABOVE your cursor and is not returned again: on a busy account, a full
walk silently omits the conversations that were active during it. It
never returns one twice.

That is a property of ordering by activity, so plan around it rather
than against it: the chats you missed are exactly the chats that just
had traffic, which `GET /v1/streams/events` announces as it happens and
`GET /v1/chats/{chat}/events` reads back in full. Reconcile with those
two, not by walking the list again. Within one chat there is no such
gap — the transcript's order is the journal's own sequence and never
moves.

### Query Parameters

- `cursor: optional string`

  Cursor from a previous page's `next_cursor`.

- `limit: optional number`

  Page size. The bounds are in this parameter's schema, not only in this sentence — a value outside them is refused, never clamped.

### Returns

- `ChatPage object { data, has_more, next_cursor }`

  A page of chats.

  - `data: array of Chat`

    - `id: string`

      The chat's id.

    - `created_at: string`

    - `customer: string`

      Customer address as an opaque identifier.

    - `customer_window: object { expires_at, state, source }`

      The customer service window — first-class state on every chat read. Only
      `template` parts are sendable while it is closed.

      - `expires_at: string`

        When the open window expires. `null` when no window has ever opened.

      - `state: string`

        `open` or `closed`.

      - `source: optional string`

        What opened the current window: `customer_message`, or `free_entry_point` for ad-sourced windows. Absent when no window has ever opened.

    - `phone_number_id: string`

      The id of the sending number this chat is pinned to.

    - `updated_at: string`

      When the chat last changed — a new event moves it.

    - `from: optional string`

      The number this conversation sends from, in E.164 (leading `+`). This is
      the value to pass back as a send's `from` to address this exact
      conversation. Absent only if the number is no longer one of yours.

  - `has_more: boolean`

    True when another page exists — pass `next_cursor` to fetch it.

  - `next_cursor: optional string`

    Opaque cursor for the next page; present when `has_more` is true.

### Example

```http
curl https://whatsapp.messages.api.linqapp.com/v1/chats \
    -H "Authorization: Bearer $LINQ_WHATSAPP_API_KEY"
```

#### Response

```json
{
  "data": [
    {
      "id": "id",
      "created_at": "2019-12-27T18:11:19.117Z",
      "customer": "customer",
      "customer_window": {
        "expires_at": "2019-12-27T18:11:19.117Z",
        "state": "state",
        "source": "source"
      },
      "phone_number_id": "phone_number_id",
      "updated_at": "2019-12-27T18:11:19.117Z",
      "from": "from"
    }
  ],
  "has_more": true,
  "next_cursor": "next_cursor"
}
```
