---
title: "List contacts"
method: GET
path: "/v1/contacts"
tags: ["Contacts"]
---

# List contacts

`GET /v1/contacts`

## Request

- Base URL: `https://api.automatedclientacquisition.com`
- URL: `https://api.automatedclientacquisition.com/v1/contacts`
- Auth: HTTP bearer

List contacts in your organization, newest-agnostic and keyset-paginated.

Follow `next_cursor` until `has_more` is false to walk the whole set.
Pagination is stable under concurrent writes, which OFFSET is not.

> **Ordering is by `id`, not by date.** `crm_contacts` is past five million
> rows and the only organization-scoped index that can serve this is
> `(organization_id, id)`. Sorting by `created_at` would fall back to a heap
> scan and time out on large organizations. If you need "everything changed
> since X", ask — that needs an index we haven't added yet.

Filters are restricted to indexed columns for the same reason. Combining
several is fine.

## Query parameters

- `limit` integer
- `cursor` string
- `email` string
- `tag` string
- `company` string
- `status` string
- `source` string
- `stage_id` string, uuid
- `owner_user_id` string, uuid

## Response `200`

A page of contacts.

- object
  - `success` boolean
  - `data` Contact[]
    - `id` string, uuid
    - `display_name` string
    - `first_name` string, nullable
    - `last_name` string, nullable
    - `primary_email` string, nullable
    - `primary_phone` string, nullable
    - `primary_linkedin_url` string, nullable
    - `company` string, nullable
    - `company_website` string, nullable
    - `job_title` string, nullable
    - `city` string, nullable
    - `state` string, nullable
    - `country` string, nullable
    - `tags` string[], nullable
    - `status` string
    - `source` string, nullable
    - `lead_score` number, nullable
    - `stage_id` string, uuid, nullable
    - `pipeline_id` string, uuid, nullable
    - `owner_user_id` string, uuid, nullable
    - `custom_fields` object, nullable
    - `created_at` string, date-time
    - `updated_at` string, date-time, nullable
  - `has_more` boolean: Whether another page exists.
  - `next_cursor` string, nullable: Pass as `cursor` to fetch the next page. Null on the last page.

## Other responses

- `400`: Malformed or invalid body. Do not retry — it will fail identically.
- `401`: Missing, invalid or revoked token.
- `500`: Something broke on our side. Safe to retry with backoff.

---

[API](https://skmtc.dev/automatedclientacquisition/apis/aca-api.md) · [All operations](https://skmtc.dev/automatedclientacquisition/apis/aca-api/llms.txt) · [OpenAPI document](https://skmtc.dev/automatedclientacquisition/apis/aca-api/revisions/8f3e3b141311?raw)
