Skip to main content

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.

POST /screener/persondb/search
POST /person/search
This page lists every behavioral and contract change between the legacy person-search endpoint and the current one. Use it as a side-by-side reference when porting an integration; each section gives the old shape, the new shape, and the smallest edit that closes the gap.
TopicLegacyCurrent
PathPOST /screener/persondb/searchPOST /person/search
AuthAuthorization: Bearer <key>Authorization: Bearer <key>
Version(not required)x-api-version: 2025-11-01 (required)
Base URLhttps://api.crustdata.comhttps://api.crustdata.com
The x-api-version header is required on every request to /person/search. Calls without it are rejected. The legacy endpoint did not use this header.

1. Request body — top-level keys

KeyLegacyCurrentNotes
filtersobjectobjectGrammar changed — see Filter grammar below.
sortsarray of {column, order}array of {field, order}column renamed to field.
limitinteger 1–1000, default 20integer 1–1000, default 20Unchanged.
countinteger alias for limitinteger alias for limitUnchanged.
cursorstring nullablestring nullableUnchanged.
fields(not supported)string[]New — request a subset of response sections via dot-paths.
post_processing{ exclude_profiles, exclude_names }{ exclude_profiles, exclude_names }Same shape. exclude_profiles still accepts the same profile-URL list.
previewbooleanbooleanUnchanged.
searchobject (semantic / hybrid)(removed)Semantic/hybrid search has no replacement on this endpoint — see Removed features.
single_queryboolean (debug)(removed)Removed.
return_queryboolean (debug)boolean (accepted, response does not include query)Behavioral change.

2. Filter grammar

The condition key changed from column to field. Operator names and the and/or group shape are unchanged.
{
    "column": "current_employers.title",
    "type": "=",
    "value": "CEO"
}
Two changes per condition:
  1. Rename columnfield.
  2. Map the legacy field name to the new dataset path (see Field-name mapping).

Operators

OperatorLegacyCurrentNotes
=
!=
<, >
=<, =>>= and <= are not supported — use => / =<.
in, not_inValue must be an array.
(.)Fuzzy / all-words match.
[.]Exact phrase match.
geo_distance✅ (only on region)✅ (only on professional_network.location.raw)Field renamed; payload { location, distance, unit } unchanged.
is_null, is_not_null(not implemented)Filter for null client-side using fields.

and / or groups

The group shape is unchanged — op: "and" or op: "or" plus a conditions array. Only the leaf-condition key (columnfield) and the leaf field names need to change.

3. Field-name mapping

The legacy endpoint exposed flat names like name, region, and current_employers.title. The current endpoint uses structured dataset paths under basic_profile, experience.employment_details, education, etc.

Identity and location

Legacy fieldCurrent field
namebasic_profile.name
first_namebasic_profile.first_name
last_namebasic_profile.last_name
headlinebasic_profile.headline
summarybasic_profile.summary
languagesbasic_profile.languages
regionprofessional_network.location.raw (also accepted as basic_profile.location.full_location alias)
location_citybasic_profile.location.city
location_statebasic_profile.location.state
location_countrybasic_profile.location.country
location_continentbasic_profile.location.continent

Skills and connections

Legacy fieldCurrent field
skillsskills.professional_network_skills
num_of_connectionsprofessional_network.connections
open_to_cardsprofessional_network.open_to_cards
twitter_handlesocial_handles.twitter_identifier.slug

Employment — current role

The legacy current_employers.* array maps to experience.employment_details.current.*. Same keys, new prefix.
Legacy fieldCurrent field
current_employers.name / .company_nameexperience.employment_details.current.name
current_employers.company_idexperience.employment_details.current.company_id
current_employers.titleexperience.employment_details.current.title
current_employers.seniority_levelexperience.employment_details.current.seniority_level
current_employers.function_categoryexperience.employment_details.current.function_category
current_employers.start_dateexperience.employment_details.current.start_date
current_employers.company_website_domainexperience.employment_details.current.company_website_domain
current_employers.company_headcount_rangeexperience.employment_details.current.company_headcount_range
current_employers.company_headcount_latestexperience.employment_details.current.company_headcount_latest
current_employers.company_industriesexperience.employment_details.current.company_industries
current_employers.company_linkedin_industryexperience.employment_details.current.company_professional_network_industry
current_employers.company_typeexperience.employment_details.current.company_type
current_employers.company_hq_locationexperience.employment_details.current.company_hq_location
current_employers.company_headquarters_countryexperience.employment_details.current.company_headquarters_country
current_employers.business_email_verifiedexperience.employment_details.current.business_email_verified
current_employers.years_at_company_rawexperience.employment_details.current.years_at_company_raw

Employment — past roles

The legacy past_employers.* array maps to experience.employment_details.past.* with the same suffix conventions as the current role. The legacy all_employers.* (current and past combined) maps to experience.employment_details.* without the current/past segment.

Education, certifications, honors

Legacy fieldCurrent field
education_background.institute_nameeducation.schools.school
education_background.degree_nameeducation.schools.degree
education_background.field_of_studyeducation.schools.field_of_study
certifications.namecertifications.name
certifications.issued_datecertifications.issue_date
certifications.expiration_datecertifications.expiration_date
certifications.issuer_organizationcertifications.issuing_organization
honors.titlehonors.title

Contact and identity flags

Legacy fieldCurrent field
emails(not filterable; surfaced via Person Enrich)
business_emails(not filterable on search; use experience.employment_details.business_email_verified boolean filter)
person_idcrustdata_person_id
recently_changed_jobsrecently_changed_jobs
years_of_experience_rawyears_of_experience_raw
For the full searchable-field catalog, see Person Search reference.

4. Response shape

The response envelope keeps the same top-level keys, but each profile object moved from a flat structure to a nested one.

Envelope

KeyLegacyCurrent
profilesarray of profilesarray of profiles
next_cursorstring | nullstring | null
total_countinteger | nullinteger | null
querypresent when return_query: true(not returned)

Profile object

Legacy profiles returned a flat object with keys like name, linkedin_profile_url, current_employers, education_background. Current profiles group those fields into named sections:
{
    "person_id": 14540,
    "name": "David Hsu",
    "headline": "Founder, CEO @ Retool",
    "region": "San Francisco Bay Area",
    "linkedin_profile_url": "https://www.linkedin.com/in/dvdhsu",
    "current_employers": [
        { "name": "Retool", "title": "Founder, CEO" }
    ],
    "education_background": [
        { "institute_name": "Oxford" }
    ]
}

Response-key map

Legacy keyCurrent key
person_idcrustdata_person_id
namebasic_profile.name
headlinebasic_profile.headline
summarybasic_profile.summary
regionbasic_profile.location.raw
location_city / _state / _country / _continentbasic_profile.location.{city,state,country,continent}
linkedin_profile_urlsocial_handles.professional_network_identifier.profile_url
twitter_handlesocial_handles.twitter_identifier.slug
skillsskills.professional_network_skills
num_of_connectionsprofessional_network.connections
current_employers[]experience.employment_details.current[]
past_employers[]experience.employment_details.past[]
education_background[]education.schools[]
certifications[]certifications[]
honors[]honors[]
Use the fields request parameter to request just the sections you need (for example, fields: ["basic_profile.name", "experience.employment_details.current.title"]). This keeps responses small and avoids parsing sections you do not use. See Response fields.

5. Removed features

Semantic search (search parameter)

The legacy endpoint accepted a top-level search object that ran a natural-language query against an embedding model:
{
    "search": {
        "query": "engineers who like climbing",
        "mode": "hybrid",
        "min_similarity": 0.2
    }
}
The current endpoint does not accept search. Sending it returns 400. Use structured filters in filters instead, or contact support@crustdata.co if you need semantic retrieval for an account.

single_query debug flag

Removed. The flag had no externally documented behavior.

is_null / is_not_null operators

Currently not implemented on the new endpoint. To detect null presence:
  1. Request the field via fields.
  2. Filter for null in your client code.

6. Added features

FeatureDescription
fields parameterRequest only the dot-paths you need (e.g. ["basic_profile.name", "experience.employment_details.current.title"]).
Nested response sectionsProfiles return structured basic_profile, experience, education, contact, social_handles, skills, professional_network sections.
Stable error envelopeAll 4xx/5xx errors return { "error": { "type", "message", "metadata" } } (legacy returned { "error": "...", "details": {...} }).
metadata.updated_at filterNew sortable, filterable timestamp marking when the profile record was last refreshed.
Contact availability flagscontact.has_business_email, contact.has_personal_email, and contact.has_phone_number summarize contact availability in the search response.
Discoverable filter valuesPerson Autocomplete returns valid indexed values for any supported field.

7. Error responses

The error envelope changed shape. Status codes are unchanged (400, 401, 403, 500).
{
    "error": "Unsupported column 'job_title'",
    "details": { "supported_columns": ["name", "headline", "..."] }
}
401 continues to use a flat { "message": "Invalid API key in request" } shape — parse based on HTTP status.

8. End-to-end example

The same query — Co-Founders in San Francisco — written against both endpoints.
curl --request POST \
  --url https://api.crustdata.com/screener/persondb/search \
  --header 'authorization: Bearer YOUR_API_KEY' \
  --header 'content-type: application/json' \
  --data '{
    "filters": {
      "op": "and",
      "conditions": [
        { "column": "current_employers.title", "type": "(.)", "value": "Co-Founder" },
        { "column": "region",                   "type": "(.)", "value": "San Francisco" }
      ]
    },
    "limit": 2
  }'

Migration checklist

  • Replace base path /screener/persondb/search/person/search.
  • Add x-api-version: 2025-11-01 header to every request.
  • Rename columnfield in every filter condition.
  • Rename columnfield in every sort directive.
  • Map legacy field names to the current dataset paths (see Field-name mapping).
  • Drop the search parameter (semantic mode is no longer accepted).
  • Drop the single_query debug flag.
  • Replace is_null / is_not_null operators with client-side null checks.
  • Update response parsing for the nested profile shape (see Response-key map).
  • Update error handlers for the new error.type / error.message envelope.

See also