---
title: "List or find the contacts of a list"
method: GET
path: "/lists/list/{listId}/rows"
tags: ["List contacts"]
---

# List or find the contacts of a list

`GET /lists/list/{listId}/rows`

## Request

- Base URL: `https://api.emelia.io`
- URL: `https://api.emelia.io/lists/list/{listId}/rows`
- Auth: API key in header `Authorization`

Two modes.

**Exact lookup** (use it before an update or a delete): pass `email` OR `linkedinUrl`. The email is matched exactly but case-insensitively, the LinkedIn URL is compared as an exact string (a trailing slash or a missing `www` is a different URL). The search covers this list and the lists linked to it, returns up to 50 matches, ignores `search`, filters and pagination, and returns the full contact objects. The envelope then has `page: 1`, `pageSize` equal to the number of items (1 when empty) and no `customVariables`.

**Paginated listing**: without `email` and `linkedinUrl`, returns one page of the contacts stored in this list (not in linked lists), in creation order unless `sortBy` is set. Company rows without a contact (company-only lists) are included with `rowKind: "company_only"` and an id of the form `co:<companyId>` that the contact routes do not accept.

In paginated mode, when the list has column settings (every list created by this API or by the current app has them), each item only contains the fields of the columns visible in the list table of the app: a column hidden in the app disappears from the API response, `labels` is not returned and `company` carries no `companyId`. Use the exact lookup to get the full object.

Deep pages are expensive (the service sorts `page x pageSize` rows to serve one page): page through large lists with `pageSize=100` and avoid restarting from page 1, or use the export.

## Path parameters

- `listId` string, required

## Query parameters

- `email` string, email
- `linkedinUrl` string
- `page` integer
- `pageSize` integer
- `search` string
- `sortBy` 'firstName' | 'lastName' | 'fullName' | 'jobTitle' | 'email' | 'phone' | 'linkedinUrlProfile' | 'country' | 'city' | 'createdAt' | 'updatedAt'
- `sortDir` 'asc' | 'desc'
- `statuses` string
- `filters` string

## Response `200`

Contacts of the list.

- ListsContactsPage
  - `items` ListsContact[], required
    - `id` string, required: Contact id, or `co:<companyId>` for a company-only row.
    - `rowKind` 'lead' | 'company_only', required
    - `firstName` string
    - `lastName` string
    - `fullName` string: For a company-only row: the company name, or `-`.
    - `jobTitle` string
    - `gender` string, nullable: Free text as imported.
    - `email` string, nullable
    - `secondaryEmail` string, nullable
    - `phone` string, nullable
    - `mobilePhone` string, nullable
    - `linkedinUrlProfile` string, nullable
    - `twitterUrl` string, nullable
    - `country` string
    - `city` string
    - `seniority` string: Known levels are returned with spaces (for example `C LEVEL`).
    - `department` string
    - `bio` string
    - `profilePictureUrl` string, nullable
    - `emailVerified` 'verified' | 'unverified' | 'invalid' | 'unknown': Result of the last email verification; `unknown` when never verified.
    - `status` string: Latest engagement status written by the campaigns (for example `SENT`, `OPENED`, `MAIL_REPLIED`, `ACCEPTED`), empty when none.
    - `company` ListsContactCompany: Company of a contact. In the paginated listing only the visible columns are returned and `companyId` is absent.
      - `companyId` string
      - `companyName` string
      - `companyDomain` string
      - `websiteUrl` string
      - `industry` string
      - `companySize` string
      - `employeeCount` integer, nullable
      - `country` string
      - `city` string
      - `linkedinCompanyUrl` string
      - `logoUrl` string
      - `customFields` ListsCustomFieldValue[]
        - `technicalName` string, required
        - `displayName` string, required
        - `value` string, required: Always returned as a string.
    - `labels` object[]: Always empty. Not returned in the paginated listing.
    - `customFields` ListsCustomFieldValue[]
      - `technicalName` string, required
      - `displayName` string, required
      - `value` string, required: Always returned as a string.
    - `createdAt` string: ISO date, or empty string.
    - `updatedAt` string: ISO date, or empty string.
  - `total` integer, required: Total matching rows (paginated mode) or number of matches (exact lookup).
  - `page` integer, required
  - `pageSize` integer, required
  - `customVariables` object[]: Custom variables shown in this list or used by the returned rows. Absent in the exact lookup mode.
    - `technicalName` string, required
    - `displayName` string, required
    - `schema` 'lead' | 'company', required

## Other responses

- `401`: Missing, unknown or disabled API key, or the account of the key no longer exists. Note the body shape: `error` and `code`, not `message`.
- `404`: The list does not exist or belongs to another account.
- `422`: `email` and `linkedinUrl` sent together, or invalid `filters`.
- `500`: Unexpected server error. `error`, when present, is a raw internal message: do not parse it. Retry later.

---

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