# People search

> Search the database for people with filters and get full profiles back with cursor pagination.

## Introduction

The People Search endpoint returns full person profiles matching a combination of filters. All filters are optional and combined with **AND** logic. Results are drawn from our cache-based search index. This endpoint never triggers a live fetch.

Every result is a complete profile, the same shape the [Profile](https://docs.reversecontact.com/endpoints/fetch-profile) endpoint returns, so you do not need a second call to get the full data of a hit. Use the free [People search count](https://docs.reversecontact.com/endpoints/search-people-count) endpoint to check how many profiles match before you spend credits.

> Coming from `POST /v2/search/persons`? See [Migrating people search from persons to people](https://docs.reversecontact.com/guides/migrating-search-persons-to-people).

## 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

All filters are **optional** and combined with **AND** logic. Scalar filters live in the table below; the nested-object filters (`followersCount`, `currentCompanyEmployeeCountRange`, `totalExperienceMonths`, `location`, `experience`) are documented as expandable field items right after, and pagination (`cursor`, `perPage`) closes the section.

| Name                       | Type               | Required | Description                                                          |
| -------------------------- | ------------------ | -------- | -------------------------------------------------------------------- |
| `firstName`                | string             | No       | Filter by first name                                                 |
| `lastName`                 | string             | No       | Filter by last name                                                  |
| `headline`                 | string             | No       | Match keywords found in the profile headline                         |
| `email`                    | string             | No       | Filter by email address                                              |
| `isOpenToWork`             | boolean            | No       | Restrict to profiles flagged open-to-work                            |
| `isCurrentlyEmployed`      | boolean            | No       | Restrict to profiles that have a current employer                    |
| `isPremium`                | boolean            | No       | Restrict to Social Premium members                                   |
| `isVerified`               | boolean            | No       | Restrict to profiles with a verification badge                       |
| `currentPositionTitle`     | string \| string[] | No       | Current position title, or array of titles: a person matches if their current title matches any of them |
| `excludeCurrentPositionTitle` | string \| string[] | No    | Current position title, or array of titles, to exclude from results  |
| `positionTitle`            | string \| string[] | No       | Current or past position title, or array of titles (OR-matched)      |
| `excludePositionTitle`     | string \| string[] | No       | Current or past position title, or array of titles, to exclude       |
| `currentCompanyName`       | string             | No       | Match the current employer name                                      |
| `excludeCurrentCompanyName` | string            | No       | Exclude the current employer name                                    |
| `companyName`              | string \| string[] | No       | Current or past company name, or array of names (OR-matched)         |
| `excludeCompanyName`       | string \| string[] | No       | Current or past company name, or array of names, to exclude          |
| `currentCompanyId`         | string \| string[] | No       | ReverseContact internal id (`com_...`) of the current employer       |
| `excludeCurrentCompanyId`  | string \| string[] | No       | Current employer `com_...` id, or array of ids, to exclude           |
| `companyId`                | string \| string[] | No       | Current or past company `com_...` id, or array of ids                |
| `excludeCompanyId`         | string \| string[] | No       | Current or past company `com_...` id, or array of ids, to exclude    |
| `currentCompanyLinkedinId` | string \| string[] | No       | Current employer Social identifier, or array of identifiers         |
| `excludeCurrentCompanyLinkedinId` | string \| string[] | No | Current employer Social identifier, or array, to exclude        |
| `companyLinkedinId`        | string \| string[] | No       | Current or past company Social identifier, or array of identifiers   |
| `excludeCompanyLinkedinId` | string \| string[] | No       | Current or past company Social identifier, or array, to exclude      |
| `currentCompanyPublicId`   | string \| string[] | No       | Current employer public ID or slug, or array                         |
| `excludeCurrentCompanyPublicId` | string \| string[] | No | Current employer public ID or slug, or array, to exclude         |
| `companyPublicId`          | string \| string[] | No       | Current or past company public ID or slug, or array                  |
| `excludeCompanyPublicId`   | string \| string[] | No       | Current or past company public ID or slug, or array, to exclude      |
| `currentCompanyIndustry`   | string \| string[] | No       | Current employer industry. See [Industry values](https://docs.reversecontact.com/guides/industries) for the full list |
| `companyIndustry`          | string \| string[] | No       | Current or past company industry, from the same industry list        |
| `excludeCompanyIndustry`   | string \| string[] | No       | Current or past company industry, or array, to exclude               |
| `currentFunction`          | string \| string[] | No       | Current function from the [position taxonomy](#position-taxonomy)    |
| `excludeCurrentFunction`   | string \| string[] | No       | Current function, or array of functions, to exclude                  |
| `currentSubFunction`       | string \| string[] | No       | Current sub-function from the [position taxonomy](#position-taxonomy) |
| `excludeCurrentSubFunction` | string \| string[] | No      | Current sub-function, or array of sub-functions, to exclude          |
| `currentSeniority`         | string \| string[] | No       | Current seniority from the [position taxonomy](#position-taxonomy)   |
| `excludeCurrentSeniority`  | string \| string[] | No       | Current seniority, or array of seniorities, to exclude               |
| `skills`                   | string \| string[] | No       | Skill name, or array of skill names: a person matches if they list any of them. See [Skills](#skills) |
| `languages`                | string \| string[] | No       | Language name in English, or array: a person matches if they speak any of them. See [Languages](#languages) |
| `excludeLanguages`         | string \| string[] | No       | Language name in English, or array, to exclude. Needs a positive filter next to it |
| `keywords`                 | string             | No       | Words searched across the whole profile: every word must appear, in any field. See [Keywords](#keywords) |
| `changedJobsWithinDays`    | number             | No       | `30`, `60`, `90` or `120`: the current position started within that many days. See [Recent job change](#recent-job-change) |
| `maxDataAgeDate`           | string             | No       | ISO 8601 datetime. Only returns profiles refreshed after this date   |
| `cursor`                   | string             | No       | Opaque cursor returned as `metadata.nextCursor`; request the next page |
| `perPage`                  | number             | No       | Profiles per page (1 to 100, default `25`)                           |

> **Filter validation:** filters are validated before the query runs. Unknown field names, blank values, values outside a closed list (`currentCompanyIndustry`, `currentFunction`, `currentSubFunction`, `currentSeniority`, `changedJobsWithinDays`, `location.countryCode`), `keywords` without a single word and inconsistent ranges return HTTP `422` with the offending field, the reason and suggested values, and **cost 0 credits**. Unknown fields are rejected rather than ignored, because an ignored filter would return unfiltered results. Each list filter accepts at most 20 values. See [Search filter validation](https://docs.reversecontact.com/guides/errors-retries#search-filter-validation).

> **Note:** Title matching is token-based, not exact: `"CTO"` also matches `"Deputy CTO"`. Multiple titles are OR-matched, and exclusions always win over matches. The `positionTitle`, `companyName`, `companyId`, `companyLinkedinId`, `companyPublicId` and `companyIndustry` filters match current and past positions, while their `current...` counterparts match the current position only.

**followersCount** (RangeFilter): Filter by follower count range. Both bounds are optional and inclusive.

| Field | Type   | Description              |
| ----- | ------ | ------------------------ |
| `min` | number | Minimum value, inclusive |
| `max` | number | Maximum value, inclusive |

**currentCompanyEmployeeCountRange** (RangeFilter): Filter by the current company employee count range. Both bounds are optional and inclusive. Headcount is stored as fixed size brackets (`1`, `2-10`, `11-50`, `51-200`, `201-500`, `501-1000`, `1001-5000`, `5001-10000`, `10001+`), not as an exact number, and a range only matches a bracket it fully contains. Send bracket boundaries, otherwise the range contains no bracket, matches nothing and returns an empty `data.data` array.

| Field | Type   | Description              |
| ----- | ------ | ------------------------ |
| `min` | number | Lower bound, inclusive. Must be a bracket start: `1`, `2`, `11`, `51`, `201`, `501`, `1001`, `5001`, `10001` |
| `max` | number | Upper bound, inclusive. Must be a bracket end: `1`, `10`, `50`, `200`, `500`, `1000`, `5000`, `10000`. Omit it to include `10001+` |

> **Examples:** `{ "min": 11, "max": 50 }` matches the `11-50` bracket. `{ "min": 11, "max": 200 }` spans `11-50` and `51-200`. `{ "min": 10001 }` matches `10001+`. `{ "min": 11, "max": 20 }` returns an empty array, because no whole bracket fits between 11 and 20.

**totalExperienceMonths** (RangeFilter): Filter by total career length in months. Both bounds are optional and inclusive, from 0 to 1200.

| Field | Type   | Description              |
| ----- | ------ | ------------------------ |
| `min` | number | Minimum value, inclusive |
| `max` | number | Maximum value, inclusive |

**location** (LocationFilter): Multi-field location filter. Each sub-field is optional and accepts a single string or an array of strings (OR matching), with a maximum of 20 values per sub-field (for example 20 `region` values). Beyond that, the request returns HTTP `422` with `FILTER_VALUES_LIMIT_EXCEEDED` and costs 0 credits: split it into several searches.

| Field         | Type               | Description                         |
| ------------- | ------------------ | ----------------------------------- |
| `country`     | string \| string[] | Country name (e.g. `"France"`)      |
| `countryCode` | string \| string[] | ISO 3166 country code (e.g. `"FR"`) |
| `region`      | string \| string[] | State or region                     |
| `city`        | string \| string[] | City                                |
| `area`        | string \| string[] | Broader geographic area             |

**experience** (ExperienceFilter[]): Required past experience. Each entry demands a position taxonomy value, with an optional minimum tenure. Entries are AND-combined, up to 10 per request.

| Field       | Type   | Description                                                            |
| ----------- | ------ | ---------------------------------------------------------------------- |
| `dimension` | string | Taxonomy dimension: `function`, `subFunction` or `seniority`           |
| `value`     | string | Value from the selected dimension of the [position taxonomy](#position-taxonomy) |
| `minMonths` | number | Optional minimum tenure in that dimension, in months (0 to 720)        |

## Position taxonomy

`currentFunction`, `currentSubFunction`, `currentSeniority` and the `experience` filter match a closed taxonomy of professional functions. A value must come from the taxonomy: case and surrounding spaces are ignored, and any other value is rejected with HTTP `422` and the closest valid values, never silently ignored.

There are 32 functions, 386 sub-functions and 10 seniorities. The functions and seniorities are listed below; the full sub-function list is long, so read it from the [available fields](https://docs.reversecontact.com/endpoints/search-people-available-fields) endpoint, which returns every accepted value for each filter, plus the function each sub-function belongs to.

### Functions (32)

- Administrative
- Agriculture and Environment
- Construction and Trades
- Consulting and Advisory
- Customer Service
- Design
- Education
- Energy and Utilities
- Entertainment and Gaming
- Executive and Leadership
- Finance
- Hospitality and Tourism
- Human Resources
- Legal
- Marketing
- Media and Communications
- Medical and Health
- Nonprofit and Government
- Not Employed
- Operations
- Other
- Personal and Home Services
- Product
- Project and Program Management
- Public Safety and Security
- Real Estate
- Research and Science
- Retail and Consumer
- Sales
- Software
- Traditional Engineering
- Transportation and Logistics

### Seniorities (10)

- CXO
- VP
- Director
- Head
- Manager
- Partner
- Owner / Founder
- Individual Contributor
- Intern
- Other

## Skills, languages, keywords and job changes

These four filters read the whole profile rather than one position. They combine with every other filter, and each of them except `excludeLanguages` is a valid search on its own.

### Skills

`skills` matches the skills listed on the profile, whatever position or school they come from. Matching ignores case and accents and compares whole skill names, never part of one: `"Java"` does not match a profile that only lists `"JavaScript"`, and `"Machine Learning"` is matched as one value. A list is OR-matched: a person matches when they list at least one of the requested skills.

### Languages

`languages` keeps people who speak at least one of the requested languages, and `excludeLanguages` removes people who speak any of the listed ones. Profiles that list no language are kept by `excludeLanguages`, which only refines a search: sent alone, it is rejected.

Send language names in English. Profiles store their languages in their own spelling (`Français`, `Inglese`, `Deutsch`), and the following names also match those spellings: Arabic, Bengali, Catalan, Chinese, Czech, Danish, Dutch, English, Finnish, French, German, Greek, Hebrew, Hindi, Hungarian, Indonesian, Italian, Japanese, Korean, Mandarin, Norwegian, Polish, Portuguese, Punjabi, Romanian, Russian, Spanish, Swedish, Tagalog, Thai, Turkish, Ukrainian, Urdu, Vietnamese. Any other value is accepted and matches its exact spelling only. Matching compares whole names: `"French"` does not match `"French Creole"`. There is no proficiency level: any level matches.

> **Note:** about one profile in six lists its languages, so a `languages` filter leaves out every profile that lists none.

### Keywords

`keywords` is one string searched across the whole profile: names, headline, summary, current and past job titles, companies, industries, skills, schools, degrees, certifications, languages and location. The value is split into words, case and accents are ignored, and **every** word must appear somewhere in the profile, in any field and in any order: `"react paris"` means react **and** paris. Words are matched whole: `"react"` does not match `"reactive"`. Because the words may come from different fields, there is no exact-phrase match. A value with no word at all, such as `"!!!"`, returns HTTP `422`.

### Recent job change

`changedJobsWithinDays` keeps people whose **current** position started within the last `30`, `60`, `90` or `120` days, boundary included, counted in UTC days. A profile with no current position, or whose current position has no start date, does not match, and a start date in the future never matches. Any other value returns HTTP `422` with the accepted ones.

**Example**

```bash [cURL]
curl -X POST https://api.reversecontact.com/v2/search/people \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "currentFunction": "Software",
    "skills": ["Python", "Machine Learning"],
    "languages": "German",
    "keywords": "fintech",
    "changedJobsWithinDays": 90,
    "location": { "countryCode": "DE" },
    "perPage": 25
  }'
```

> **Tip:** on the largest countries, a lone `skills` or `languages` filter has to scan a very large set of profiles and can be slow. Pair it with a title, a function or a company to keep the search fast.

## Pagination and credits

People search uses **cursor pagination**. Each response returns up to `perPage` profiles (1 to 100, default `25`) and a `metadata.nextCursor` value. Pass that value back as `cursor` in the next request to get the following page; `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.

A `nextCursor` has no hard expiry. The result list behind it is cached for 10 minutes. If you use a cursor after that, the search is re-run with the same filters and you get the next page from the refreshed list. If the data changed in the meantime, that page can contain a profile you already received or skip one. For a consistent result set, fetch each page within 10 minutes of the previous one.

An invalid or expired cursor returns HTTP `400` with the message `Invalid or expired cursor`. This happens when a filter is changed between two pages (keep the request body identical and only add the `cursor`), or when the cursor is malformed (truncated or altered).

`perPage` above `100` returns HTTP `422` with `error.code` `PAGINATION_LIMIT_EXCEEDED`, and the `error.details` object identifies the field and maximum, for example `{ "field": "perPage", "max": 100 }`.

People search 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. Check the size of a query first with the free [People search count](https://docs.reversecontact.com/endpoints/search-people-count) endpoint, and 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 `data` field 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.data** (PersonFull[]): Full profiles returned for this page, wrapped under `data.data` in the envelope. Empty array if no match. Each item is the same full profile shape as the [Profile](https://docs.reversecontact.com/endpoints/fetch-profile) endpoint; the table below lists its main fields.

| Field                | Type           | Description                                                          |
| -------------------- | -------------- | -------------------------------------------------------------------- |
| `id`                 | string         | ReverseContact internal person identifier (`prs_...`)                |
| `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](https://docs.reversecontact.com/guides/current-position-resolution)) |
| `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                                             |

**location** (PersonLocation): Geographic location (`null` if unknown)

| 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 |

**currentPosition** (CurrentPosition): Current job position (`null` if no current position)

| 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](https://docs.reversecontact.com/api-reference)) |

**data.metadata** (SearchPagination): Pagination metadata wrapped under `data.metadata` in the envelope.

| Field        | Type           | Description                                                            |
| ------------ | -------------- | ---------------------------------------------------------------------- |
| `perPage`    | number         | Profiles requested per page                                            |
| `count`      | number         | Profiles returned in this page. Use [People search count](https://docs.reversecontact.com/endpoints/search-people-count) for the total matching set |
| `nextCursor` | string \| null | Opaque cursor for the next page, `null` on the last page               |

**quotas** (V2QuotaInfo): Credits and rate limit usage after this request

| Field             | Type   | Description                      |
| ----------------- | ------ | -------------------------------- |
| `creditsConsumed` | number | Credits consumed by this request |

**workspace** (Workspace): Workspace-level limits

| 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 |

**credits** (Credits): Credit balance

| Field   | Type   | Description                |
| ------- | ------ | -------------------------- |
| `total` | number | Total credits in your plan |
| `used`  | number | Credits consumed so far    |
| `left`  | number | Remaining credits          |

**dailyLimit** (DailyLimit): Daily request limit (`null` if not configured)

| 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) |

**minuteRateLimit** (MinuteRateLimit): Per-minute rate limit

| 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) |

**key** (ApiKey): API key-level limits (`null` when request is from dashboard)

| Field | Type   | Description        |
| ----- | ------ | ------------------ |
| `id`  | string | API key identifier |

**dailyLimit** (KeyDailyLimit): Daily limit for this key (`null` if not configured)

| 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) |

**minuteRateLimit** (KeyMinuteRateLimit): Minute rate limit for this key

| 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) |

**metadata** (V2ResponseMetadata): Request tracking information (not to be confused with `data.metadata` which is pagination)

| Field             | Type   | Description                          |
| ----------------- | ------ | ------------------------------------ |
| `requestId`       | string | Unique identifier for this request   |
| `executionTimeMs` | number | Total execution time in milliseconds |

## Code examples

**Code Examples**

```bash [cURL]
curl -X POST https://api.reversecontact.com/v2/search/people \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "currentFunction": "Marketing",
    "currentSeniority": ["Director", "VP"],
    "excludeCurrentSubFunction": "Marketing Operations",
    "currentCompanyIndustry": ["Software Development", "Technology, Information and Internet"],
    "location": {
      "country": "United States",
      "city": ["San Francisco", "New York"]
    },
    "followersCount": { "min": 1000 },
    "experience": [
      { "dimension": "function", "value": "Sales", "minMonths": 24 }
    ],
    "perPage": 25
  }'
```
```javascript [JavaScript]
const searchPage = async (cursor) => {
  const response = await fetch("https://api.reversecontact.com/v2/search/people", {
    method: "POST",
    headers: {
      "Authorization": "Bearer YOUR_API_KEY",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      currentFunction: "Marketing",
      currentSeniority: ["Director", "VP"],
      currentCompanyIndustry: ["Software Development", "Technology, Information and Internet"],
      location: { country: "United States", city: ["San Francisco", "New York"] },
      followersCount: { min: 1000 },
      perPage: 25,
      cursor
    })
  });

  return response.json();
};

const firstPage = await searchPage();
const profiles = firstPage.data.data;
const { count, nextCursor } = firstPage.data.metadata;
console.log(`Got ${count} profiles, credits used: ${firstPage.quotas.creditsConsumed}`);

if (nextCursor) {
  const secondPage = await searchPage(nextCursor);
  profiles.push(...secondPage.data.data);
}
```
```python [Python]
import requests

response = requests.post(
    "https://api.reversecontact.com/v2/search/people",
    headers={
        "Authorization": "Bearer YOUR_API_KEY",
        "Content-Type": "application/json"
    },
    json={
        "currentFunction": "Marketing",
        "currentSeniority": ["Director", "VP"],
        "currentCompanyIndustry": ["Software Development", "Technology, Information and Internet"],
        "location": {
            "country": "United States",
            "city": ["San Francisco", "New York"]
        },
        "followersCount": {"min": 1000},
        "experience": [
            {"dimension": "function", "value": "Sales", "minMonths": 24}
        ],
        "perPage": 25
    }
)

payload = response.json()
profiles = payload["data"]["data"]
metadata = payload["data"]["metadata"]
print(f"Got {metadata['count']} profiles, next cursor: {metadata['nextCursor']}")
```

## Example response

**Example Response**

```json [200 - Success]
{
  "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_01j9x7q4m2z8b6d4f0a2c8e6"
    }
  },
  "error": null,
  "metadata": {
    "requestId": "req_s1e2a3r4c5h6",
    "executionTimeMs": 410
  },
  "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"
      }
    }
  }
}
```
