Context.dev People Search (POST https://api.context.dev/v1/people/search) finds professionals who match a plain-language description such as "VPs of sales at solar companies in California" and returns each person's current role and employer, location, years of experience, skills, schools and public profile links.
Tools used in this guide
- Context.dev People Search (find people by role, employer and location)
- Context.dev People Enrich (optional, a fuller profile for one result)
- The LLM or agent framework you already use
What does a people search API need to return for an AI app?
Context.dev People Search enables AI recruiting tools and outbound lead generation workflows to retrieve structured candidate and prospect records rather than unstructured web pages. When developers build autonomous agents or data pipelines, they need an API that translates natural language criteria into exact, filterable data points. An effective API must evaluate multi-part queries, map the results to a consistent JSON schema, and provide reliable pagination for building comprehensive shortlists.
The table below maps common AI application requirements directly to the fields and features available in the Context.dev API.
| AI App Requirement | Context.dev People Search / Enrich Field |
|---|---|
| Plain-language discovery by role, employer, and location | query (up to 500 characters in fast mode, up to 5,000 characters in ultra mode) |
| Strict geographic and tenure filtering | filters.countries (two-letter codes such as US or GB), filters.years_of_experience_min, filters.years_of_experience_max |
| Exact title, employer, or school matching | Double-quoted phrases ("site reliability"), OR between quoted phrases, and - exclusion in fast mode |
| Multi-criteria evaluation and candidate scoring | mode: "ultra" with match.confidence (0 to 1) per result |
| Structured current role and company resolution | role (title, seniority, functions, started_on, company.name, company.domain) |
| Location, background, and public profile links | location (country_code, region, city), years_of_experience, is_founder, skills, schools, profiles (public professional profile URLs) |
| Deep pagination for shortlist and prospect list building | next_cursor passed back as cursor (up to 10 results per page, up to 1,000 people per search) |
| Full single-person profile enrichment | POST /v1/people/enrich with social_urls, returning match.score (0 to 100), email, experience, education, and current_role |
| Predictable credit accounting | key_metadata.credits_consumed in JSON and X-Credits-Used response header |
Step 1: Search people by job title, company and location in plain language
Context.dev People Search accepts a natural-language query at POST https://api.context.dev/v1/people/search authenticated with the header Authorization: Bearer $CONTEXT_DEV_API_KEY. The most straightforward way to discover professionals is to describe the people you need in plain language. For example, passing "VPs of sales at solar companies in California" tells the API to parse the role, the industry, and the location simultaneously.
Developers can also pass optional tags in the request body. You can attach up to 20 labels of 1 to 50 characters to categorize your queries for usage charts and request logs. This helps track which AI agent or internal tool initiated the search.
Below is an example using the official TypeScript SDK to initiate a basic search.
import ContextDev from "context.dev";
const client = new ContextDev({ apiKey: process.env.CONTEXT_DEV_API_KEY });
const people = await client.people.search({
query: "VPs of sales at solar companies in California",
filters: {
countries: ["US"],
years_of_experience_min: 5
}
});
console.log(people.results);You can perform the exact same request using cURL to test your prompt before writing application code.
curl -X POST https://api.context.dev/v1/people/search \
-H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "VPs of sales at solar companies in California",
"filters": {
"countries": ["US"],
"years_of_experience_min": 5
}
}'Step 2: Choose fast or ultra mode
Context.dev People Search offers two distinct processing modes controlled by the mode parameter. By default, the API uses fast mode. This mode matches people on basic criteria such as role, location, or background. It accepts a query up to 500 characters in length. If you send a fast query exceeding 500 characters, the API returns a 400 invalid input error.
For more complex AI agent workflows, you can set the mode to ultra. This mode plans a deeper search and judges each candidate against every single criterion in your query. It accepts massive queries up to 5,000 characters long. Because it evaluates candidates thoroughly, it appends a match.confidence score ranging from 0 to 1 to every result. You should use ultra for detailed requests that combine several criteria. A great use case for ultra mode is a highly specific prompt like "Engineering managers at fintech companies in New York who previously worked at a bank and have led platform teams".
Because complex ultra searches require heavy evaluation, they can take up to 30 seconds to process. Any custom HTTP or SDK client timeout you configure must stay above 30 seconds. If a search does not finish in time, the API returns a 408 error. In this scenario, you should retry the request. Submitting a shorter or more specific query can help the request complete faster.
| Feature | fast mode | ultra mode |
|---|---|---|
| Default mode | Yes | No (mode: "ultra") |
| Best for | Basic criteria such as role, location, or background | Detailed multi-criteria queries combining past employers, skills, and leadership scope |
Maximum query length | 500 characters | 5,000 characters |
| Per-result confidence score | Not included | match.confidence from 0 to 1 |
| Typical response window | Standard request timeout | Up to 30 seconds (keep custom client timeouts above 30s) |
| Cost per page with matches | 10 credits | 50 credits |
| Cost when page has no matches | 0 credits (free) | 0 credits (free) |
Step 3: Filter by country and years of experience
Context.dev People Search evaluates a filters object in addition to the plain-language query, and every returned person must match these constraints. The filters block guarantees strict inclusion bounds for your candidate pool.
The countries array accepts two-letter country codes to dictate where the candidates currently live. Passing ["US"] restricts results to the United States, while ["US", "GB"] allows for candidates in both the United States and the United Kingdom.
To constrain professional tenure, apply years_of_experience_min and years_of_experience_max. These integers represent the total years of professional experience a candidate possesses. The maximum value must be at least the minimum value. Setting the minimum above the maximum returns an HTTP 400 invalid input error.
Step 4: Match exact titles and employers with quoted phrases
Context.dev People Search processes exact-phrase operators in fast mode to require specific keywords word for word. These operators give developers granular control over the keyword matching process.
Wrapping a phrase in double quotes demands a strict inclusion. The API matches the quoted phrase against a person's name, headline, current and past job titles, employers, schools, and fields of study. For instance, sending "site reliability" engineers in Berlin ensures that only individuals with that exact string in their profile surface in the response. Both straight double quotes (") and curly double quotes (āā) work perfectly. Single quotes (') are treated as plain text and do not trigger exact matching.
You can chain quoted phrases using the OR operator. This operator only joins quoted phrases, making it ideal for targeting specific alumni or companies. A query like "Stanford" OR "MIT" founders expands your search to include graduates from either institution.
To remove unwanted profiles, place a minus sign directly before a quoted phrase to exclude it entirely. Sending product designers -"agency" prevents the API from returning candidates who have the word agency in their current or past experience.
Step 5: Read the results
Context.dev People Search places all matching candidate profiles into the results array, ordered most relevant first, returning up to 10 people per page. The schema is predictable and safely typed for data ingestion. Any unavailable details on a record are returned as null or empty lists, ensuring your application avoids unexpected undefined errors during parsing.
Each candidate object in the array includes their name and a description that serves as their headline or summary. The profiles field contains an array of public professional profile URLs, such as "https://profiles.example.com/alex-morgan".
The location object provides structured geographic data containing country_code, region, and city.
Professional experience is nested inside the role object. This object details the candidate's title, seniority, functions, and started_on date. It also contains a company object with the current employer's name and website domain.
Additional background attributes include a years_of_experience integer, an is_founder boolean, an array of skills strings, and an array of schools attended. If you initiated the request using ultra mode, the response object will also include the match.confidence score.
Finally, the response root includes important metadata. The next_cursor string powers pagination, while key_metadata.credits_consumed tells you exactly how many credits the call used. This usage data is also available in the X-Credits-Used HTTP response header.
Step 6: Page through up to 1,000 people
Context.dev People Search uses cursor-based pagination to traverse result sets. You can page through up to 1,000 people for any single search. There is no limit parameter to set. Each successful page returns up to 10 people automatically.
To fetch the next batch of candidates, pass the next_cursor string from the previous response back as cursor in your next request. You must supply the exact same query, mode, and filters. Sending a cursor with a different query, mode, or filters returns an HTTP 400 invalid input error. You should stop paging when next_cursor is null or absent from the payload. Keep in mind that receiving a full page of 10 results does not guarantee another page exists.
When building recursive paging functions, you must handle standard HTTP error codes gracefully. An HTTP 400 indicates invalid input, which happens if a fast query exceeds 500 characters, if the experience minimum exceeds the maximum, or if you use a cursor from a different search. An HTTP 402 signifies a USAGE_EXCEEDED error when your organization exhausts its credit balance. An HTTP 408 means the search did not finish in time, prompting a retry. Finally, an HTTP 429 returns a RATE_LIMITED status, requiring your code to wait for the duration specified in the Retry-After header.
Step 7: Enrich a result with People Enrich
Context.dev People Enrich retrieves a fuller profile for a specific result when you pass that candidate's public professional profile URL to the enrichment endpoint. While search results provide an excellent summary for candidate shortlists, some workflows require deeper historical context like past roles or email addresses.
To retrieve this data, send a POST request to https://api.context.dev/v1/people/enrich. In the SDK, you call client.people.enrich({ social_urls: [url] }). The payload accepts 1 to 20 public professional profile URLs passed into the social_urls array. You can optionally include company: { domain } using the domain parsed from the search result's role.company.domain field. When enriching profiles by email, note that passing free and disposable email inputs returns an HTTP 422 error.
The enrichment API evaluates the match and returns a match.status of "candidate" with a score from 0 to 100 alongside a person object. If no data exists, it returns a match.status of "not_found" with a score of null. Because weak candidates can occasionally be returned, applications should enforce a score threshold and hold uncertain matches for manual review.
The enriched person object includes comprehensive data fields: name, email, location, social_urls, website_urls, current_role (which outlines title, an organization with name and domain, start_date, and is_current), experience, education, skills, last_updated, and checked_at.
People Enrich is a beta API available on all plans. It costs 20 credits per returned candidate match. Responses returning not_found are entirely free.
Complete TypeScript example
Context.dev People Search works best when wrapped in a pagination and normalization function that builds a consolidated list of candidates for your LLM or CRM. The TypeScript snippet below defines a single function that calls the API with fast mode, applies a United States location filter, loops through the cursor pagination until a page cap is met, and deduplicates the results.
import ContextDev from "context.dev";
const client = new ContextDev({ apiKey: process.env.CONTEXT_DEV_API_KEY });
export async function findPeople(query: string, maxPages = 5) {
let cursor: string | undefined = undefined;
let pagesFetched = 0;
const allPeople = [];
const seenProfiles = new Set<string>();
while (pagesFetched < maxPages) {
const response = await client.people.search({
query,
mode: "fast",
filters: { countries: ["US"] },
cursor
});
for (const person of response.results) {
// Deduplicate by first profile URL falling back to name plus company domain
const primaryProfile = person.profiles?.[0];
const fallbackKey = `${person.name}@${person.role?.company?.domain}`;
const dedupKey = primaryProfile || fallbackKey;
if (!seenProfiles.has(dedupKey)) {
seenProfiles.add(dedupKey);
// Map into a compact object for LLM context windows or CRM ingestion
allPeople.push({
name: person.name,
title: person.role?.title,
companyName: person.role?.company?.name,
companyDomain: person.role?.company?.domain,
location: person.location,
years_of_experience: person.years_of_experience,
profileUrl: primaryProfile
});
}
}
if (!response.next_cursor) {
break;
}
cursor = response.next_cursor;
pagesFetched++;
}
return allPeople;
}If you prefer to test the first page of this pipeline directly in your terminal, here is the equivalent cURL command.
curl -X POST https://api.context.dev/v1/people/search \
-H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "YOUR_QUERY_HERE",
"mode": "fast",
"filters": {
"countries": ["US"]
}
}'What it costs
Context.dev People Search operates on a predictable credit model available on all plans, including the Free tier. Free organizations receive 1,000 credits a month to build and test API requests.
Billing is calculated per page. In fast mode, the API charges 10 credits per page. Because each page returns up to 10 people, fetching 100 people across 10 pages costs 100 credits total. In ultra mode, the API charges 50 credits per page, bringing the cost of fetching 100 people across 10 pages to 500 credits.
Context.dev includes zero-match protection for search requests. Pages that return no matches are free in both fast and ultra modes. If you utilize People Enrich to expand a profile, the API charges 20 credits per returned match. Responses that result in not_found are completely free.
Frequently asked questions
How do I find people by job title and company with an API?
Context.dev People Search lets you find professionals by sending a plain-language query such as "VPs of sales at solar companies in California" to POST https://api.context.dev/v1/people/search or client.people.search(). Each response returns up to 10 matching people with their current role, employer name and domain, location, years of experience, skills, schools and public professional profile URLs. In fast mode, you can also wrap exact job titles or employer names in double quotes to require a word-for-word match.
How do I search for people in a specific country or with a minimum number of years of experience?
Context.dev People Search accepts a filters object alongside your plain-language query, and every returned result must match those filters. Pass two-letter country codes in filters.countries (such as ["US", "GB"]) to restrict results by the country a person lives in, and set filters.years_of_experience_min and filters.years_of_experience_max to bound total career tenure. If years_of_experience_min is set higher than years_of_experience_max, the API returns a 400 validation error.
What is the difference between fast and ultra mode?
Context.dev People Search uses fast mode by default, which accepts queries up to 500 characters, supports exact-phrase quotes, and costs 10 credits per page of results for basic role, location or background searches. Setting mode: "ultra" enables queries up to 5,000 characters, evaluates each candidate against every criterion in a complex multi-part prompt, and attaches a match.confidence score from 0 to 1 to each result for 50 credits per page. Because complex ultra searches can take up to 30 seconds to complete, configure custom client timeouts above 30 seconds.
How many people can one search return?
Context.dev People Search returns up to 10 people per page, ordered from most relevant to least relevant, and does not use a limit parameter. To retrieve more matches, pass the next_cursor string from the response back as cursor with the identical query, mode and filters until next_cursor is null or absent. A single search can page through up to 1,000 people across 100 pages.
How much does People Search cost?
Context.dev People Search is available on all plans, including the Free tier which includes 1,000 credits per month. A search page costs 10 credits in fast mode (100 credits for 100 people across 10 pages) or 50 credits in ultra mode (500 credits for 100 people), and pages with zero matches are always free. If you enrich individual profiles with Context.dev People Enrich, each returned candidate match costs 20 credits while not_found responses are free.
Get started
Get an API key at context.dev, test a live query in the People Search playground, and read the full schema in the Search people documentation.