Search

Profiles for a filter set. limit is how many profiles to return, from 1 to 100, and defaults to 25. cursor continues a previous search: send the next_cursor from the last response. Filters map one to one to what the index supports; an unknown or unsupported filter is refused with unsupported_filter, and an unknown body field with invalid_request, never ignored.

company_headcount is A through I: A self-employed, B 1-10, C 11-50, D 51-200, E 201-500, F 501-1,000, G 1,001-5,000, H 5,001-10,000, I 10,001+. years_of_experience_ids and years_at_current_company_ids are 1 through 5: 1 is under a year, 2 is 1 to 2 years, 3 is 3 to 5 years, 4 is 6 to 10 years, 5 is more than 10 years. seniority_level_ids run from 100 to 320. function_ids run from 1 to 26.

current_companies and past_companies take a company URL or company id from POST /v1/companies:resolve. A bare name is not resolved and does not match.

data holds at most limit profiles. next_cursor is null when nothing remains. A suppressed person is never returned and never charged: search counts them in omitted.suppressed and keeps filling limit. exclude_seen defaults to false on REST and MCP, so people already in the seen register come back with already_seen true.

One credit per profile in data, once per workspace. Profiles fetched and not returned are not charged. A later call with cursor returns those cached profiles without asking the index again, and charges them when they are returned. An empty result costs nothing. A profile already billed in this workspace is free.

An authorized call runs and charges. confirm is deprecated and ignored. dry_run=true previews and charges nothing; dry_run is true, requires_confirm is false, and estimate.credits_max equals limit. The estimate includes balance_credits, sufficient, and warning. sufficient is false when the visible balance is below credits_max, and warning names 402 insufficient_credits. Above the key's approval_threshold_credits the call returns 409 approval_required with an estimate and a confirm_token.

Each search has a time budget of about 20 seconds. When it ends before limit is reached, the response is 200 with partial: true: data holds the profiles that arrived, only those are charged, and next_cursor continues the rest. Several geo_ids are fetched in parallel and interleaved; a place that did not answer in time is continued by next_cursor. Only when nothing arrived is the response 504 gateway_timeout, with nothing charged. The pages asked for keep loading, so the same request after Retry-After usually reads them from cache. Fewer geo_ids per request also finish faster. A known location drops profiles outside that place; they are counted in omitted.outside_geo and not charged. seniority 310 is CXO, and a CXO-only search drops other titles into omitted.seniority without charging them. profile_id is the search id. alternate_id is the other profile id for the same person, and it is null until that person has been enriched. total_elements is an estimate from the index before the location post-filter. omitted.outside_geo counts profiles dropped from pages already read and is not subtracted from total_elements.

Scope: sourcing:spend.

post/v1/people/search

Request

  • Base URL: https://api.recruitmcp.com
  • URL: https://api.recruitmcp.com/v1/people/search
  • Auth: one of:
    • HTTP bearer
    • OAuth 2 (authorization code, authorization URL https://recruitmcp.com/oauth/authorize, token URL https://recruitmcp.com/oauth/token, scopes: sourcing:spend)

Query parameters

dry_runboolean

Optional. true returns a free preview, labelled dry_run, and changes nothing. The same flag in the JSON body is honored. A dry run never charges. Omit it to run the call.

Headers

Idempotency-Keystring

Required unless dry_run=true. At most 128 characters. The same key and body replays the first response for 24 hours and does not charge again. A different body is 409 idempotency_key_reused. A second call waits for the first and replays it. 409 idempotency_in_progress means the first call was still running when the wait ended.

RecruitMCP-Version'2026-10-13'

API version. Defaults to the version the key was created with. Supported: 2026-10-13.

RecruitMCP-Customerstring

Act inside this customer (cus_…). Ignored for keys bound to a customer, which always act inside theirs.

Request body

limitinteger

Profiles to return. 1 to 100. Defaults to 25. A JSON number. Query parameters accept numeric strings; a JSON body does not.

cursorstring

From the previous response next_cursor. Omit to start at the beginning.

exclude_seenboolean

Drop people already in the seen register. Default false on REST and MCP: they are returned with already_seen true.

confirmboolean

Deprecated. Accepted and ignored. An authorized search runs without it.

confirm_tokenstring

From approval_required. Required only when the estimate is above the key threshold.

Example request

{
  "filters": {
    "current_job_titles": [
      "Backend Engineer"
    ],
    "geo_ids": [
      "90009496"
    ]
  },
  "limit": 10
}

Response

Live response is a PeopleSearchPage. With ?dry_run=true, a PeopleSearchPreview; nothing is charged or sent.

OR

Example response

{
  "object": "people_page",
  "query_key": "qk_backend_london",
  "total_elements": 128,
  "data": [
    {
      "profile_id": "lead_8f2a1c_1",
      "full_name": "Ada Peeters",
      "location": "London, England, United Kingdom",
      "alternate_id": null,
      "photo": null,
      "profile_url": "https://profiles.example.com/ada-peeters",
      "current_positions": [
        {
          "title": "Backend Engineer",
          "company_name": "Acme Robotics",
          "company_id": null,
          "company_url": "https://companies.example.com/acme-robotics",
          "current": true,
          "description": "Builds the fleet API in Go.",
          "started_on": {
            "year": 2021,
            "month": 3,
            "text": "2021-03"
          },
          "tenure_at_position": {
            "numYears": 5,
            "numMonths": 7
          },
          "tenure_at_company": {
            "numYears": 6
          }
        }
      ],
      "identity_key": "ada peeters|acme robotics",
      "already_seen": false
    },
    {
      "profile_id": "lead_3c71e0_2",
      "full_name": "Jonas Vermeulen",
      "location": "London, England, United Kingdom",
      "alternate_id": null,
      "photo": null,
      "profile_url": "https://profiles.example.com/jonas-vermeulen",
      "current_positions": [
        {
          "title": "Platform Engineer",
          "company_name": "Paperkiln",
          "company_id": null,
          "company_url": "https://companies.example.com/paperkiln",
          "current": true,
          "description": null,
          "started_on": {
            "year": 2025,
            "month": 11,
            "text": "2025-11"
          },
          "tenure_at_position": {
            "numMonths": 11
          },
          "tenure_at_company": {
            "numMonths": 11
          }
        }
      ],
      "identity_key": "jonas vermeulen|paperkiln",
      "already_seen": false
    },
    {
      "profile_id": "lead_5d09b4_3",
      "full_name": "Lina Dubois",
      "location": "London, England, United Kingdom",
      "alternate_id": null,
      "photo": null,
      "profile_url": "https://profiles.example.com/lina-dubois",
      "current_positions": [
        {
          "title": "Backend Engineer",
          "company_name": "Acme Robotics",
          "company_id": null,
          "company_url": "https://companies.example.com/acme-robotics",
          "current": true,
          "description": null,
          "started_on": {
            "year": 2023,
            "month": 1,
            "text": "2023-01"
          },
          "tenure_at_position": {
            "numYears": 3,
            "numMonths": 9
          },
          "tenure_at_company": {
            "numYears": 3,
            "numMonths": 9
          }
        }
      ],
      "identity_key": "lina dubois|acme robotics",
      "already_seen": true
    }
  ],
  "next_cursor": "eyJvZmZzZXQiOjN9",
  "omitted": {
    "suppressed": 0,
    "already_seen": 0,
    "unpaid": 0
  },
  "applied_filters": [
    {
      "field": "current_job_titles",
      "effect": "hard_filter",
      "detail": "Backend Engineer"
    }
  ],
  "ignored_fields": [],
  "cost": {
    "credits": 3,
    "cached_items": 3,
    "live_items": 0,
    "upstream_calls": 1
  }
}

Changes

    • warning

      added the new approval_forced enum value to the / response property for the response status

    • warning

      added the new approval_forced enum value to the / response property for the response status

    • warning

      added the new approval_forced enum value to the / response property for the response status

    • warning

      added the new approval_forced enum value to the / response property for the response status

    • warning

      added the new approval_forced enum value to the / response property for the response status

    • warning

      added the new approval_forced enum value to the / response property for the response status

    • warning

      added the new approval_forced enum value to the / response property for the response status

    • warning

      added the new approval_forced enum value to the / response property for the response status

    • warning

      added the new approval_forced enum value to the / response property for the response status