Skip to main content
Person Semantic Search is currently in beta on POST /person/search. Request fields, ranking behavior, and query-constraint extraction may evolve based on feedback. To share input or request access, write to support@crustdata.co.
Use this when you want to search for people using natural language instead of building every filter by hand, for recruiting searches, persona discovery, market mapping, and exploratory lead lists. Person Semantic Search lets you pass a natural-language search.query to Person Search. Crustdata uses the query to rank matching people by profile context such as title, skills, company history, education, location, and summary text. You can also combine semantic ranking with structured filters.
This is current platform behavior for the live /person/search endpoint. The checked-in OpenAPI reference may not yet list the beta search object or top-level semantic mode field.

Where semantic search is available

APIRequest fieldNotes
Person SearchsearchAdd a natural-language query to rank and recall people semantically.
Person SearchmodeOptional top-level recall mode: managed (default) or exact.

At a glance

DetailValue
EndpointPOST https://api.crustdata.com/person/search
AuthAuthorization: Bearer YOUR_API_KEY
API versionx-api-version: 2025-11-01 header
Beta request fieldsearch.query
Retrieval modessearch.mode: hybrid (default), lexical, or semantic
Recall modestop-level mode: managed (default) or exact
ResponseSame paginated Person Search shape: profiles, next_cursor, total_count
PricingSame as Person Search: 0.03 credits per result
Rate limitSame as Person Search: 30 requests per minute

Structured filters are precise, but they force you to know the exact fields, operators, and indexed values before you search. That works for narrow queries, but it breaks down when your intent is broader:
  • Persona searches - “founding engineers at developer tools startups.”
  • Skill-heavy searches - “backend engineers with Golang and distributed systems experience.”
  • Job-description searches - paste the most important parts of a role and find similar profiles.
  • Exploratory recruiting - start with a plain-language role description, then tighten with filters.
Without semantic search, you need to manually translate those ideas into many field-specific filters.

The solution: natural-language ranking

Add a search object to a Person Search request:
{
    "search": {
        "query": "founding engineers at developer tools startups",
        "mode": "hybrid"
    },
    "limit": 10
}
The search.query is used to find and rank people whose profiles match the meaning of the query. You can send search by itself, or combine it with structured filters.
Do not send sorts with semantic search. Semantic results are already rank-ordered by relevance.

Retrieval modes

The nested search.mode field controls which retrieval signals are used for the natural-language query.
search.modeMeaningUse when
hybridCombines lexical keyword matching and semantic vector search.You want the best default for natural-language people search.
lexicalUses keyword matching only.You want exact terms, acronyms, names, or IDs to dominate.
semanticUses vector similarity only.You want concept matching even when profiles use different words.
hybrid is the default. Use it unless you have a specific reason to isolate keyword-only or vector-only behavior.

Recall modes

The top-level mode field controls how Crustdata combines your natural-language query with explicit filters.
modeBehaviorUse when
managed (default)Crustdata can extract extra constraints from the query and union them with your filters before reranking.You want better recall and are comfortable with adaptive results.
exactOnly your explicit filters define the hard result set. The query still ranks results inside that set.You need filters enforced as hard constraints or reproducible counts.
In managed mode, explicit filters are a recall and ranking signal, not always a hard global constraint. A strong profile can be returned if it matches constraints extracted from the natural-language query. Use mode: "exact" when every returned profile must satisfy your explicit filters.

Example: search from a natural-language query

This request finds people who match a plain-language recruiting query.
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 '{
    "search": {
      "query": "backend engineers with Golang and distributed systems experience",
      "mode": "hybrid"
    },
    "fields": [
      "basic_profile",
      "experience.employment_details.current"
    ],
    "limit": 5
  }'
The response uses the normal Person Search shape:
Response shape
{
    "profiles": [
        {
            "crustdata_person_id": 123,
            "basic_profile": {
                "name": "Example Person",
                "current_title": "Senior Backend Engineer"
            }
        }
    ],
    "next_cursor": "H4sIA...",
    "total_count": 1250
}
The response above shows shape only. Actual profile values depend on the query, requested fields, and account permissions.

Example: semantic ranking inside hard filters

Use mode: "exact" when your filters must be enforced. This example limits the result set to people in San Francisco, then uses the natural-language query to rank the best machine-learning profiles inside that set.
Request
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 '{
    "search": {
      "query": "machine learning engineers who have built recommender systems",
      "mode": "hybrid"
    },
    "mode": "exact",
    "filters": {
      "field": "basic_profile.location.full_location",
      "type": "(.)",
      "value": "San Francisco"
    },
    "fields": [
      "basic_profile",
      "experience.employment_details.current"
    ],
    "limit": 5
  }'
Use this pattern when you need deterministic membership for handoffs to agents, workflows, or downstream systems.

When to use each approach

You want toUse
Find people from a natural-language role or personasearch.query with search.mode: "hybrid"
Match concepts even when profiles use different wordingsearch.mode: "semantic"
Match exact terms, acronyms, names, or IDssearch.mode: "lexical"
Keep explicit filters as hard constraintstop-level mode: "exact"
Maximize recall and let Crustdata improve query parsingtop-level mode: "managed"
Build a fully deterministic filter queryFilter-only Person Search
Discover exact filter values before filteringPerson Autocomplete

What to do next