Skip to main content
Worked examples for Person Search. Each example is a full working request you can copy, paste, and adapt. For the core walkthrough (first search, combining filters with and), see Person Search. For the operator list, field catalog, and validation rules, see Search reference.
Replace YOUR_API_KEY in each example with your actual API key. All requests require the x-api-version: 2025-11-01 header.

Search by employer and title

This is the most common pattern for sales and recruiting: find people with a specific title at a specific company. This search finds VPs, Directors, and Heads of department at Retool.
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": {
      "op": "and",
      "conditions": [
        {
          "field": "experience.employment_details.company_name",
          "type": "in",
          "value": ["Retool"]
        },
        {
          "op": "or",
          "conditions": [
            { "field": "experience.employment_details.current.title", "type": "(.)", "value": "VP" },
            { "field": "experience.employment_details.current.title", "type": "(.)", "value": "Vice President" },
            { "field": "experience.employment_details.current.title", "type": "(.)", "value": "Director" },
            { "field": "experience.employment_details.current.title", "type": "(.)", "value": "Head of" },
            { "field": "experience.employment_details.current.title", "type": "(.)", "value": "Head" }
          ]
        }
      ]
    },
    "limit": 1
  }'
Response trimmed for clarity.

How the operators work

There are two different operators at play here:
  • in on experience.employment_details.company_name checks if the person has worked at any of the listed companies (current or past). Pass an array even for a single company. To search only current employers, use experience.employment_details.current.company_name instead.
  • (.) on experience.employment_details.title does a regex match. The pipe | means “or”, so VP|Director|Head of matches any title containing “VP”, “Director”, or “Head of”. To search only current titles, use experience.employment_details.current.title instead.
The experience.employment_details.company_name field includes all employers (current and past). If you see someone whose current role is at a different company, it means they previously worked at your target company.

Find people at a company by its profile URL

When you know a company’s profile URL but not its exact name, filter on the employer’s profile URL. Names can be ambiguous; the profile URL is exact, so this is the most reliable way to target one specific company. Lead with the current-employer field to find people who currently work there:
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.company_professional_network_profile_url",
      "type": "=",
      "value": "https://www.linkedin.com/company/stripe"
    },
    "limit": 1
  }'
Response trimmed for clarity.
The value must be the exact, full profile URL — for example https://www.linkedin.com/company/stripe. A trailing slash (.../stripe/), a missing scheme (linkedin.com/company/stripe), or a bare slug (stripe) all return zero results.

Current, former, or either

  • Current employeesexperience.employment_details.current.company_professional_network_profile_url
  • Former employeesexperience.employment_details.past.company_professional_network_profile_url
  • Anyone who has ever worked there — combine both with an or group:
{
    "filters": {
        "op": "or",
        "conditions": [
            { "field": "experience.employment_details.current.company_professional_network_profile_url", "type": "=", "value": "https://www.linkedin.com/company/stripe" },
            { "field": "experience.employment_details.past.company_professional_network_profile_url", "type": "=", "value": "https://www.linkedin.com/company/stripe" }
        ]
    },
    "limit": 25
}
To target several companies at once, use the in operator with an array of profile URLs.
The bare experience.employment_details.company_professional_network_profile_url path (all employers) is not filterable — use the current. or past. variants above. The accepted alias ...company_linkedin_profile_url resolves to the same data.

Exclude specific titles

Sometimes you want everyone at a company except certain roles. Use the not_in operator to exclude titles. This search finds people at OpenAI or Retool but excludes interns and students.
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": {
      "op": "and",
      "conditions": [
        {
          "field": "experience.employment_details.company_name",
          "type": "in",
          "value": ["OpenAI", "Retool"]
        },
        {
          "field": "experience.employment_details.title",
          "type": "not_in",
          "value": ["Intern", "Student"]
        }
      ]
    },
    "limit": 2
  }'
The not_in operator removes any profile where one of the listed values appears in their title history. This is useful for cleaning up results in recruiting or sales workflows.

Search within a geographic radius

The geo_distance filter finds people within a specific distance of a city. This is powerful for territory-based sales or local recruiting. This search finds CTOs within 10 miles of San Francisco.
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": {
      "op": "and",
      "conditions": [
        {
          "field": "professional_network.location.raw",
          "type": "geo_distance",
          "value": {
            "location": "San Francisco",
            "distance": 10,
            "unit": "mi"
          }
        },
        {
          "field": "experience.employment_details.current.title",
          "type": "(.)",
          "value": "CTO|Chief Technology"
        }
      ]
    },
    "limit": 1
  }'
Response trimmed for clarity.

How geo_distance works

The geo_distance filter uses the professional_network.location.raw field. The value is an object whose centre is given as either a location string (geocoded server-side) or an explicit lat_lng pair (which skips geocoding). If both are supplied, lat_lng wins.
FieldRequiredDescription
locationone ofCity or region name geocoded server-side (e.g., "San Francisco", "London", "New York")
lat_lngone ofExplicit [lat, lng]. Lat in [-90, 90], lng in [-180, 180]. Bypasses geocoding.
distanceYesRadius from the centre point. Must be positive.
unitNoOne of km, mi, miles, m, meters, ft, feet. Defaults to km.

Search by explicit coordinates

Use lat_lng when you already have coordinates (for example, from a map picker) or you want to skip the geocoding step. The example below finds people within 5 km of latitude 37.7749, longitude -122.4194 (downtown San Francisco).
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": "professional_network.location.raw",
      "type": "geo_distance",
      "value": {
        "lat_lng": [37.7749, -122.4194],
        "distance": 5,
        "unit": "km"
      }
    },
    "limit": 5
  }'

Exclude profiles matching a substring

Use (!) when you want to drop profiles whose value contains a particular phrase — useful when not_in is too rigid (it requires exact values) and you want a substring-style exclusion instead. This search finds VP-level people at Retool, then drops anyone whose headline mentions “Investor” or “Advisor”.
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": {
      "op": "and",
      "conditions": [
        {
          "field": "experience.employment_details.current.company_name",
          "type": "=",
          "value": "Retool"
        },
        {
          "field": "experience.employment_details.current.title",
          "type": "(.)",
          "value": "VP"
        },
        {
          "field": "basic_profile.headline",
          "type": "(!)",
          "value": "Investor"
        },
        {
          "field": "basic_profile.headline",
          "type": "(!)",
          "value": "Advisor"
        }
      ]
    },
    "limit": 5
  }'
(!) matches a multi-word value as a literal phrase. (!) "New York" excludes only profiles that literally contain "New York" — it does not exclude "New Yorker". To exclude on each word independently, send a separate (!) condition for each word inside an and group, as shown above.

Search by country

For broader geographic targeting, filter by country directly.
basic_profile.location.country uses full country names, such as "United States" or "India".
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": "basic_profile.location.country",
      "type": "=",
      "value": "United States"
    },
    "limit": 2
  }'
This returns all people located in the United States. With 125M+ matching profiles, you will want to combine this with title or employer filters to narrow results.

Search by employer headquarters country

Use company_headquarters_country when you want to filter by where a person’s current or past employer is headquartered.
Note: company_headquarters_country uses ISO-3 codes (USA, IND, GBR), unlike basic_profile.location.country which uses full names. Use ISO 3166-1 alpha-3 codes for the current, past, and all-role headquarters country fields. See the ISO 3166-1 alpha-3 country code list for accepted codes.
This search finds founders or co-founders whose current employer is headquartered in the United States and who previously worked at an employer headquartered in India.
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": {
      "op": "and",
      "conditions": [
        {
          "op": "or",
          "conditions": [
            {
              "field": "experience.employment_details.current.title",
              "type": "(.)",
              "value": "Founder"
            },
            {
              "field": "experience.employment_details.current.title",
              "type": "(.)",
              "value": "Co-Founder"
            }
          ]
        },
        {
          "field": "experience.employment_details.current.company_headquarters_country",
          "type": "=",
          "value": "USA"
        },
        {
          "field": "experience.employment_details.past.company_headquarters_country",
          "type": "=",
          "value": "IND"
        }
      ]
    },
    "limit": 10
  }'

Exclude specific people from results

Use post_processing to remove known profiles from results. This is useful when re-running searches and you want to skip people you have already contacted.
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"
    },
    "limit": 5,
    "post_processing": {
      "exclude_names": ["Ali Kashani"],
      "exclude_profiles": ["https://www.linkedin.com/in/alikashani"]
    }
  }'
You can exclude by name, by profile URL, or both.

Build a profile card with company and school logos

Person Search returns stable Crustdata-hosted logo permalinks for employers (company_profile_picture_permalink) and schools (institute_logo_permalink), so you can render a profile card without resolving image URLs yourself. Request the experience and education sections for the person you want.
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": "crustdata_person_id", "type": "=", "value": 14540 },
    "fields": ["basic_profile", "experience", "education"],
    "limit": 1
  }'
company_profile_picture_permalink and institute_logo_permalink are returned for display only — they are not searchable fields.

Next steps