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"
}
{
"code": "no_filters_extracted",
"message": "No usable filters could be derived from the query.",
"api_request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
{
"code": "unauthorized",
"message": "Unauthorized",
"api_request_id": "b2c3d4e5-f6a7-1234-bcde-f12345678901"
}
{
"code": "forbidden",
"message": "Not authorized for this route or plan",
"api_request_id": "c3d4e5f6-a7b8-2345-cdef-123456789012"
}
{
"code": "validation_error",
"message": "Invalid request data",
"api_request_id": "d4e5f6a7-b8c9-3456-def0-234567890123",
"details": [
{
"loc": ["query"],
"type": "string_too_long"
}
]
}
{
"code": "rate_limit_reached",
"message": "You reached your total request-rate limit, please contact help@minerva.io for help",
"api_request_id": "e5f6a7b8-c9d0-4567-ef01-345678901234"
}
Person Search
Person Search
Find people using a natural-language audience description and return matching Minerva PIDs with contact-channel coverage stats
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"
}
{
"code": "no_filters_extracted",
"message": "No usable filters could be derived from the query.",
"api_request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
{
"code": "unauthorized",
"message": "Unauthorized",
"api_request_id": "b2c3d4e5-f6a7-1234-bcde-f12345678901"
}
{
"code": "forbidden",
"message": "Not authorized for this route or plan",
"api_request_id": "c3d4e5f6-a7b8-2345-cdef-123456789012"
}
{
"code": "validation_error",
"message": "Invalid request data",
"api_request_id": "d4e5f6a7-b8c9-3456-def0-234567890123",
"details": [
{
"loc": ["query"],
"type": "string_too_long"
}
]
}
{
"code": "rate_limit_reached",
"message": "You reached your total request-rate limit, please contact help@minerva.io for help",
"api_request_id": "e5f6a7b8-c9d0-4567-ef01-345678901234"
}
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?
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
/enrichor 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_idyou can retrieve again later - Minerva PIDs for the returned page (up to
size) - The
total_countof 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)
Writing good queries
The query is a natural-language audience description — not a lookup of a specific named person. Best results come from describing the attributes the people share. The parser handles these attribute categories well:| Category | Examples |
|---|---|
| Role / job title | ”engineers”, “CFOs”, “senior product managers”, “VPs of engineering” |
| Industry | ”fintech”, “biotech”, “SaaS”, “venture capital” |
| Company | named companies (“Google”, “Stripe”), groupings (“FAANG companies”), or stage (“Series B startups”) |
| Career history | ”previously worked at Meta”, “former Apple engineers”, “left a Series A in 2024” |
| Location | cities, regions, or countries (“in NYC”, “Bay Area”, “based in Germany”) |
| Education | school + major + level (“CS degrees from MIT”, “Harvard MBAs”) |
| Age | ranges or descriptive (“30–40 years old”, “in their 50s”) |
| Income / wealth | ”earning over 200k”, “own homes worth over 1M” |
| Contact-channel constraints | ”with a professional email on file”, “have a verified LinkedIn” |
and / or / not) and nested groups work too — the
parser turns “MIT or Stanford CS grads” into the right OR group
automatically.
Three example queries
Three patterns that cover most real audience definitions. Each maps to a shape the parser handles cleanly out of the box.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
}'
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": "CFOs at Series B fintech startups in NYC",
"size": 100
}'
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": "Engineers at FAANG companies with CS degrees from MIT or Stanford, 30-40 years old, who own homes worth over 1M",
"size": 100
}'
Tips
- Describe attributes, not specific people. A lookup of “John Doe at
Acme Inc.” is a PII match — use
/v2/resolvefor that. Person Search is for audience definitions (“engineers at SaaS companies”). - Be specific about role + company. Adding “at Google” or “in fintech” narrows the result set materially vs. a bare role.
- Combine 4–6 attributes for high-precision audiences. Each additional filter sharpens the segment.
- Add a contact-channel constraint (e.g. “with a professional email”) when you need to reach the audience — guarantees the returned PIDs are actually reachable on that channel.
- Stay under 500 characters. The endpoint validates
querylength (see Request Body).
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
string
required
Your API key for authentication.
string
required
application/jsonRequest Body
string
required
Natural-language description of the people you want to find. Between 1 and 500 characters. See Writing good queries for supported attribute categories and worked examples.
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 newsearch_id, the list of matching PIDs for this page, and coverage statistics for contact channels.
string
UUID identifying this search. Store it if you plan to fetch the same results later with Get Person Search.
string
The normalized query associated with this search.
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.integer
Total number of people matching the search. Can be larger than
result_count if size is smaller than the match set.integer
Number of PIDs actually returned in
results for this response.object
Availability of contact channels across the full match set of
total_count people. See Coverage stats below for object shape.object
Availability of contact channels across the
result_count PIDs returned on this page. See Coverage stats below for object shape.string
ISO 8601 timestamp (UTC) indicating when the search was created.
Coverage stats
Bothtotal_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.
object
Count and percent of people with a personal email on file.
object
Count and percent of people with a professional email on file.
object
Count and percent of people with a phone number on file.
object
Count and percent of people with a LinkedIn profile on file.
integer
Number of people in the population who have this contact channel on file.
number
count divided by the size of the population, expressed as a percentage (0.0–100.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"
}
{
"code": "no_filters_extracted",
"message": "No usable filters could be derived from the query.",
"api_request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
{
"code": "unauthorized",
"message": "Unauthorized",
"api_request_id": "b2c3d4e5-f6a7-1234-bcde-f12345678901"
}
{
"code": "forbidden",
"message": "Not authorized for this route or plan",
"api_request_id": "c3d4e5f6-a7b8-2345-cdef-123456789012"
}
{
"code": "validation_error",
"message": "Invalid request data",
"api_request_id": "d4e5f6a7-b8c9-3456-def0-234567890123",
"details": [
{
"loc": ["query"],
"type": "string_too_long"
}
]
}
{
"code": "rate_limit_reached",
"message": "You reached your total request-rate limit, please contact help@minerva.io for help",
"api_request_id": "e5f6a7b8-c9d0-4567-ef01-345678901234"
}
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 key403- Forbidden: The API key is valid but not authorized for this route or your plan tier422- Unprocessable Entity: Request validation failed. Examples:querymissing or empty,querylonger than 500 characters,sizeoutside1-100, or body is not valid JSON.429- Too Many Requests: Rate limit or plan quota exceeded500- Internal Server Error: Unexpected server error
Error Examples
No usable filters extracted from the query:{
"code": "no_filters_extracted",
"message": "No usable filters could be derived from the query.",
"api_request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
{
"code": "validation_error",
"message": "Invalid request data",
"api_request_id": "b2c3d4e5-f6a7-1234-bcde-f12345678901",
"details": [
{
"loc": ["query"],
"type": "string_too_long"
}
]
}
Related Endpoints
- Get Person Search - Retrieve a previously created search by
search_id - Async Person Search - Materialize a complete segment, inspect its size, then unlock and page PIDs
- Person Search Usage - Daily delivery limits and consumption history
- Contact Append - Async ABM contacts at target companies
- Contact Prospect - Async contacts by NAICS + title
- Contact Job Status - Poll contact-append / contact-prospect jobs
- Contact Job Results - Unlock (bill) and page contact job results
- Enrich v2 - Fetch full profile data for the Minerva PIDs returned here
- Add Members to Segment - Persist search results into a segment for tracking
Was this page helpful?