Endpoints // Search
People lookalike
NewFind the people who look like one seed profile, given by Social URL or Reverse Contact person id.
Introduction
The People Lookalike endpoint returns the people who look like one seed profile. You name the seed by its Social profile URL or by its Reverse Contact person id (prs_...), and the search is built from what the seed does today: its current function and sub-function, with the time it has spent in them when it is known, its current seniority and its location (country and city). The seed itself is never part of the results.
Every result is a complete profile, the same shape People search returns, with the same cursor pagination and the same price: 1 credit per profile delivered. Results are drawn from our cache-based search index. This endpoint never triggers a live fetch.
Use it when you know one good profile and want more people like it. To choose the criteria yourself, use People search.
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 body
Provide exactly one seed: url or id. Sending both returns HTTP 422, because a lookalike is built from a single profile.
| Name | Type | Required | Description |
|---|---|---|---|
url | string | Conditional | Public Social profile URL of the seed (e.g. https://social.com/in/janedoe). Required unless id is given. |
id | string | Conditional | Reverse Contact person id of the seed (e.g. prs_01jbd5vewyenebxgaz869ffe5t), as returned in the id field of any person response. Required unless url is given. |
cursor | string | No | Opaque cursor returned as metadata.nextCursor; request the next page |
perPage | number | No | Profiles per page (1 to 100, default 25) |
No filters: the search criteria come from the seed, so the request takes no search filter. Any other field, such as
locationorcurrentSeniority, returns HTTP422witherror.codeLOOKALIKE_FILTERS_NOT_SUPPORTEDand the offending fields inerror.details.fields, and costs 0 credits. A filter is refused rather than ignored, because an ignored filter would return results you did not ask for.
Seed checks: the seed must already be in our search index. A profile that is not indexed yet returns HTTP
404and costs 0 credits: no lookalike can be built from it, so try another seed. Anidthat matches no profile returns HTTP422witherror.codeVALIDATION_ERROR, and a seed under an active data subject request (GDPR/CCPA) returns HTTP451witherror.codeDATA_SUBJECT_BLOCKED. Neither costs credits.
Pagination and credits
People lookalike uses cursor pagination, like People search. Each response returns up to perPage profiles (1 to 100, default 25) and a metadata.nextCursor value. To get the following page, send the same seed again with that value as cursor; nextCursor is null on the last page. The cursor is opaque: send it back unchanged, without parsing or altering it. There is no page parameter.
perPage above 100 returns HTTP 422 with error.code PAGINATION_LIMIT_EXCEEDED, and a perPage that is not a whole number returns HTTP 422 with error.code INVALID_PAGINATION.
People lookalike costs 1 credit per profile delivered. Compliance-blocked profiles are removed before the response and are not billed. A page that returns 25 profiles costs 25 credits, and a page that returns no profile costs 0 credits. Lower perPage to control how many credits a single request can spend.
Response structure
Note: This endpoint uses a nested envelope. The top-level V2
datafield wraps an inner search payload that contains the actual results array (data.data) and the pagination info (data.metadata). See the example response for the exact shape.
| Field | Type | Description |
|---|---|---|
success | boolean | true if the request was processed successfully |
error | null | Always null on success |
data.dataobject[]Full profiles of the people who look like the seed, wrapped under data.data in the envelope. The seed is never among them. Empty array if no one matches. Each item is the same full profile shape as the Profile endpoint; the table below lists its main fields.
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
id | string | Reverse Contact person id (prs_...). Send it back as id to use this profile as the next seed |
publicId | string | Social public identifier (the /in/xxx slug) |
memberId | string | null | Upstream member identifier when available |
linkedinUrl | string | Full Social profile URL |
firstName | string | null | First name |
lastName | string | null | Last name |
headline | string | null | Profile headline |
summary | string | null | Profile summary |
isOpenToWork | boolean | Whether the profile is flagged open to work |
hasPremium | boolean | Whether the profile has Social Premium |
hasVerificationBadge | boolean | Whether the profile has a verification badge |
photoUrl | string | null | Profile photo URL |
creationDate | string | null | When the profile was created (ISO 8601) |
followersCount | number | null | Follower count |
connectionsCount | number | null | Connection count |
currentPosition | object | null | Current job position (how it is chosen) |
experience | array | Professional experiences, same shape as currentPosition |
education | array | Education history |
skills | string | Skills listed on the profile |
languages | array | Spoken languages |
certifications | array | Professional certifications |
recommendations | array | Received recommendations |
locationobjectGeographic location (null if unknown)
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
city | string | null | City |
state | string | null | State or region |
country | string | null | Country name |
countryCode | string | null | ISO country code (e.g. "US") |
rawLocation | string | null | Raw location string as displayed on the profile |
currentPositionobjectCurrent job position (null if no current position)
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
title | string | null | Job title |
description | string | null | Position description |
contractType | string | null | Contract type |
companyName | string | null | Company name |
companyLinkedinId | string | null | Company Social identifier |
companyUrl | string | null | Company Social URL |
companyLocation | string | null | Company location |
companyLogoUrl | string | null | Company logo URL |
startEndDate | object | null | Period boundaries (DateRange) |
data.metadataobjectPagination metadata wrapped under data.metadata in the envelope.
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
perPage | number | Profiles requested per page |
count | number | Profiles returned in this page |
nextCursor | string | null | Opaque cursor for the next page, null on the last page |
quotasobjectCredits and rate limit usage after this request
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
creditsConsumed | number | Credits consumed by this request |
workspaceobjectWorkspace-level limits
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
id | string | Your workspace identifier |
hasUnlimitedCredits | boolean | Whether workspace credits are unlimited |
allowDailyOvercost | boolean | Whether the workspace may exceed its daily cap |
creditsobjectCredit balance
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
total | number | Total credits in your plan |
used | number | Credits consumed so far |
left | number | Remaining credits |
dailyLimitobjectDaily request limit (null if not configured)
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
limit | number | Maximum requests per day |
used | number | Requests made today |
left | number | Remaining requests today |
nextReset | string | When the daily window resets (ISO 8601) |
minuteRateLimitobjectPer-minute rate limit
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
limit | number | Maximum requests per minute |
used | number | Requests made in the current minute |
left | number | Remaining requests in the current minute |
nextReset | string | When the minute window resets (ISO 8601) |
keyobjectAPI key-level limits (null when request is from dashboard)
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
id | string | API key identifier |
dailyLimitobjectDaily limit for this key (null if not configured)
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
limit | number | Maximum requests per day |
used | number | Requests made today |
left | number | Remaining requests today |
nextReset | string | When the daily window resets (ISO 8601) |
minuteRateLimitobjectMinute rate limit for this key
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
limit | number | Maximum requests per minute |
used | number | Requests made in the current minute |
left | number | Remaining requests in the current minute |
nextReset | string | When the minute window resets (ISO 8601) |
metadataobjectRequest tracking information (not to be confused with data.metadata which is pagination)
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
requestId | string | Unique identifier for this request |
executionTimeMs | number | Total execution time in milliseconds |
Code examples
Code Examples
curl -X POST https://api.reversecontact.com/v2/search/people/lookalike \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://social.com/in/janedoe",
"perPage": 25
}'const lookalikePage = async (cursor) => {
const response = await fetch("https://api.reversecontact.com/v2/search/people/lookalike", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
// The seed travels with every page, the cursor only from the second one.
body: JSON.stringify({
id: "prs_01jbd5vewyenebxgaz869ffe5t",
perPage: 25,
cursor
})
});
return response.json();
};
const firstPage = await lookalikePage();
const profiles = firstPage.data.data;
const { count, nextCursor } = firstPage.data.metadata;
console.log(`Got ${count} lookalikes, credits used: ${firstPage.quotas.creditsConsumed}`);
if (nextCursor) {
const secondPage = await lookalikePage(nextCursor);
profiles.push(...secondPage.data.data);
}import requests
response = requests.post(
"https://api.reversecontact.com/v2/search/people/lookalike",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
json={
"id": "prs_01jbd5vewyenebxgaz869ffe5t",
"perPage": 25
}
)
payload = response.json()
profiles = payload["data"]["data"]
metadata = payload["data"]["metadata"]
print(f"Got {metadata['count']} lookalikes, next cursor: {metadata['nextCursor']}")Example response
Example Response
{
"success": true,
"data": {
"data": [
{
"id": "prs_01h2x3y4z5a6b7c8d9e0f1g2h3",
"publicId": "janedoe",
"memberId": "ACoAAB12345",
"linkedinUrl": "https://www.social.com/in/janedoe",
"firstName": "Jane",
"lastName": "Doe",
"headline": "VP of Marketing at Acme Corp | Demand Gen & Brand",
"summary": "Experienced marketing leader with 15+ years driving growth for B2B SaaS companies.",
"pronoun": "she/her",
"isOpenToWork": false,
"hasPremium": true,
"hasVerificationBadge": true,
"isInRemembrance": false,
"photoUrl": "https://media.licdn.com/dms/image/v2/D5603AQ.../profile-photo.jpg",
"backgroundUrl": null,
"creationDate": "2009-03-15T00:00:00.000Z",
"followersCount": 12480,
"connectionsCount": 500,
"location": {
"city": "San Francisco",
"state": "California",
"country": "United States of America",
"countryCode": "US",
"rawLocation": "San Francisco Bay Area"
},
"currentPosition": {
"title": "VP of Marketing",
"description": "Leading a team of 25 marketers across demand gen, product marketing, and brand.",
"contractType": "Full-time",
"companyName": "Acme Corp",
"companyLinkedinId": "12345678",
"companyUrl": "https://www.social.com/company/acme-corp",
"companyLocation": "San Francisco, CA",
"companyLogoUrl": "https://media.licdn.com/dms/image/v2/C4D0BAQ.../logo.jpg",
"startEndDate": {
"start": "2021-06-01T00:00:00.000Z",
"end": null
}
},
"experience": [
{
"title": "VP of Marketing",
"description": "Leading a team of 25 marketers across demand gen, product marketing, and brand.",
"contractType": "Full-time",
"companyName": "Acme Corp",
"companyLinkedinId": "12345678",
"companyUrl": "https://www.social.com/company/acme-corp",
"companyLocation": "San Francisco, CA",
"companyLogoUrl": "https://media.licdn.com/dms/image/v2/C4D0BAQ.../logo.jpg",
"startEndDate": {
"start": "2021-06-01T00:00:00.000Z",
"end": null
}
},
{
"title": "Director of Marketing",
"description": "Built the marketing function from scratch. Scaled from 0 to $5M ARR.",
"contractType": "Full-time",
"companyName": "Startup Inc",
"companyLinkedinId": "98765432",
"companyUrl": "https://www.social.com/company/startup-inc",
"companyLocation": "Remote",
"companyLogoUrl": null,
"startEndDate": {
"start": "2018-01-01T00:00:00.000Z",
"end": "2021-05-31T00:00:00.000Z"
}
}
],
"education": [
{
"degreeName": "MBA",
"fieldOfStudy": "Marketing",
"description": null,
"grade": null,
"schoolName": "Stanford Graduate School of Business",
"schoolUrl": "https://www.social.com/school/stanford-gsb",
"schoolLogoUrl": "https://media.licdn.com/dms/image/v2/C4D0BAQ.../logo.jpg",
"startEndDate": {
"start": "2012-09-01T00:00:00.000Z",
"end": "2014-06-15T00:00:00.000Z"
}
}
],
"skills": ["Marketing Strategy", "B2B SaaS", "Demand Generation", "Product Marketing"],
"languages": [{ "language": "English", "proficiency": "Native or bilingual" }],
"certifications": [],
"recommendations": [],
"testScores": []
}
],
"metadata": {
"perPage": 25,
"count": 1,
"nextCursor": "cur_01j9x8r5n3a9c7e5g1b3d9f7"
}
},
"error": null,
"metadata": {
"requestId": "req_l0o1k2a3l4i5",
"executionTimeMs": 520
},
"quotas": {
"creditsConsumed": 1,
"workspace": {
"id": "ws_abc123",
"credits": {
"total": 10000,
"used": 4522,
"left": 5478
},
"dailyLimit": null,
"minuteRateLimit": {
"limit": 60,
"used": 5,
"left": 55,
"nextReset": "2026-09-14T14:16:00.000Z"
},
"hasUnlimitedCredits": false,
"allowDailyOvercost": false
},
"key": {
"id": "key_abc123",
"dailyLimit": null,
"minuteRateLimit": {
"limit": 60,
"used": 5,
"left": 55,
"nextReset": "2026-09-14T14:16:00.000Z"
}
}
}
}