docs sourcing

Raw search

One page of the person index for filters you choose.

Raw search is for builders who want their own sourcing logic: you choose the filters, you get one page of 25 people, and nothing is planned, ranked, or deduplicated for you.

curl -s -X POST "$RECRUITMCP_BASE/v1/people/search" \
  -H "Authorization: Bearer $RECRUITMCP_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"filters": {"current_job_titles": ["Data Engineer"], "geo_ids": ["90009596"], "past_companies": ["Showpad"]}, "page": 1}'

Filters

Each filter maps one to one to a filter the person index applies. Anything else is refused with 400 unsupported_filter and details.field; nothing is silently ignored.

FilterValues
current_job_titles, past_job_titles (+ exclude_…)Titles, up to 70
geo_ids, exclude_geo_idsLocation ids from lookups, up to 70
current_companies, past_companies (+ exclude_…)Company URLs, ids, or names, up to 50
schools, exclude_schoolsSchool names, up to 50
industry_ids, function_ids, seniority_level_ids (+ exclude_…)Ids from the value lists
years_of_experience_ids, years_at_current_company_idsYear buckets 1–5
company_headcountSize ranges A–I
profile_languagesLanguage codes the profile is written in
first_names, last_namesUp to 50
recently_changed_jobsChanged jobs in the last 90 days
searchKeywords. Quote phrases; combine with OR, AND, NOT

Unknown top-level fields are refused the same way, as 400 invalid_request with details.field and details.allowed, so a typo such as pgae never runs a different search than you meant. There is no raw flag: every layer returns the normalized profile, and raw: true is refused. The reasons are in API layers.

Refused on purpose, with a reason in the error: time in the current title (years_in_current_position_ids; filter run candidates on tenure_months), skills (put the skill in search), and emails (use POST /v1/people:match).

Response

FieldMeaning
data[]People: profile_id, name, location, profile URL, current positions, and already_seen
query_keyStable id of this filter set. Ask for the next page with the same filters
done, total_elementsWhether more pages exist, and the index's total when it reports one
applied_filtersEvery filter as sent, plus suppression and exclude_seen
ignored_fieldsAlways empty here; raw search refuses instead of ignoring
omitted.unpaidLeads on this page that were not returned because the balance ran out. They were not charged
resume{ page, query_key } when unpaid is greater than zero. Repeat the same filters and that page after you add credits. Leads already billed come back free

People already in your seen register are returned with already_seen: true. Pass exclude_seen: true to drop them. Suppressed people are always removed, in every layer, and counted.

Fetch the full profiles of the people you want with POST /v1/people:fetch.

What it costs

1 credit per lead actually returned. Suppressed people and people left out with exclude_seen are not charged, an empty page is free, and a lead is charged once per workspace. There is no per-page fee. ?dry_run=true is free and returns an estimate from 0 up to 25 credits.

MCP: search_people_raw in the advanced toolset. Without confirm it is the estimate.

Reference: searchPeople and PeopleFilters in the API reference.

API reference