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

# List Contacts: Paginate and Filter Your Workspace

> Retrieve a paginated list of contacts from your ChatbotX Workspace with optional keyword search, channel filters, inbox filters, and custom sort orders.

The List Contacts endpoint returns a paginated array of contact objects from your Workspace. You can narrow results using keyword search, filter by channel type, filter by specific inbox IDs, and control pagination and sort order. Each contact object includes full profile data, tags, custom fields, notes, inbox connections, and the most recent conversation.

<Info>
  **GET** `/api/v1/contacts`
</Info>

## Query Parameters

<ParamField query="page" type="integer">
  Page number to retrieve. Must be between `1` and `9007199254740991`. Defaults to `1`.
</ParamField>

<ParamField query="perPage" type="integer">
  Number of contacts per page. Must be between `1` and `9007199254740991`. Defaults to `20`.
</ParamField>

<ParamField query="sort" type="array of objects">
  Array of sort objects. Each object specifies a field and direction to sort by. Example: `[{"field": "createdAt", "order": "desc"}]`.
</ParamField>

<ParamField query="keyword" type="string">
  Free-text search string. Matches against contact name, email, and phone number.
</ParamField>

<ParamField query="contactFilter" type="object">
  Advanced filter object for filtering contacts by tag, custom field value, subscription status, and other criteria.
</ParamField>

<ParamField query="channels" type="array of strings">
  Filter contacts by the channels they are active on. Accepted values: `omnichannel`, `webchat`, `messenger`, `whatsapp`, `zalo`, `smtp`, `telegram`, `instagram`, `tiktok`.
</ParamField>

<ParamField query="inboxIds" type="array of strings">
  Filter contacts by specific inbox IDs. Each value must match the pattern `\d+`.
</ParamField>

## Code Examples

<CodeGroup>
  ```bash curl theme={null}
  curl --request GET \
    --url "https://app.chatbotx.io/api/v1/contacts?page=1&perPage=20" \
    --header "Authorization: Bearer YOUR_API_TOKEN"
  ```

  ```python Python theme={null}
  import requests

  url = "https://app.chatbotx.io/api/v1/contacts"
  headers = {"Authorization": "Bearer YOUR_API_TOKEN"}
  params = {"page": 1, "perPage": 20}

  response = requests.get(url, headers=headers, params=params)
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const options = {
    method: 'GET',
    headers: { Authorization: 'Bearer YOUR_API_TOKEN' }
  };

  fetch('https://app.chatbotx.io/api/v1/contacts?page=1&perPage=20', options)
    .then(res => res.json())
    .then(data => console.log(data))
    .catch(err => console.error(err));
  ```
</CodeGroup>

## Response Fields

<ResponseField name="data" type="array" required>
  Array of contact objects.

  <Expandable title="Contact object fields">
    <ResponseField name="id" type="string" required>Unique contact ID.</ResponseField>
    <ResponseField name="createdAt" type="string (date-time)" required>Timestamp when the contact was created.</ResponseField>
    <ResponseField name="updatedAt" type="string (date-time)" required>Timestamp of the last update.</ResponseField>
    <ResponseField name="avatar" type="string | null" required>URL of the contact's profile image.</ResponseField>
    <ResponseField name="phoneNumber" type="string | null" required>Contact's phone number.</ResponseField>
    <ResponseField name="email" type="string | null" required>Contact's email address.</ResponseField>
    <ResponseField name="emailVerified" type="boolean" required>Whether the email address has been verified.</ResponseField>
    <ResponseField name="emailOptIn" type="boolean" required>Whether the contact has opted in to email communications.</ResponseField>
    <ResponseField name="firstName" type="string | null" required>Contact's first name.</ResponseField>
    <ResponseField name="lastName" type="string | null" required>Contact's last name.</ResponseField>
    <ResponseField name="fullName" type="string | null" required>Contact's full name (computed from first + last).</ResponseField>
    <ResponseField name="gender" type="string | null">One of `male`, `female`, `unknown`.</ResponseField>
    <ResponseField name="lastReadAt" type="string (date-time) | null" required>When the contact last read a message.</ResponseField>
    <ResponseField name="ref" type="string | null" required>External reference identifier.</ResponseField>
    <ResponseField name="country" type="string | null" required>Contact's country.</ResponseField>
    <ResponseField name="state" type="string | null" required>Contact's state or region.</ResponseField>
    <ResponseField name="city" type="string | null" required>Contact's city.</ResponseField>
    <ResponseField name="locale" type="string | null" required>Contact's locale string (e.g., `en-US`).</ResponseField>
    <ResponseField name="timezone" type="string | null" required>Contact's timezone (e.g., `America/New_York`).</ResponseField>
    <ResponseField name="subscribedAt" type="string (date-time) | null" required>When the contact subscribed.</ResponseField>
    <ResponseField name="broadcastSubscribedAt" type="string (date-time) | null" required>When the contact subscribed to broadcasts.</ResponseField>
    <ResponseField name="blockedAt" type="string (date-time) | null" required>When the contact was blocked, or `null` if not blocked.</ResponseField>
    <ResponseField name="workspaceId" type="string" required>ID of the Workspace this contact belongs to.</ResponseField>
    <ResponseField name="contactCustomFields" type="array" required>Array of custom field value objects assigned to the contact.</ResponseField>
    <ResponseField name="tags" type="array" required>Array of tag objects applied to the contact.</ResponseField>
    <ResponseField name="contactNotes" type="array" required>Array of note objects attached to the contact.</ResponseField>
    <ResponseField name="contactInboxes" type="array" required>Array of inbox connection objects showing which channels the contact is active on.</ResponseField>
    <ResponseField name="conversation" type="object | null" required>The most recent conversation object for this contact, or `null`.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="pageCount" type="number" required>
  Total number of pages available based on the current `perPage` value.
</ResponseField>

## Example Response

```json theme={null}
{
  "data": [
    {
      "id": "clx1abc123",
      "createdAt": "2023-11-07T05:31:56Z",
      "updatedAt": "2023-11-07T05:31:56Z",
      "avatar": "https://example.com/avatar.jpg",
      "phoneNumber": "+84708123123",
      "email": "user@example.com",
      "emailVerified": true,
      "emailOptIn": true,
      "firstName": "Jane",
      "lastName": "Doe",
      "fullName": "Jane Doe",
      "lastReadAt": "2023-11-07T05:31:56Z",
      "ref": null,
      "country": "VN",
      "state": null,
      "city": "Ho Chi Minh City",
      "location": null,
      "locale": "vi-VN",
      "timezone": "Asia/Ho_Chi_Minh",
      "subscribedAt": "2023-11-07T05:31:56Z",
      "broadcastSubscribedAt": "2023-11-07T05:31:56Z",
      "blockedAt": null,
      "workspaceId": "ws123",
      "contactCustomFields": [],
      "tags": [
        {
          "id": "tag1",
          "name": "VIP",
          "workspaceId": "ws123",
          "createdAt": "2023-11-07T05:31:56Z",
          "updatedAt": "2023-11-07T05:31:56Z"
        }
      ],
      "contactNotes": [],
      "contactInboxes": [],
      "conversation": null
    }
  ],
  "pageCount": 5
}
```
