> ## Documentation Index
> Fetch the complete documentation index at: https://docs.crustdata.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Person Search reference

> Reference for Person Search: filter operators, searchable fields, response fields, request parameters, preview mode, and errors.

Reference material for [Person Search](/person-docs/search/introduction): the full list of
filter operators, searchable fields with sortable flags, response fields,
request parameters, preview mode, and error responses.

For walk-through examples, see [Person Search](/person-docs/search/introduction) and
[Examples](/person-docs/search/introduction).

***

## Filter operator reference

Person Search accepts the following `filters.type` operators.

| Operator       | Value shape                    | Meaning                                                                                                                                                                 | Example use                                                                           |
| -------------- | ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| `=`            | scalar                         | Exact match                                                                                                                                                             | `basic_profile.name` = "David Hsu"                                                    |
| `!=`           | scalar                         | Not equal                                                                                                                                                               | Exclude a specific country                                                            |
| `<`            | scalar (number or date string) | Less than                                                                                                                                                               | Profiles updated before a timestamp                                                   |
| `=<`           | scalar (number or date string) | Less than or equal                                                                                                                                                      | `professional_network.connections` at or below a threshold                            |
| `>`            | scalar (number or date string) | Greater than                                                                                                                                                            | `years_of_experience_raw` above a threshold                                           |
| `=>`           | scalar (number or date string) | Greater than or equal                                                                                                                                                   | `professional_network.followers` at or above a threshold                              |
| `in`           | array                          | Value is in list                                                                                                                                                        | `experience.employment_details.company_name` in \["Retool", "OpenAI"]                 |
| `not_in`       | array                          | Value is not in list                                                                                                                                                    | Exclude titles like "Intern"                                                          |
| `has_all`      | array                          | Each listed value is matched by some nested-array element, possibly different elements (see [Nested-array matching](#nested-array-matching-all_of-and-has_all))         | `experience.employment_details.company_id` `has_all` \[629097, 632500]                |
| `(.)`          | string                         | Case-insensitive all-words match — every query word must appear, in any order (not regex); a piped value is split into separate words that must ALL match (AND), not OR | Match `engineer` in any title; for VP **or** Director use `any_of`                    |
| `(!)`          | string                         | Fuzzy negation — exclude substring matches                                                                                                                              | Exclude titles containing "Intern" (see notes below)                                  |
| `[.]`          | string                         | Case-insensitive exact-phrase match — words must be contiguous and in order (no partial words or typos)                                                                 | `[.]` "Software Engineer" matches "Senior Software Engineer", not "Engineer Software" |
| `geo_distance` | object                         | Within radius of a location or explicit coordinate                                                                                                                      | People within 50 km of San Francisco                                                  |
| `geo_exclude`  | object                         | Outside radius of a location or explicit coordinate                                                                                                                     | People **not** within 50 km of San Francisco                                          |

<Warning>
  Use `=>` for greater-than-or-equal and `=<` for less-than-or-equal.
  The operators `>=` and `<=` are not supported.
</Warning>

<Note>
  **Operator sets differ per endpoint.** `contains` is **not** supported on
  `/person/search` (use `(.)` for substring/word matching) — it is accepted
  by Company Search and by the autocomplete endpoints' `filters`. `has_all`
  works only on nested array fields (for example
  `experience.employment_details.*`); non-array fields return `400`.
</Note>

### `(!)` — fuzzy negation

`(!)` excludes profiles whose value contains the given substring,
case-insensitive. It is the opposite of `(.)`. Multi-word values are matched
as a literal phrase — they are **not** word-split:

* `{ "type": "(!)", "value": "New York" }` excludes only profiles that
  literally contain the phrase `"New York"`. A profile whose location is
  `"New Yorker"` is **not** excluded by this filter; `"New York City"` **is**
  excluded because it contains the full phrase.
* To exclude on each word independently, wrap multiple `(!)` conditions in an
  `and` group:

  ```json theme={"theme":"vitesse-black"}
  {
      "op": "and",
      "conditions": [
          {
              "field": "basic_profile.headline",
              "type": "(!)",
              "value": "Intern"
          },
          {
              "field": "basic_profile.headline",
              "type": "(!)",
              "value": "Student"
          }
      ]
  }
  ```

### `geo_distance` — radius around a point

Supply the centre of the radius using **one** of:

* `location` — a string that is geocoded server-side (e.g. `"San Francisco, CA"`).
* `lat_lng` — explicit coordinates as `[lat, lng]`. Skips geocoding.

If both are supplied, `lat_lng` wins. `distance` is required; `unit` defaults
to `km`.

| Field      | Type      | Required | Notes                                                                      |
| ---------- | --------- | -------- | -------------------------------------------------------------------------- |
| `location` | string    | One of   | Geocoded server-side. Ignored when `lat_lng` is also set.                  |
| `lat_lng`  | number\[] | One of   | Two-element `[lat, lng]`. Lat in `[-90, 90]`, lng in `[-180, 180]`.        |
| `distance` | number    | Yes      | Radius around the centre. Must be positive.                                |
| `unit`     | string    | No       | One of `km`, `mi`, `miles`, `m`, `meters`, `ft`, `feet`. Defaults to `km`. |

See [`geo_distance` examples](/person-docs/search/introduction#search-within-a-geographic-radius)
for end-to-end requests using both `location` and `lat_lng`.

### `geo_exclude` — exclude a radius

`geo_exclude` is the inverse of `geo_distance`: it removes profiles **inside**
the radius and keeps everyone else. It takes the same value object —
`location` or `lat_lng`, a required `distance`, and an optional `unit`
(defaults to `km`) — and works on the same location fields. Use it to carve
out a metro you already cover, or to target candidates outside a region.

```json theme={"theme":"vitesse-black"}
{
    "field": "professional_network.location.raw",
    "type": "geo_exclude",
    "value": { "location": "San Francisco", "distance": 50, "unit": "km" }
}
```

See [`geo_exclude` examples](/person-docs/search/introduction#exclude-a-geographic-radius)
for an end-to-end request.

## Nested-array matching: `all_of` and `has_all`

Some fields are **arrays of nested objects** — for example a person's
employment history (`experience.employment_details.*`), where each entry has
its own `title`, `company_id`, `company_name`, and dates. When you put several
conditions on one such field, there are two distinct things you might mean:

* **Same element** — one array entry satisfies all the conditions (was an
  *Engineer* **at** company X — one job).
* **Cross element** — different entries each satisfy a condition (was an
  *Engineer* at A **and** a *Manager* at B — two separate jobs).

A plain `and` group over one nested field means **same element**: all
conditions must match within a single entry. To express **cross element**, use
an `all_of` group.

### `all_of` — each condition matched by some element

`all_of` is a group operator (like `and`/`or`). Each condition inside it must be
satisfied by **at least one array element**, and each condition is evaluated
**independently** — so different conditions can be matched by different
elements. A condition can be a single filter or an `and`/`or` group; a group is
matched **within one element**.

Existential — some job is both `Engineer` and at company `629097`:

```json theme={"theme":"vitesse-black"}
{
    "filters": {
        "op": "all_of",
        "conditions": [
            { "op": "and", "conditions": [
                { "field": "experience.employment_details.title", "type": "(.)", "value": "Engineer" },
                { "field": "experience.employment_details.company_id", "type": "=", "value": 629097 }
            ] }
        ]
    }
}
```

Cross element — `Engineer` at one company **and** `Manager` at another, in
different jobs:

```json theme={"theme":"vitesse-black"}
{
    "filters": {
        "op": "all_of",
        "conditions": [
            { "op": "and", "conditions": [
                { "field": "experience.employment_details.title", "type": "(.)", "value": "Engineer" },
                { "field": "experience.employment_details.company_id", "type": "=", "value": 629097 } ] },
            { "op": "and", "conditions": [
                { "field": "experience.employment_details.title", "type": "(.)", "value": "Manager" },
                { "field": "experience.employment_details.company_id", "type": "=", "value": 632500 } ] }
        ]
    }
}
```

`all_of` groups nest freely inside `and`/`or` groups, so you can combine
cross-element requirements with document-level filters (like location).
Conditions inside `all_of` accept any **positive** operator
(`=`, `(.)`, `[.]`, `in`, `<`, `>`, `=<`, `=>`).

### `has_all` — every value matched by some element

`has_all` is shorthand for the common cross-element case: a value list where
**each value is matched by some element** of the array.

Worked at **both** company `629097` and `632500` (two separate roles):

```json theme={"theme":"vitesse-black"}
{ "filters": { "field": "experience.employment_details.company_id", "type": "has_all", "value": [629097, 632500] } }
```

This expands to exactly `all_of` with one equality condition per value:
`{ "op": "all_of", "conditions": [company_id = 629097, company_id = 632500] }`.

### Rules and validation

* Send the operator in lowercase: `all_of` (like `and`/`or`; `allOf` and other
  casings are rejected).
* All fields inside one `all_of` condition (or its `and`/`or` group) must
  resolve to a **single** nested-array path. Mixing paths (for example an
  employment field and an education field in the same group) is rejected —
  split them into separate `all_of` conditions.
* `all_of` and `has_all` are valid only on **nested-array fields** (employment,
  education, certifications, honors). Using them on a scalar field (such as a
  name) is rejected.
* Conditions inside `all_of` allow **positive** predicates only. Negation
  operators (`!=`, `not_in`, `(!)`, `geo_exclude`) are not allowed — apply
  negation at the document level instead.
* Do not put a `has_all` condition (or another `all_of`) **inside** an `all_of`
  group — expand it into `=` conditions instead.
* `has_all` requires a **non-empty** list value.

## Searchable fields

* Some returned fields use a different filter path. For example, the returned `basic_profile.current_title` is searched with `experience.employment_details.current.title`.
* Contact availability flags such as `contact.has_business_email` are response-only convenience fields. For search filters, use `experience.employment_details.current.business_email_verified`, `experience.employment_details.past.business_email_verified`, or `experience.employment_details.business_email_verified`.
* `social_handles.professional_network_identifier.profile_url` is returned in search results but is rejected as a search filter. Use [Person Enrich](/person-docs/enrichment/introduction) for direct profile URL lookups.
* Some searchable fields, such as `certifications.*` and `honors.title`, may not appear in the response summary below.

<Note>
  Country filters do not all use the same value format. Use full country names
  for person location fields, and use ISO 3166-1 alpha-3 codes for employer
  headquarters country fields.
</Note>

### Country and region value formats

| Field                                                                | Value format                    | Examples                      |
| -------------------------------------------------------------------- | ------------------------------- | ----------------------------- |
| `basic_profile.location.country`                                     | Full country name               | `"United States"`, `"India"`  |
| `basic_profile.location.state`                                       | Full state or region name       | `"California"`, `"Ontario"`   |
| `basic_profile.location.continent`                                   | Full continent name             | `"North America"`, `"Asia"`   |
| `professional_network.location.raw`                                  | Raw location string             | `"San Francisco Bay Area"`    |
| `experience.employment_details.company_headquarters_country`         | ISO 3166-1 alpha-3 country code | `"USA"`, `"IND"`              |
| `experience.employment_details.current.company_headquarters_country` | ISO 3166-1 alpha-3 country code | `"USA"`, `"GBR"`              |
| `experience.employment_details.past.company_headquarters_country`    | ISO 3166-1 alpha-3 country code | `"IND"`, `"USA"`              |
| `experience.employment_details.company_hq_location`                  | Employer HQ location string     | `"San Francisco, California"` |

For headquarters country filters, use ISO-3 codes such as `USA`, `IND`, and
`GBR`. For the full code list, see the
[ISO 3166-1 alpha-3 country code list](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3).
For `basic_profile.location.country`, use [Autocomplete](/person-docs/autocomplete/introduction)
to discover indexed full-country labels before filtering.

### Website value formats

| Field                                                          | Value format                                         | Examples                       |
| -------------------------------------------------------------- | ---------------------------------------------------- | ------------------------------ |
| `experience.employment_details.current.company_website_domain` | Bare website domain                                  | `"stripe.com"`                 |
| `experience.employment_details.past.company_website_domain`    | Bare website domain                                  | `"stripe.com"`                 |
| `experience.employment_details.company_website_domain`         | Bare website domain                                  | `"stripe.com"`                 |
| `experience.employment_details.company_website`                | Exact stored website URL (scheme + any query string) | `"http://www.chetnetwork.com"` |

Filter websites with the `company_website_domain` fields — a bare domain, no
scheme. The all-roles `company_website` filter matches the stored URL
**exactly**, including scheme and any query string (stored values can look like
`https://example.com?utm_source=profile`), so prefer the domain fields unless
you need an exact URL match. In search responses the website comes back as a
full URL under `experience.employment_details.current.company_website` /
`past.company_website`; the `company_website_domain` paths are filter-side
names and never appear in the search response.
[Person Enrich](/person-docs/enrichment/introduction) is the reverse: it
returns the bare domain under `company_website_domain`.

### Identity & metadata

| Field                          | Type     | Filterable | Sortable | Description                   |
| ------------------------------ | -------- | ---------- | -------- | ----------------------------- |
| `crustdata_person_id`          | integer  | Yes        | Yes      | Crustdata person ID           |
| `metadata.updated_at`          | datetime | Yes        | Yes      | Last profile update timestamp |
| `metadata.last_scraped_source` | string   | Yes        | No       | Last profile refresh source   |

### Basic profile

| Field                                           | Type      | Filterable | Sortable | Description                                                                                                         |
| ----------------------------------------------- | --------- | ---------- | -------- | ------------------------------------------------------------------------------------------------------------------- |
| `basic_profile.name`                            | string    | Yes        | Yes      | Full name                                                                                                           |
| `basic_profile.first_name`                      | string    | Yes        | No       | First name                                                                                                          |
| `basic_profile.last_name`                       | string    | Yes        | No       | Last name                                                                                                           |
| `basic_profile.headline`                        | string    | Yes        | No       | Profile headline                                                                                                    |
| `basic_profile.summary`                         | string    | Yes        | No       | Profile summary / about                                                                                             |
| `basic_profile.languages`                       | string\[] | Yes        | No       | Spoken languages                                                                                                    |
| `basic_profile.last_updated`                    | datetime  | Yes        | No       | Last update timestamp on the basic profile                                                                          |
| `basic_profile.location`                        | string    | Yes        | Yes      | Location summary                                                                                                    |
| `basic_profile.location.full_location`          | string    | Yes        | Yes      | Full location string                                                                                                |
| `basic_profile.location.city`                   | string    | Yes        | Yes      | City                                                                                                                |
| `basic_profile.location.state`                  | string    | Yes        | Yes      | State / region as a full name                                                                                       |
| `basic_profile.location.country`                | string    | Yes        | Yes      | Country as a full name                                                                                              |
| `basic_profile.location.continent`              | string    | Yes        | No       | Continent as a full name                                                                                            |
| `basic_profile.normalized_title.department`     | string    | Yes        | No       | [Job Title Normalization](/guides/job-title-normalization) (beta) — high-level department.                          |
| `basic_profile.normalized_title.sub_department` | string    | Yes        | No       | [Job Title Normalization](/guides/job-title-normalization) (beta) — sub-department / category.                      |
| `basic_profile.normalized_title.matched_title`  | string    | Yes        | No       | [Job Title Normalization](/guides/job-title-normalization) (beta) — standardized canonical title.                   |
| `basic_profile.normalized_title.similarity`     | float     | No         | No       | [Job Title Normalization](/guides/job-title-normalization) (beta) — similarity score between raw and matched title. |
| `basic_profile.normalized_title.confident`      | boolean   | No         | No       | [Job Title Normalization](/guides/job-title-normalization) (beta) — whether the mapping is high-confidence.         |
| `basic_profile.professional_network_name`       | string    | Yes        | No       | Display name on the professional-network profile                                                                    |

### Professional network

| Field                                               | Type      | Filterable | Sortable | Description                                                               |
| --------------------------------------------------- | --------- | ---------- | -------- | ------------------------------------------------------------------------- |
| `professional_network.location.raw`                 | string    | Yes        | No       | Raw location string from profile                                          |
| `professional_network.location`                     | string    | Yes        | No       | Network location summary                                                  |
| `professional_network.location.city`                | string    | Yes        | No       | Network location city                                                     |
| `professional_network.location.state`               | string    | Yes        | No       | Network location state / region                                           |
| `professional_network.location.country`             | string    | Yes        | No       | Network location country                                                  |
| `professional_network.location.continent`           | string    | Yes        | No       | Network location continent                                                |
| `professional_network.connections`                  | integer   | Yes        | Yes      | Connection count                                                          |
| `professional_network.followers`                    | integer   | Yes        | Yes      | Follower count (requires API key access)                                  |
| `professional_network.open_to_cards`                | string\[] | Yes        | No       | Open-to signal codes. See [Open-to signal values](#open-to-signal-values) |
| `professional_network.metadata.last_scraped_source` | string    | Yes        | No       | Last profile refresh source                                               |

### Skills

| Field                                | Type      | Filterable | Sortable | Description   |
| ------------------------------------ | --------- | ---------- | -------- | ------------- |
| `skills.professional_network_skills` | string\[] | Yes        | No       | Listed skills |

### Experience — all employers

| Field                                                                 | Type      | Filterable | Sortable | Description                                                                                                                                         |
| --------------------------------------------------------------------- | --------- | ---------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `experience.employment_details.company_name`                          | string    | Yes        | No       | Company name across all roles                                                                                                                       |
| `experience.employment_details.title`                                 | string    | Yes        | No       | Job title across all roles                                                                                                                          |
| `experience.employment_details.description`                           | string    | Yes        | No       | Role description across all roles                                                                                                                   |
| `experience.employment_details.seniority_level`                       | string    | Yes        | No       | Seniority level across all roles                                                                                                                    |
| `experience.employment_details.function_category`                     | string    | Yes        | No       | Function category across all roles                                                                                                                  |
| `experience.employment_details.start_date`                            | date      | Yes        | Yes      | Role start date across all roles                                                                                                                    |
| `experience.employment_details.end_date`                              | date      | Yes        | No       | Role end date across all roles                                                                                                                      |
| `experience.employment_details.location`                              | string    | Yes        | No       | Role location across all roles                                                                                                                      |
| `experience.employment_details.company_id`                            | integer   | Yes        | Yes      | Company ID across all roles                                                                                                                         |
| `experience.employment_details.company_website_domain`                | string    | Yes        | No       | Employer website domain                                                                                                                             |
| `experience.employment_details.company_headcount_latest`              | integer   | Yes        | Yes      | Employer latest headcount                                                                                                                           |
| `experience.employment_details.company_headcount_range`               | string    | Yes        | No       | Employer headcount range                                                                                                                            |
| `experience.employment_details.company_industries`                    | string\[] | Yes        | No       | Employer industries                                                                                                                                 |
| `experience.employment_details.company_professional_network_industry` | string    | Yes        | No       | Employer primary industry label                                                                                                                     |
| `experience.employment_details.company_type`                          | string    | Yes        | No       | Employer company type                                                                                                                               |
| `experience.employment_details.company_headquarters_country`          | string    | Yes        | No       | Employer HQ country as ISO-3 code                                                                                                                   |
| `experience.employment_details.company_hq_location`                   | string    | Yes        | No       | Employer HQ location string                                                                                                                         |
| `experience.employment_details.company_website`                       | string    | Yes        | No       | Employer website across all roles — exact match against the stored full URL (scheme and any query string included); prefer `company_website_domain` |
| `experience.employment_details.employment_type`                       | string    | Yes        | No       | Employment type across all roles                                                                                                                    |
| `experience.employment_details.years_at_company_raw`                  | number    | Yes        | Yes      | Years at company across all roles                                                                                                                   |
| `experience.employment_details.business_email_verified`               | boolean   | Yes        | No       | Verified business email across all roles                                                                                                            |

### Experience — current employer

| Field                                                                            | Type      | Filterable | Sortable | Description                                                                                                                                                                                    |
| -------------------------------------------------------------------------------- | --------- | ---------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `experience.employment_details.current.company_name`                             | string    | Yes        | No       | Current company name (filter alias of `current.name`)                                                                                                                                          |
| `experience.employment_details.current.title`                                    | string    | Yes        | No       | Current job title                                                                                                                                                                              |
| `experience.employment_details.current.description`                              | string    | Yes        | No       | Current role description                                                                                                                                                                       |
| `experience.employment_details.current.seniority_level`                          | string    | Yes        | No       | Current seniority level                                                                                                                                                                        |
| `experience.employment_details.current.function_category`                        | string    | Yes        | No       | Current function category                                                                                                                                                                      |
| `experience.employment_details.current.start_date`                               | date      | Yes        | No       | Current role start date                                                                                                                                                                        |
| `experience.employment_details.current.name`                                     | string    | Yes        | No       | Current company name (returned response field)                                                                                                                                                 |
| `experience.employment_details.current.years_at_company_raw`                     | number    | Yes        | No       | Years at current company                                                                                                                                                                       |
| `experience.employment_details.current.company_headquarters_country`             | string    | Yes        | No       | Current employer HQ country as ISO-3 code                                                                                                                                                      |
| `experience.employment_details.current.company_id`                               | integer   | Yes        | No       | Current employer company ID (filter alias of `current.crustdata_company_id`) — the response returns the id under `current.crustdata_company_id`, not `company_id`                              |
| `experience.employment_details.current.position_id`                              | string    | Yes        | No       | Per-role identifier for the current position (one per role, distinct from company ID)                                                                                                          |
| `experience.employment_details.current.company_industries`                       | string\[] | Yes        | No       | Current employer industries                                                                                                                                                                    |
| `experience.employment_details.current.company_type`                             | string    | Yes        | No       | Current employer company type                                                                                                                                                                  |
| `experience.employment_details.current.company_headcount_latest`                 | integer   | Yes        | No       | Current employer latest headcount                                                                                                                                                              |
| `experience.employment_details.current.company_headcount_range`                  | string    | Yes        | No       | Current employer headcount range                                                                                                                                                               |
| `experience.employment_details.current.company_hq_location`                      | string    | Yes        | No       | Current employer HQ location string                                                                                                                                                            |
| `experience.employment_details.current.company_website_domain`                   | string    | Yes        | No       | Current employer website domain (filter alias of `current.company_website`) — filter with a bare domain like `"stripe.com"`; the response returns the full URL under `current.company_website` |
| `experience.employment_details.current.company_professional_network_industry`    | string    | Yes        | No       | Current employer primary industry label                                                                                                                                                        |
| `experience.employment_details.current.company_professional_network_profile_url` | string    | Yes        | No       | Current employer profile URL. Exact full URL — see [Find people at a company](/person-docs/search/introduction#find-people-at-a-company-by-its-profile-url)                                    |
| `experience.employment_details.current.company_linkedin_profile_url`             | string    | Yes        | No       | Current employer profile URL (accepted alias)                                                                                                                                                  |
| `experience.employment_details.current.employment_type`                          | string    | Yes        | No       | Current employment type                                                                                                                                                                        |
| `experience.employment_details.current.business_email_verified`                  | boolean   | Yes        | No       | Verified business email on current role                                                                                                                                                        |

### Experience — past employer

| Field                                                                         | Type      | Filterable | Sortable | Description                                                                                                                                                                           |
| ----------------------------------------------------------------------------- | --------- | ---------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `experience.employment_details.past.company_name`                             | string    | Yes        | No       | Past company name (filter alias of `past.name`)                                                                                                                                       |
| `experience.employment_details.past.title`                                    | string    | Yes        | No       | Past job title                                                                                                                                                                        |
| `experience.employment_details.past.description`                              | string    | Yes        | No       | Past role description                                                                                                                                                                 |
| `experience.employment_details.past.seniority_level`                          | string    | Yes        | No       | Past seniority level                                                                                                                                                                  |
| `experience.employment_details.past.function_category`                        | string    | Yes        | No       | Past function category                                                                                                                                                                |
| `experience.employment_details.past.start_date`                               | date      | Yes        | No       | Past role start date                                                                                                                                                                  |
| `experience.employment_details.past.name`                                     | string    | Yes        | No       | Past company name (returned response field)                                                                                                                                           |
| `experience.employment_details.past.years_at_company_raw`                     | number    | Yes        | No       | Years at past company                                                                                                                                                                 |
| `experience.employment_details.past.company_headquarters_country`             | string    | Yes        | No       | Past employer HQ country as ISO-3 code                                                                                                                                                |
| `experience.employment_details.past.company_id`                               | integer   | Yes        | No       | Past employer company ID (filter alias of `past.crustdata_company_id`) — the response returns the id under `past.crustdata_company_id`, not `company_id`                              |
| `experience.employment_details.past.position_id`                              | string    | Yes        | No       | Per-role identifier for the past position (one per role, distinct from company ID)                                                                                                    |
| `experience.employment_details.past.company_industries`                       | string\[] | Yes        | No       | Past employer industries                                                                                                                                                              |
| `experience.employment_details.past.company_type`                             | string    | Yes        | No       | Past employer company type                                                                                                                                                            |
| `experience.employment_details.past.company_headcount_latest`                 | integer   | Yes        | No       | Past employer latest headcount                                                                                                                                                        |
| `experience.employment_details.past.company_headcount_range`                  | string    | Yes        | No       | Past employer headcount range                                                                                                                                                         |
| `experience.employment_details.past.company_hq_location`                      | string    | Yes        | No       | Past employer HQ location string                                                                                                                                                      |
| `experience.employment_details.past.company_website_domain`                   | string    | Yes        | No       | Past employer website domain (filter alias of `past.company_website`) — filter with a bare domain like `"stripe.com"`; the response returns the full URL under `past.company_website` |
| `experience.employment_details.past.company_professional_network_industry`    | string    | Yes        | No       | Past employer primary industry label                                                                                                                                                  |
| `experience.employment_details.past.company_professional_network_profile_url` | string    | Yes        | No       | Past employer profile URL. Exact full URL — see [Find people at a company](/person-docs/search/introduction#find-people-at-a-company-by-its-profile-url)                              |
| `experience.employment_details.past.company_linkedin_profile_url`             | string    | Yes        | No       | Past employer profile URL (accepted alias)                                                                                                                                            |
| `experience.employment_details.past.employment_type`                          | string    | Yes        | No       | Past employment type                                                                                                                                                                  |
| `experience.employment_details.past.business_email_verified`                  | boolean   | Yes        | No       | Verified business email on past role                                                                                                                                                  |

### Education

| Field                                      | Type   | Filterable | Sortable | Description                    |
| ------------------------------------------ | ------ | ---------- | -------- | ------------------------------ |
| `education.schools.school`                 | string | Yes        | No       | School name                    |
| `education.schools.degree`                 | string | Yes        | No       | Degree                         |
| `education.schools.field_of_study`         | string | Yes        | No       | Field of study                 |
| `education.schools.location`               | string | Yes        | No       | School location summary        |
| `education.schools.location.city`          | string | Yes        | No       | School location city           |
| `education.schools.location.state`         | string | Yes        | No       | School location state / region |
| `education.schools.location.country`       | string | Yes        | No       | School location country        |
| `education.schools.location.continent`     | string | Yes        | No       | School location continent      |
| `education.schools.location.full_location` | string | Yes        | No       | School full location string    |

### Certifications & honors

| Field                                 | Type   | Filterable | Sortable | Description                   |
| ------------------------------------- | ------ | ---------- | -------- | ----------------------------- |
| `certifications.name`                 | string | Yes        | No       | Certification name            |
| `certifications.issuing_organization` | string | Yes        | No       | Certification issuer          |
| `certifications.issue_date`           | date   | Yes        | No       | Certification issue date      |
| `certifications.expiration_date`      | date   | Yes        | No       | Certification expiration date |
| `certifications.credential_id`        | string | Yes        | No       | Certification credential ID   |
| `certifications.credential_url`       | string | Yes        | No       | Certification credential URL  |
| `honors.title`                        | string | Yes        | No       | Honor or award title          |

### Social handles

| Field                           | Type   | Filterable | Sortable | Description      |
| ------------------------------- | ------ | ---------- | -------- | ---------------- |
| `social_handles.twitter_handle` | string | Yes        | No       | Twitter/X handle |

### Other

| Field                     | Type    | Filterable | Sortable | Description                               |
| ------------------------- | ------- | ---------- | -------- | ----------------------------------------- |
| `recently_changed_jobs`   | boolean | Yes        | Yes      | True if the profile recently changed jobs |
| `years_of_experience_raw` | number  | Yes        | Yes      | Total years of experience (precise)       |
| `years_of_experience`     | number  | Yes        | No       | Total years of experience (rounded)       |

### Open-to signal values

`professional_network.open_to_cards` is a closed enum of exactly three code strings. Filter with the `in` operator using one or more of these values:

| Code              | Meaning                                     |
| ----------------- | ------------------------------------------- |
| `CAREER_INTEREST` | Profile is open to new career opportunities |
| `HIRING_MANAGER`  | Profile is actively hiring                  |
| `VOLUNTEERING`    | Profile is open to volunteer work           |

<Warning>
  Only the three uppercase code strings above are indexed. Human-readable
  strings like `"open_to_work"` or `"Open to Work"` return **zero results**.
  Always use the codes as-is.
</Warning>

```json Filter example theme={"theme":"vitesse-black"}
{
    "filters": {
        "op": "and",
        "conditions": [
            {
                "field": "professional_network.open_to_cards",
                "type": "in",
                "value": ["CAREER_INTEREST"]
            }
        ]
    },
    "limit": 5
}
```

## Response fields

Each profile in the response can include these sections, depending on `fields`. This table summarizes returned sections only. It is not a complete filter reference.

| Section          | Key fields                                                                                                       | Description                |
| ---------------- | ---------------------------------------------------------------------------------------------------------------- | -------------------------- |
| `basic_profile`  | `name`, `headline`, `current_title`, `normalized_title`, `professional_network_name`, `location`                 | Identity and location      |
| `experience`     | `employment_details.current`, `employment_details.past` (each role includes `company_profile_picture_permalink`) | Full work history          |
| `education`      | `schools` (each includes `school`, `degree`, `location`, `description`, `institute_logo_permalink`)              | Education background       |
| `contact`        | `has_business_email`, `has_personal_email`, `has_phone_number`                                                   | Contact availability flags |
| `social_handles` | `professional_network_identifier.profile_url`, `dev_platform_identifier.profile_url`, `twitter_identifier.slug`  | Available profile handles  |

<Note>
  **`skills` and `dev_platform_profiles` are not returned by Person Search.**
  Search returns a lightweight subset, so these sections are absent from the
  response for every account regardless of `fields` — they are not gated, just
  not part of search. Fetch skills with
  [Person Enrich](/person-docs/enrichment/introduction). `skills.professional_network_skills`
  still works as a filter (see [Filterable but not returned](#filterable-but-not-returned)).
</Note>

### Filterable but not returned

Some fields can be used in `filters` to narrow results but are **not returned**
in the search response — search is lightweight discovery, not full enrichment.
Filter on them, then fetch their values with
[Person Enrich](/person-docs/enrichment/introduction).
`skills.professional_network_skills` is the most common example — filterable here,
but only returned by Enrich.

| Field                                                | Filterable | Returned |
| ---------------------------------------------------- | ---------- | -------- |
| `basic_profile.summary`                              | Yes        | No       |
| `certifications.*` (name, issuer, dates, credential) | Yes        | No       |
| `honors.title`                                       | Yes        | No       |
| `skills.professional_network_skills`                 | Yes        | No       |

<Note>
  The reverse also holds for a few fields: the person's profile URL
  (`social_handles.professional_network_identifier.profile_url`) is **returned
  but not filterable**. To find people at a company, filter on the employer's
  company URL
  (`experience.employment_details.current.company_professional_network_profile_url`)
  instead.
</Note>

***

## Request parameter reference

| Parameter         | Type      | Required | Default     | Description                                                                                                                                                                                                                                                                                                                                         |
| ----------------- | --------- | -------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `filters`         | object    | Yes      | —           | Filter condition or condition group. See [operators](#filter-operator-reference) above.                                                                                                                                                                                                                                                             |
| `fields`          | string\[] | No       | Default set | Dot-path fields or section groups to return (e.g., `["basic_profile.name", "experience.employment_details.current.title"]`). When omitted, the default profile sections are returned. `skills` and `dev_platform_profiles` are **not returned by search** for any account — fetch skills via [Person Enrich](/person-docs/enrichment/introduction). |
| `sorts`           | array     | No       | `[]`        | Sort specifications as an array of `{ field, order }` objects. Use `asc` or `desc` for `order`. Required for stable pagination.                                                                                                                                                                                                                     |
| `limit`           | integer   | No       | 20          | Max profiles per page (1–1000).                                                                                                                                                                                                                                                                                                                     |
| `count`           | integer   | No       | —           | Alias for `limit`.                                                                                                                                                                                                                                                                                                                                  |
| `cursor`          | string    | No       | `null`      | Pagination cursor from previous response's `next_cursor`.                                                                                                                                                                                                                                                                                           |
| `post_processing` | object    | No       | —           | `exclude_profiles` (URL array) and `exclude_names` (name array).                                                                                                                                                                                                                                                                                    |
| `preview`         | boolean   | No       | `false`     | Premium feature — see [Preview mode](#preview-mode).                                                                                                                                                                                                                                                                                                |
| `return_query`    | boolean   | No       | `false`     | Debug flag accepted by the API. The response does not include a top-level `query` field.                                                                                                                                                                                                                                                            |

## Preview mode

<Card title="Preview mode" icon="lock" href="https://crustdata.com/demo">
  Preview search is a premium feature. Book a demo to enable it for your
  account.
</Card>

If preview access is enabled for your account, use `preview: true` to get lightweight results before running a full search. Preview responses keep the same top-level shape but may return fewer profile fields.

<Note>
  If preview is not enabled for your account,
  the API returns `400 invalid_request` with the message `error: PersonDB
        preview feature is not available for your account.`
</Note>

<CodeGroup>
  ```bash Preview search theme={"theme":"vitesse-black"}
  curl --request POST \
    --url https://api.crustdata.com/person/search \
    --header 'authorization: Bearer YOUR_API_KEY' \
    --header 'content-type: application/json' \
    --header 'x-api-version: 2025-11-01' \
    --data '{
      "filters": {
        "field": "experience.employment_details.title",
        "type": "(.)",
        "value": "Founder"
      },
      "preview": true,
      "limit": 1
    }'
  ```
</CodeGroup>

***

## Errors

| Status | Meaning                                                                                                          |
| ------ | ---------------------------------------------------------------------------------------------------------------- |
| `400`  | Invalid request — unsupported field, wrong operator, malformed filters, or preview not enabled for your account. |
| `401`  | Invalid or missing API key.                                                                                      |
| `403`  | Permission denied or insufficient credits.                                                                       |
| `500`  | Internal server error. Retry with exponential backoff.                                                           |

### No results

When no people match the filters, the API returns `200` with an empty `profiles` array:

```json theme={"theme":"vitesse-black"}
{
    "profiles": [],
    "next_cursor": null,
    "total_count": 0
}
```

**Action:** Broaden filters or check field values with [Autocomplete](/person-docs/autocomplete/introduction).

<Note>
  **Filter sizing.** To match many values of a field, put them all in a single
  `in` condition rather than many separate conditions — `in` compiles to one
  efficient query. A single `in` list of up to \~5,000–10,000 values returns in a
  few seconds; larger lists get progressively slower, and very large lists
  (roughly 50,000+) are rejected. For bigger sets, split the values into
  \~5,000–10,000 chunks across multiple requests and merge. The request body is
  hard-capped at **10 MB** (larger bodies return `413 request_too_large`),
  though with typical payloads you reach the query-size limit first.
</Note>

***

## API reference summary

| Detail         | Value                                                                            |
| -------------- | -------------------------------------------------------------------------------- |
| **Endpoint**   | `POST /person/search`                                                            |
| **Auth**       | Bearer token + `x-api-version: 2025-11-01`                                       |
| **Response**   | `{ "profiles": [...], "next_cursor": "...", "total_count": N }`                  |
| **Pagination** | Cursor-based. Pass `next_cursor` as `cursor`. Stop when `next_cursor` is `null`. |
| **Errors**     | `400`, `401`, `403`, `500`                                                       |

## Paginate through results

When your search matches more profiles than your `limit`, use cursor-based pagination to walk through all pages.

**First page:** send your normal search request.

<CodeGroup>
  ```bash First page theme={"theme":"vitesse-black"}
  curl --request POST \
    --url https://api.crustdata.com/person/search \
    --header 'authorization: Bearer YOUR_API_KEY' \
    --header 'content-type: application/json' \
    --header 'x-api-version: 2025-11-01' \
    --data '{
      "filters": {
        "field": "experience.employment_details.company_name",
        "type": "in",
        "value": ["Retool"]
      },
      "limit": 100
    }'
  ```
</CodeGroup>

**Next page:** take the `next_cursor` value from the response and pass it in your next request. Keep the same `filters` and `limit`.

<CodeGroup>
  ```bash Next page theme={"theme":"vitesse-black"}
  curl --request POST \
    --url https://api.crustdata.com/person/search \
    --header 'authorization: Bearer YOUR_API_KEY' \
    --header 'content-type: application/json' \
    --header 'x-api-version: 2025-11-01' \
    --data '{
      "filters": {
        "field": "experience.employment_details.company_name",
        "type": "in",
        "value": ["Retool"]
      },
      "limit": 100,
      "cursor": "PASTE_NEXT_CURSOR_VALUE_HERE"
    }'
  ```
</CodeGroup>

Continue until `next_cursor` is `null`, which means you have reached the last page.

<Warning>
  Always include `sorts` when paginating to ensure stable ordering across
  pages.
</Warning>

***

## Sort results

Use the `sorts` parameter to order results by a specific field. This is important for stable pagination.

<CodeGroup>
  ```bash Sort by connections (descending) theme={"theme":"vitesse-black"}
  curl --request POST \
    --url https://api.crustdata.com/person/search \
    --header 'authorization: Bearer YOUR_API_KEY' \
    --header 'content-type: application/json' \
    --header 'x-api-version: 2025-11-01' \
    --data '{
      "filters": {
        "field": "experience.employment_details.current.title",
        "type": "=",
        "value": "CEO"
      },
      "sorts": [{"field": "professional_network.connections", "order": "desc"}],
      "limit": 5,
      "fields": ["crustdata_person_id", "basic_profile.name"]
    }'
  ```
</CodeGroup>

The 16 sortable fields are: `crustdata_person_id`, `metadata.updated_at`, `basic_profile.name`, `basic_profile.location`, `basic_profile.location.city`, `basic_profile.location.state`, `basic_profile.location.country`, `basic_profile.location.full_location`, `professional_network.connections`, `professional_network.followers`, `experience.employment_details.start_date`, `experience.employment_details.company_id`, `experience.employment_details.company_headcount_latest`, `experience.employment_details.years_at_company_raw`, `recently_changed_jobs`, and `years_of_experience_raw`. Sorting on any other field returns `400`.

The **Sortable** column in [Searchable fields](#searchable-fields) marks these per
field, alongside whether each field is **Filterable**.

See the [full API reference](/openapi-specs/2025-11-01/introduction) for the complete OpenAPI schema
