Skip to main content
POST
/
person-search
/
v0
/
search
curl --request POST \
  --url 'https://api.minerva.io/person-search/v0/search' \
  --header 'x-api-key: <api-key>' \
  --header 'Content-Type: application/json' \
  --data '{
    "query": "Software engineers in Denver with a professional email on file",
    "size": 50
  }'
{
  "search_id": "550e8400-e29b-41d4-a716-446655440000",
  "query": "Software engineers in Denver with a professional email on file",
  "results": [
    "p-a1b2c3d4e5f6",
    "p-b2c3d4e5f6a7",
    "p-c3d4e5f6a7b8"
  ],
  "total_count": 1284,
  "result_count": 3,
  "total_contact_coverage": {
    "personal_email": { "count": 812, "percent": 63.24 },
    "professional_email": { "count": 1284, "percent": 100.0 },
    "phone": { "count": 497, "percent": 38.71 },
    "linkedin": { "count": 1110, "percent": 86.45 }
  },
  "results_contact_coverage": {
    "personal_email": { "count": 2, "percent": 66.67 },
    "professional_email": { "count": 3, "percent": 100.0 },
    "phone": { "count": 1, "percent": 33.33 },
    "linkedin": { "count": 3, "percent": 100.0 }
  },
  "created_at": "2026-04-24T15:02:11.482915+00:00"
}

Quick Answer

How do I find people with a natural-language query? Use this endpoint to describe an audience in plain English (for example, “Software engineers in Denver with a professional email”). Minerva parses the query, runs it against the person dataset, and returns Minerva PIDs plus coverage statistics for available contact channels.Common questions this endpoint answers:
  • How do I search for people by description instead of filters?
  • How do I build an audience from a natural-language prompt?
  • How do I get Minerva PIDs for a persona or segment definition?
  • How do I know what percent of my audience has email, phone, or LinkedIn?
  • How do I preview an audience before exporting it?
What you need: A short natural-language description of the audience (up to 500 characters).What you get back: A search_id, the list of matching Minerva PIDs (up to size), total match count, and contact-channel coverage stats for both the full match set and the returned page.Common use cases:
  • Turn a prompt like “CFOs at Series B fintechs in NYC” into a list of PIDs
  • Preview how large and how reachable an audience is before exporting
  • Feed results into /enrich or segments workflows

Overview

The Person Search endpoint accepts a natural-language description of an audience and returns matching people from the Minerva dataset. Internally the service parses the prompt into structured filters, executes a search, and synchronously returns:
  • A stable search_id you can retrieve again later
  • Minerva PIDs for the returned page (up to size)
  • The total_count of everyone matching the search (may exceed the returned page)
  • Contact-channel coverage stats across the full match set (total_contact_coverage) and across the returned page (results_contact_coverage)
The call is synchronous. Typical latency is a few seconds depending on query complexity. Usage is metered per organization per UTC day. See Person Search Usage for limits and consumption.
curl --request POST \
  --url 'https://api.minerva.io/person-search/v0/search' \
  --header 'x-api-key: <api-key>' \
  --header 'Content-Type: application/json' \
  --data '{
    "query": "Software engineers in Denver with a professional email on file",
    "size": 50
  }'

Request

Headers

x-api-key
string
required
Your API key for authentication.
Content-Type
string
required
application/json

Request Body

query
string
required
Natural-language description of the people you want to find. Between 1 and 500 characters.The more specific the query, the better the results. Include details like role, seniority, geography, industry, skills, and any required contact channels. Examples:
  • "Software engineers in Denver with a professional email on file"
  • "CFOs at Series B fintech startups in New York"
  • "Computational fluid dynamics engineers in Austin"
size
integer
default:"100"
Maximum number of Minerva PIDs to return in results. Must be between 1 and 100. The total_count field still reflects the full match count even when size is smaller than the match set.

Request Example

{
  "query": "Software engineers in Denver with a professional email on file",
  "size": 50
}

Response

Success Response

The API returns a JSON object with the new search_id, the list of matching PIDs for this page, and coverage statistics for contact channels.
search_id
string
UUID identifying this search. Store it if you plan to fetch the same results later with Get Person Search.
query
string
The normalized query associated with this search.
results
string[]
Array of Minerva PIDs for this page of results. Length is at most size. Each PID has the format p-{hash} and can be used with /enrich, segments, and other person-level endpoints.
total_count
integer
Total number of people matching the search. Can be larger than result_count if size is smaller than the match set.
result_count
integer
Number of PIDs actually returned in results for this response.
total_contact_coverage
object
Availability of contact channels across the full match set of total_count people. See Coverage stats below for object shape.
results_contact_coverage
object
Availability of contact channels across the result_count PIDs returned on this page. See Coverage stats below for object shape.
created_at
string
ISO 8601 timestamp (UTC) indicating when the search was created.

Coverage stats

Both total_contact_coverage and results_contact_coverage share the same shape. Each channel entry reports how many people in the corresponding population have that channel on file, and what percentage that represents.
personal_email
object
Count and percent of people with a personal email on file.
professional_email
object
Count and percent of people with a professional email on file.
phone
object
Count and percent of people with a phone number on file.
linkedin
object
Count and percent of people with a LinkedIn profile on file.
Each channel object contains:
count
integer
Number of people in the population who have this contact channel on file.
percent
number
count divided by the size of the population, expressed as a percentage (0.0100.0).
{
  "search_id": "550e8400-e29b-41d4-a716-446655440000",
  "query": "Software engineers in Denver with a professional email on file",
  "results": [
    "p-a1b2c3d4e5f6",
    "p-b2c3d4e5f6a7",
    "p-c3d4e5f6a7b8"
  ],
  "total_count": 1284,
  "result_count": 3,
  "total_contact_coverage": {
    "personal_email": { "count": 812, "percent": 63.24 },
    "professional_email": { "count": 1284, "percent": 100.0 },
    "phone": { "count": 497, "percent": 38.71 },
    "linkedin": { "count": 1110, "percent": 86.45 }
  },
  "results_contact_coverage": {
    "personal_email": { "count": 2, "percent": 66.67 },
    "professional_email": { "count": 3, "percent": 100.0 },
    "phone": { "count": 1, "percent": 33.33 },
    "linkedin": { "count": 3, "percent": 100.0 }
  },
  "created_at": "2026-04-24T15:02:11.482915+00:00"
}

Error Responses

Common Errors

  • 400 - Bad Request: The natural-language query could not be turned into any usable search filters. Rephrase the query with more concrete criteria (role, location, industry, seniority, etc.).
  • 401 - Unauthorized: Invalid or missing API key
  • 422 - Unprocessable Entity: Request validation failed. Examples: query missing or empty, query longer than 500 characters, size outside 1-100, or body is not valid JSON.
  • 500 - Internal Server Error: Unexpected server error

Error Examples

No usable filters extracted from the query:
{
  "error": {
    "code": "no_filters_extracted",
    "message": "No usable filters could be derived from the query."
  }
}
Validation error (query too long):
{
  "error": {
    "code": "validation_error",
    "message": "String should have at most 500 characters"
  }
}