Skip to main content
The Person Search API lets you find professionals by name, title, company, location, and more. This page walks you through the basics: your first search, the response shape, and combining filters — plus worked example recipes you can copy, paste, and adapt. For the operator list, field catalog, and validation rules, see Search reference. Every request goes to the same endpoint:
Replace YOUR_API_KEY in each example with your actual API key. All requests require the x-api-version: 2025-11-01 header.
Pricing: 0.03 credits per result returned.
Looking for the list of fields you can filter on? See Searchable fields in the search reference for the full table of filters.field values grouped by family, plus a one-line trick to fetch the live list from the API.

Examples

Employer + title, geo radius, country, and post-processing exclusions.

Pagination & sorting

Cursor-based pagination and sort rules for stable ordering.

Reference

Operators, searchable fields, response fields, preview mode, errors.

Your first search: find a person by name

The simplest search finds a person by their exact name. You pass a single filter with the = operator.
Response trimmed for clarity.

Understanding the response

Every search response has three fields:
  • profiles — an array of matching people. Each profile contains identity fields, education, profile handles, and contact availability flags for the fields you requested.
  • total_count — how many people match your filters across the full database. Here, 8 people named “Abhilash Chowdhary” exist.
  • next_cursor — a pagination token. Pass it in the next request to get the next page of results. null means there are no more pages.

Combine filters with and

Real searches need more than one criterion. Wrap multiple conditions inside an op: "and" group to require all of them. This search finds Co-Founders located in San Francisco. The (.) operator does a fuzzy token match instead of an exact match. This makes it tolerant to typos.
Response trimmed for clarity.
The key difference from the first example: instead of a single filters object, you now have a group with op: "and" and a conditions array. Every condition must match for a profile to be included. For more filter patterns (employer + title, geo radius, excludes), see the example requests below. To walk through large result sets, see Pagination and sorting.

Read normalized titles and education details

Each profile also returns a normalized title classification and structured education — including school location and a Crustdata-hosted institution logo. Request the sections you need with fields, and filter by crustdata_person_id to fetch a single person.
basic_profile.normalized_title and education.schools.location are filterable but not sortable. professional_network.followers and professional_network.connections are filterable and sortable, but they are not returned in the search response — use them to narrow or rank results, not to read counts. School description and institute_logo_permalink are returned for display only.

Example Requests

Common filter patterns for Person Search. Each is a full, tested request against POST /person/search that you can copy, paste, and adapt. Click any row to expand it.
Find people by exact title match:
= and in match the full title string exactly. "Chief Information Security Officer" will not match people titled “Deputy Chief Information Security Officer” or “SVP and CISO”. For substring or word matching — the common case for titles — use the (.) operator, as in the next example.
Find people whose headline contains “founder” (case-insensitive contains match):
Find people with more than 10 years of experience:
Find well-connected people who recently changed jobs:
Find professionals in a region, excluding certain employers and titles:
Find senior people (VP, Director, or CXO) with 10+ years of experience at companies under 1,000 employees:
Find people who started a role at a public company since 2023:
Find Stanford alumni (non-Bachelor degree) skilled in machine learning:

Semantic search (natural language)

Instead of hand-building filters, pass a natural-language search.query to rank people by overall profile meaning. search.mode controls how matching works — including a keyword (lexical) mode and a semantic mode: Every result carries a relevance fit tier (strong, possible, or weak). Responses use the standard Person Search shape plus fit and total_count_relation:
Response shape
Semantic search is in beta. Don’t send sorts — results are already rank-ordered by relevance. For recall modes (managed vs exact) and the full behavior, see the Person Semantic Search guide.
The default. Describe who you want in plain language; hybrid blends keyword and semantic matching for the best general-purpose recall.
Use lexical when exact terms, acronyms, tools, or names should dominate — keyword matching only, no vector similarity.
For precise keyword search, set search.query_syntax: "boolean" to turn the query into a boolean expression: a space means AND, | means OR, + requires a term, - excludes a term, "…" matches an exact phrase, * matches a prefix, and () groups operators. Honored only with search.mode: "lexical" and the top-level recall mode: "exact".
See the Person Semantic Search guide for the full operator reference.
Use semantic to match the meaning of a query even when profiles use different words — vector similarity only.
Enforce explicit filters as hard constraints, then rank inside that set with the query using the top-level mode: "exact".

More recipes

Each recipe below is a full walkthrough with a tested request. Expand any one to see the pattern, the response, and how the operators work.
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.
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.
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:
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:
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.
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.
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.
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.
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.

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).
The geo_exclude filter is the inverse of geo_distance — it removes people inside the radius and keeps everyone else. Use it to carve out a metro you already cover, or to find candidates outside a relocation zone.This search finds engineers in the United States who are not within 50 km of San Francisco.
geo_exclude accepts the same value object as geo_distance (location or lat_lng, a required distance, and an optional unit), so you can also exclude a radius around explicit coordinates.
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”.
(!) 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.
For broader geographic targeting, filter by country directly.
basic_profile.location.country uses full country names, such as "United States" or "India".
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.
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.
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.
You can exclude by name, by profile URL, or both.
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.
company_profile_picture_permalink and institute_logo_permalink are returned for display only — they are not searchable fields.
When you have a company’s website domain but not its exact display name, filter on the employer’s domain. Lead with the current-employer field to find people who currently work there.
Response trimmed for clarity. The response carries the employer’s full website URL under company_website — the company_website_domain paths are filter-side names and do not appear in search responses.
To target several companies at once, switch to the in operator with an array of domains. For current employees use the current. field above; for former employees use experience.employment_details.past.company_website_domain; for anyone who has ever worked there, use the all-roles field experience.employment_details.company_website_domain.
Combine the recently_changed_jobs flag with a current-employer filter to surface people who recently started at a target company — a strong signal for sales and recruiting outreach.
Response trimmed for clarity.
recently_changed_jobs is a boolean — pair it with a current. employer or title filter to scope the signal to the population you care about. It is both filterable and sortable.
To find individual contributors only, use not_in on the all-roles career-history paths (experience.employment_details.seniority_level and experience.employment_details.title). On these all-employers fields, not_in drops anyone who has ever held that seniority or title at any point in their career — not just in their current role.
This keeps people whose current title contains “engineer” but excludes anyone who has ever been a VP/Director/CXO or held a founder/CEO-level title. Because the exclusions are on the all-roles paths, a single past executive stint is enough to remove a profile.
Use not_in on the all-roles experience.employment_details.company_name path to remove anyone who has ever worked at a named company — current or past. This is the cleanest way to screen out competitor alumni from a candidate or prospect list.
The all-roles company_name path covers current and past employers, so this excludes a profile if Google or Meta appears anywhere in their work history. For exact-company precision, prefer the company profile-URL paths (...company_professional_network_profile_url) over names.
Stack filters to source founders for an investor pipeline: a founder/CEO title, a target school, a recent current-role start date (a proxy for a recently founded company), and a country. Each layer narrows the universe.
Response trimmed for clarity. basic_profile.location.country uses full country names; current.start_date accepts ISO date strings with the => (greater-than-or-equal) operator.
Filter on where a person’s past and current employers are headquartered to find cross-border movers — for example, engineers who once worked at India-headquartered companies and are now at US-headquartered ones. Headquarters-country fields use ISO 3166-1 alpha-3 codes (IND, USA).
Response trimmed for clarity. Note that the person’s location and the employer’s headquarters country are independent — this person is based in the Netherlands while their employers are US- and India-headquartered.
For the broadest geographic targeting, filter on basic_profile.location.continent. It takes a full continent name such as "Europe", "Asia", or "North America".
This returns founders located anywhere in Europe (total_count 1,055,157 at time of writing). Combine continent with title, employer, or country filters to narrow a large pool. basic_profile.location.continent is filterable but not sortable.
To find people who worked at both of two named companies, target one as the current employer and the other as a past employer. Use the slot-specific paths experience.employment_details.current.company_name and experience.employment_details.past.company_name.
Response trimmed for clarity.
This pattern works because each company is matched against a different employment slot (current. vs past.). Putting two different company names in two = conditions on the same all-roles path (experience.employment_details.company_name) returns zero results — a single employment record can’t equal both names at once.
Filter on experience.employment_details.current.business_email_verified to keep only profiles where a business email on the current role has been verified — useful when you plan to enrich and reach out by email.
Response trimmed for clarity. business_email_verified is filterable on the current, past, and all-roles paths but is not returned in standard search results — retrieve the actual email with Contact Enrich.
Add a sorts array to order results. This finds everyone associated with Retool and ranks them by professional-network followers, highest first. Request the fields you want to read alongside the sort key.
Response trimmed for clarity.
professional_network.followers is filterable and sortable, but it is not returned in results — the sort ranks profiles by follower count without exposing the count itself. Always include a sorts array when paginating so ordering stays stable across pages — see Pagination and sorting.
Preview mode returns lightweight results so you can sanity-check a filter and read total_count before committing to a full search. Set preview: true alongside your normal filters.
Preview is a premium feature. To enable it for your account, reach out to gtm@crustdata.co. If preview is not enabled, the API returns 400 invalid_request with the message PersonDB preview feature is not available for your account.
Response trimmed for clarity.
Preview responses keep the same top-level shape as a normal search — profiles, next_cursor, and total_count — but each profile carries a reduced field set. See Preview mode in the search reference.

What to do next

  • Try more filter patterns — see the example requests above for employer + title, geo radius, and exclude patterns.
  • Paginate and sort — see Pagination and sorting to walk through every matching profile in a stable order.
  • Look up operators and fields — see Search reference for operators, searchable fields, response fields, request parameters, and errors.
  • Enrich a profile — once you have a profile URL from search, use Person Enrich to get the full cached profile.
  • Discover filter values — use Person Autocomplete to find exact indexed values for search filters before building a filter.
  • Check the API reference — see the OpenAPI spec for the full schema.