Endpoints // Lists
Page through the members and Pending Intake of a List, or find members by your own identifier, for free.
Credits
Free.
Introduction
The List members endpoint returns one page of the rows of a List: the List Members (kind: "member"), and the lines no one matched, kept as Pending Intake (kind: "pending"). With externalId, it returns the members that carry that identifier of yours, so you can find the member behind a line of your CRM without keeping our ids.
This endpoint is free (0 credits). It reads what the List holds and never looks anyone up. It counts toward your per-minute rate limit like any other call.
The API key needs the lists permission (see API key management).
Authorization
| Name | Type | Required | Description |
|---|---|---|---|
apikey | string | Yes | Your API key from the developer dashboard. Pass it via Authorization: Bearer YOUR_API_KEY header. |
Request
The route is GET /v2/lists/:listId/members.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
listId | string | Yes | List id (UUID) |
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
kind | string | No | all (default) mixes members and Pending Intake by added date, members or pending returns one kind only |
externalId | string | No | Returns the members carrying this identifier of yours (1 to 200 characters) |
perPage | integer | No | Rows per page, from 1 to 1,000. Defaults to 100. |
cursor | string | No | The nextCursor of the previous page, sent with the same filters. A malformed cursor, or one sent with other filters, returns 400. |
Response structure
| Field | Type | Description |
|---|---|---|
success | boolean | true if the request was processed successfully |
error | null | Always null on success |
dataobjectOne page of rows
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
memberCount | number | List Members in the whole List |
pendingIntakeCount | number | Pending Intake lines in the whole List |
nextCursor | string | null | Send it back as cursor for the next page, null on the last page |
itemsobjectA row with kind: "member": a person or company the List holds
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
kind | string | member |
id | string | Member id (UUID), the one Remove members takes |
entityId | string | Person (prs_...) or company (com_...) id, the one the other endpoints return |
linkedinUrl | string | null | Profile or company page URL |
status | string | enriched when the List holds the member's profile or company details, which is the case of every member added from a Signal; profiled or identified for a member added from a Search in the app, with or without a stored profile |
fields | object | The fields the List shows for the member: name, headline, company, location, url, photo for a person; name, industry, location, url, websiteUrl, logo for a company. enrichment holds the enriched fields once a family was bought. A value your team typed over a cell in the app replaces the enriched one. |
addedAt | string | Date the member was added (ISO 8601) |
families | object | What the List holds for each data family, see below |
externalId | string | null | Your identifier for this member, null when none was sent. A member keeps the first one it received. |
familiesobjectData families, absent until a family was bought or looked for
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
profile | object | enrichedAt: when the profile was obtained, by the lookup that added the member or by the profile family (ISO 8601). dataAt, when present: the date of the data itself. |
company | object | enrichedAt: when the company details were obtained. dataAt, when present: the date of the data itself. |
contactEmail | object | status: found, not_found, error or not_attempted. With found, value is the email. source, when known: where it came from, signal:paste or signal:file for the email of an email Signal, manual for an email typed in the app. attemptedAt: when it was looked for. freshnessAt, when present: the date of the data. |
contactPhone | object | status: found, not_found, error or not_attempted. With found, value is the number and type its kind when the provider gives one. source, attemptedAt and freshnessAt as for contactEmail. |
itemsobjectA row with kind: "pending": a line no one matched
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
kind | string | pending |
id | string | Pending Intake id (UUID), the one pendingIds takes |
signal | object | The Signal as you sent it, with its externalId when you sent one |
source | string | paste or file |
addedAt | string | Date the line was kept (ISO 8601) |
fields | object | Values your team typed over the line in the app, by column (name, company, url, contactEmail...), {} otherwise |
quotas and metadata are the blocks of every V2 response: see Usage.
A List that does not exist in your workspace returns 404 LIST_NOT_FOUND, or 404 LISTS_NOT_ACTIVATED when the workspace has never had a List.
Code examples
Code Examples
curl "https://api.reversecontact.com/v2/lists/3f6c2a8e-1b4d-4f0a-9c7e-5d2b8a1e6f40/members?kind=members&perPage=500" \
-H "Authorization: Bearer YOUR_API_KEY"// Read every member of a List, one page at a time.
const listId = "3f6c2a8e-1b4d-4f0a-9c7e-5d2b8a1e6f40";
const members = [];
let cursor = null;
do {
const url = new URL(`https://api.reversecontact.com/v2/lists/${listId}/members`);
url.searchParams.set("kind", "members");
url.searchParams.set("perPage", "500");
if (cursor) url.searchParams.set("cursor", cursor);
const response = await fetch(url, { headers: { "Authorization": "Bearer YOUR_API_KEY" } });
const { data } = await response.json();
members.push(...data.items);
cursor = data.nextCursor;
} while (cursor);
console.log(`${members.length} members read`);import requests
# Find the member behind a line of your CRM.
list_id = "3f6c2a8e-1b4d-4f0a-9c7e-5d2b8a1e6f40"
response = requests.get(
f"https://api.reversecontact.com/v2/lists/{list_id}/members",
headers={"Authorization": "Bearer YOUR_API_KEY"},
params={"externalId": "crm-001"}
)
for member in response.json()["data"]["items"]:
print(member["id"], member["fields"].get("name"))Example response
Example Response
{
"success": true,
"data": {
"items": [
{
"kind": "member",
"id": "9b1e4c7a-2d3f-4e8a-b6c5-0a1f2e3d4c5b",
"entityId": "prs_01jbd5vewyenebxgaz869ffe5t",
"linkedinUrl": "https://www.social.com/in/janedoe",
"status": "enriched",
"fields": {
"name": "Jane Doe",
"headline": "VP Sales at Acme Corp",
"company": "Acme Corp",
"location": { "country": "France" },
"url": "https://www.social.com/in/janedoe",
"status": "enriched"
},
"addedAt": "2026-10-28T09:15:31.000Z",
"families": {
"profile": { "enrichedAt": "2026-10-28T09:15:31.000Z" },
"contactEmail": {
"status": "found",
"value": "jane.doe@acme.com",
"attemptedAt": "2026-10-28T09:16:02.000Z"
}
},
"externalId": "crm-001"
}
],
"memberCount": 1240,
"pendingIntakeCount": 18,
"nextCursor": "eyJ2IjoxLCJhZnRlciI6IjIwMjYtMTAtMjhUMDk6MTU6MzEifQ"
},
"error": null,
"quotas": {
"creditsConsumed": 0,
"workspace": {
"id": "ws_abc123",
"credits": { "total": 10000, "used": 4521, "left": 5479 }
}
},
"metadata": {
"requestId": "req_m1e2m3b4e5r6",
"executionTimeMs": 47
}
}