# List contacts

`GET /v1/contacts`

Requires an API key with the `contacts:read` scope. [About keys and scopes](/docs/api/authentication)

Returns contacts in this organization. Filter by `email` to look up a single address; it is matched trimmed and without case. Filter by `externalId` to find the contact carrying your own id; it is matched exactly. Use `q` to search instead: it matches any part of the email address or name, ignoring case. `consent`, `suppressed`, `groupId`, `segmentId` and `createdAfter` narrow the list and combine with each other and with `q`; an unknown group or segment is a 404. Each item lists the groups it is in (`groupIds`). `meta.total` counts every contact matching the filters, up to 10000: beyond that it reports the cap and `meta.totalExact` is `false`; both are counted on the first page only (null with a `cursor`). Results are newest first and cursor-paginated: pass `meta.pagination.nextCursor` back as `cursor` until it comes back `null`. The cursor is opaque — do not construct or parse one.

## Query parameters

- `limit` (integer, optional, min > 0, max 100, default `20`)
- `cursor` (string, optional, 1–2048 characters)
- `email` (string, optional) — Exact match on the address, trimmed, without case.
- `q` (string, optional, 1–100 characters) — Searches any part of the email address or name, ignoring case.
- `externalId` (string, optional, 1–255 characters) — Your own id for the contact, as set with identify; matched exactly.
- `consent` (string, optional) — Comma-separated channels, e.g. `email,push`: consent granted on each.
- `suppressed` (string, optional, one of `true`, `false`) — Whether email to the contact, or to its address, is suppressed.
- `groupId` (string, optional, uuid) — Only members of this group.
- `segmentId` (string, optional, uuid) — The segment's members as of its last background sweep.
- `createdAfter` (string, optional, date-time) — Created at or after this time.

## Returns

Returns `200 OK` with a list of `ContactListItem` objects in `data`, and the next page's cursor in `meta` (see [pagination](/docs/api/pagination)). Otherwise returns an error; [Errors](/docs/api/errors) lists every code and which to retry.

- `id` (string, required, uuid)
- `externalId` (string | null, required) — Your own id for the contact, if set.
- `email` (string | null, required, email)
- `firstName` (string | null, required)
- `lastName` (string | null, required)
- `phone` (string | null, required) — Phone number in E.164 format.
- `timezone` (string | null, required) — IANA timezone, e.g. `Europe/London`.
- `country` (string | null, required) — ISO 3166-1 alpha-2 code: as written, or inferred from the phone, else the timezone.
- `dates` (object, required) — Named calendar dates, e.g. `birthday`, as `YYYY-MM-DD` or `--MM-DD`.
- `attributes` (object, required) — Custom attributes, keyed by attribute name.
- `emailConsent` (boolean, required) — Whether the contact has consented to email.
- `pushConsent` (boolean, required) — Whether the contact has consented to push.
- `createdAt` (string, required, date-time)
- `updatedAt` (string, required, date-time)
- `emailSuppression` (object, required)
  - `suppressed` (boolean, required) — Whether email to this contact is blocked.
  - `reason` (string | null, required) — Why email to this contact is suppressed: `bounced`, `complained`, `complained_transactional`, `unsubscribed`, `manual`, `imported`, or `other_workspace` (a bounce or complaint in another workspace with the same owner or partner).
- `groupIds` (string[], required) — Ids of the groups the contact is in.

## Example

```bash
curl https://api.kirora.io/v1/contacts \
  -H "Authorization: Bearer $KIRORA_API_KEY"
```

Response `200`:

```json
{
  "data": [
    {
      "id": "018f2a4e-6b1c-7d3e-9f40-37386ae05a6b",
      "externalId": "user_8812",
      "email": "amaka@juniperkitchen.com",
      "firstName": "Amaka",
      "lastName": "Eze",
      "phone": "+447700900123",
      "timezone": "Europe/London",
      "country": "GB",
      "dates": {},
      "attributes": {},
      "emailConsent": true,
      "pushConsent": true,
      "createdAt": "2030-03-14T09:30:00Z",
      "updatedAt": "2030-03-14T09:30:00Z",
      "emailSuppression": {
        "suppressed": true,
        "reason": "reason_example"
      },
      "groupIds": [
        "018f2a4e-6b1c-7d3e-9f40-b0a20d965a6b"
      ]
    }
  ],
  "meta": {
    "pagination": {
      "limit": 1,
      "nextCursor": "nextCursor_example"
    },
    "total": 0,
    "totalExact": true
  }
}
```
