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

# List Contacts

> Retrieve a paginated list of contacts for your account, with optional filtering by list and subscription status.

Returns all contacts associated with your account. Results are sorted by signup date in descending order (newest first). Use query parameters to filter by sending list or active/inactive subscription status.

## Query Parameters

<ParamField query="list_number" type="string">
  Filter contacts by sending list phone number. Must be in E.164 format (e.g., `+18005551234`).
</ParamField>

<ParamField query="active" type="string">
  Filter by subscription status. Pass `"true"` to return only active (subscribed) contacts, or `"false"` to return only inactive (unsubscribed) contacts. Omit to return all contacts regardless of status.
</ParamField>

<ParamField query="page" type="integer" default="1">
  Page number for pagination.
</ParamField>

<ParamField query="per_page" type="integer" default="50">
  Number of contacts per page. Maximum value is `1000`.
</ParamField>

## Response Fields

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

  <Expandable title="Contact object properties">
    <ResponseField name="phone_number" type="string">
      Contact phone number in E.164 format.
    </ResponseField>

    <ResponseField name="list_number" type="string">
      Sending list phone number in E.164 format.
    </ResponseField>

    <ResponseField name="list_id" type="integer">
      Unique identifier of the sending list.
    </ResponseField>

    <ResponseField name="active" type="boolean">
      Whether the contact is currently subscribed to the list.
    </ResponseField>

    <ResponseField name="signup_date" type="string">
      ISO 8601 UTC timestamp of when the contact was added.
    </ResponseField>

    <ResponseField name="signup_method" type="string">
      How the contact was added (e.g., `api`, `web_form`, `import`).
    </ResponseField>

    <ResponseField name="custom_fields" type="object">
      Key-value pairs of custom fields associated with the contact on this list.
    </ResponseField>

    <ResponseField name="carrier" type="string">
      Mobile carrier name.
    </ResponseField>

    <ResponseField name="line_type" type="string">
      Phone line type. Values: `mobile`, `landline`, `voip`, `toll_free`, `unknown`, `premium_rate`. `null` when the number carries no classification or was flagged as an invalid number (a `fake`/invalid-number verdict stores `line_type: null` and sets `is_valid` to `false`).
    </ResponseField>

    <ResponseField name="timezone" type="string">
      Contact's timezone based on phone number area code.
    </ResponseField>

    <ResponseField name="is_valid" type="boolean">
      Whether the phone number passed carrier validation. `null` if the number has never been validated for your account.
    </ResponseField>

    <ResponseField name="country" type="string">
      ISO 3166-1 alpha-2 country code. `null` if the number has never been validated for your account.
    </ResponseField>

    <ResponseField name="send_count" type="integer">
      Total number of messages sent to this contact on this list.
    </ResponseField>

    <ResponseField name="click_count" type="integer">
      Total number of link clicks from this contact on this list.
    </ResponseField>

    <ResponseField name="revenue_total" type="number">
      Total revenue attributed to this contact on this list.
    </ResponseField>

    <ResponseField name="conversion_count" type="integer">
      Total number of conversions attributed to this contact on this list.
    </ResponseField>

    <ResponseField name="last_sent_at" type="string">
      ISO 8601 UTC timestamp of the last message sent to this contact.
    </ResponseField>

    <ResponseField name="last_clicked_at" type="string">
      ISO 8601 UTC timestamp of the last click from this contact.
    </ResponseField>

    <ResponseField name="in_workflow" type="boolean">
      Whether the contact is currently enrolled in an active journey workflow.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="pagination" type="object">
  Pagination metadata.

  <Expandable title="Pagination properties">
    <ResponseField name="page" type="integer">
      Current page number.
    </ResponseField>

    <ResponseField name="per_page" type="integer">
      Number of items per page.
    </ResponseField>

    <ResponseField name="total" type="integer">
      Total number of contacts matching the query.
    </ResponseField>

    <ResponseField name="total_pages" type="integer">
      Total number of pages available.
    </ResponseField>
  </Expandable>
</ResponseField>

## Examples

<RequestExample>
  ```bash cURL theme={null}
  curl -X GET "https://api.tracklysms.com/api/v2/contacts?list_number=%2B18005551234&active=true&page=1&per_page=50" \
    -H "X-Api-Key: trk_your_api_key_here"
  ```

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

  response = requests.get(
      "https://api.tracklysms.com/api/v2/contacts",
      params={
          "list_number": "+18005551234",
          "active": "true",
          "page": 1,
          "per_page": 50
      },
      headers={"X-Api-Key": "trk_your_api_key_here"}
  )

  data = response.json()
  for contact in data["contacts"]:
      print(contact["phone_number"], contact["active"])
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    "https://api.tracklysms.com/api/v2/contacts?list_number=%2B18005551234&active=true&page=1&per_page=50",
    {
      method: "GET",
      headers: {
        "X-Api-Key": "trk_your_api_key_here",
      },
    }
  );

  const data = await response.json();
  console.log(data.contacts);
  console.log(data.pagination);
  ```
</RequestExample>

<ResponseExample>
  ```json 200 - Success theme={null}
  {
    "contacts": [
      {
        "phone_number": "+14155559876",
        "list_number": "+18005551234",
        "list_id": 42,
        "active": true,
        "signup_date": "2025-03-15T14:30:00",
        "signup_method": "api",
        "custom_fields": {
          "first_name": "Jane",
          "source": "landing_page_v2"
        },
        "carrier": "T-Mobile",
        "line_type": "mobile",
        "timezone": "America/Los_Angeles",
        "is_valid": true,
        "country": "US",
        "send_count": 12,
        "click_count": 3,
        "revenue_total": 47.50,
        "conversion_count": 1,
        "last_sent_at": "2025-04-01T18:00:00",
        "last_clicked_at": "2025-04-01T18:05:32",
        "in_workflow": false
      }
    ],
    "pagination": {
      "page": 1,
      "per_page": 50,
      "total": 1,
      "total_pages": 1
    }
  }
  ```

  ```json 401 - Unauthorized theme={null}
  {
    "error": "Invalid credentials",
    "code": "invalid_credentials"
  }
  ```
</ResponseExample>

## Error Codes

| HTTP Status | Error Code            | Description                                                                |
| ----------- | --------------------- | -------------------------------------------------------------------------- |
| 401         | `invalid_credentials` | Missing or invalid `X-Api-Key` header.                                     |
| 403         | `account_suspended`   | Your account is suspended. Resolve outstanding billing or contact support. |
| 429         | `rate_limited`        | Request throttled; retry with exponential backoff after the window resets. |
| 500         | `internal_error`      | An unexpected server error occurred.                                       |

## Next Steps

<CardGroup cols={2}>
  <Card title="Importing Contacts" icon="upload" href="/guides/contacts/importing">
    Import contacts in bulk
  </Card>

  <Card title="Create Audience" icon="users" href="/api-reference/v2/audiences/create-audience">
    Segment your contacts into audiences
  </Card>
</CardGroup>
