PloidDocs
Search

Search

Describe who you're looking for and get back a list of matching people instantly. Search by role, company, skills, location, or anything else.

POST /v1/search

Use this endpoint for a one-shot list of up to 150 people. Provide a semantic query, at least one structured filter, or both.

curl https://api.ploid.com/v1/search \
  -H "Authorization: Bearer $PLOID_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "software engineers at fintech companies in San Francisco",
    "type": "auto",
    "category": "people",
    "num_results": 25,
    "filters": {
      "title": "software engineer",
      "seniority": "senior",
      "industry": "fintech",
      "location": "San Francisco"
    },
    "contents": {
      "fields": ["linkedin", "title", "company", "location"]
    }
  }'

Search types:

  • instant — retrieve from Ploid's people index.
  • fast — overfetch and rerank index results for better recall.
  • auto — after index retrieval, resolve a named-person miss and research more candidates when results are thin; every result is verified.
  • deep — resolve a named-person miss and always research more candidates after index retrieval; every result is verified.

Hard filters

A hard filter is a condition every returned person must satisfy. Rows that contradict one are dropped. An unsupported filter is rejected; it is never skipped.

Set fields are combined with AND. The serving index accepts these:

FilterA person matches when
titleThe current job title holds that role. Matching uses word boundaries, so founder matches Co-Founder and does not match Executive Assistant to the Founder or Partner at Founders Fund.
companyThe current employer is that company after punctuation and legal suffixes (Inc, LLC, Ltd, and similar) are removed. Apple, Inc. matches Apple. Apple World does not match Apple, and Stripe Consulting does not match Stripe. Rebrand pairs match: Meta/Facebook, X/Twitter, and Google/Alphabet.
locationCity, state, and country contain every part of the value. San Francisco, CA satisfies California and CA. Short codes match as whole tokens, so US does not match Russia or Austin.
seniorityIndexed seniority or title matches the level. Recognized values are entry, junior, mid, senior, staff, principal, director, vp, and cxo. Close titles count: senior includes Sr. and Manager; director includes Head; cxo includes chief and founder titles. Any other value must appear in the seniority or title text.
industryThe indexed industry contains the value, case-insensitively. A blank industry does not match.

Each field takes one value, or an object with any_of (match any listed value) and none_of (drop a person whose stated value matches). location also accepts countries and cities, which join any_of as alternatives. Up to 10 values per list.

{
    "query": "fintech founders",
    "type": "auto",
    "filters": {
        "title": { "any_of": ["Founder", "CEO"] },
        "location": { "countries": ["United States"], "cities": ["New York"] },
        "company": {
            "none_of": ["Google"],
            "employee_count": { "gte": 10, "lte": 200 },
            "funding_stage": { "in": ["seed", "series_a"] }
        },
        "experience": { "past_companies": { "any_of": ["Stripe", "Ramp"] } },
        "education": { "schools": { "any_of": ["MIT", "Stanford"] } }
    }
}

The index does not hold employer headcount, funding stage, past employers, or schools. Those filters are proven per person with cited evidence instead:

FilterA person matches when
company.employee_count (gte, lte), or company_size (min, max)The current employer's headcount is in range.
company.funding_stage.inThe current employer's latest stage is listed: pre_seed, seed, series_a, series_b, series_c, series_d_plus, public, or bootstrapped.
experience.past_companies.any_ofA past role, not only the current one, was at a listed company.
education.schools.any_ofThe person attended a listed school.

Each one counts toward the 5-criteria limit and needs type auto or deep, or an async search; instant and fast return 422 unsupported_filters. A person whose evidence is unclear is not returned. Exclusions and evidence-verified filters narrow a search, so a request also needs a query or a positive title, company, location, seniority, or industry value.

company_domain, radius_km, and tenure return 422 unsupported_filters.

Every result carries filter_match, one entry per requested filter. On instant and fast, basis is indexed_field: the stored profile satisfied it, with the observed value and the value that matched. On auto and deep, every filter is researched for every person, so basis is verified_evidence and the evidence is in verification.

instant and fast return index rows only. A blank title, company, or location fails that filter. Role, company, and place phrases parsed from query are hard on these types as well. Funding-stage words in query (for example, “Series B startups”) are never matched as company or headline text; on auto/deep they are verified like company.funding_stage. Qualifiers such as “ideally …”, “open to …”, sector descriptors (“fintech startups”), and “X or remote” places rank results instead of filtering them.

auto and deep research the query and still apply every explicit filter. When that research plan succeeds, phrases parsed from query are not a second hard gate. If planning falls back, those parsed phrases are hard, same as instant and fast. Every filter is checked again on the final list, and a stated mismatch is always dropped. seniority and industry filters are answered from the Ploid people index only.

A company inferred for a named person, such as Ada Lovelace at Analytical Engines, stays a ranking clue, so a stale employer cannot hide that person. An explicit filters.company is always hard.

Main results always include person.person_id, which can be passed directly to POST /v1/person, plus person.resolution_source: "ploid". Retrieval does not verify current profile claims, so person.identity_verified is false until POST /v1/person returns evidence. score and person.confidence are the result's rank within the response, from 1 for the strongest match down. Contact fields are deliberately excluded and reported as person.contact_status: "requires_enrichment"; resolve them through POST /v1/enrich. On auto and deep, data.grounding.results holds one evidence entry per returned person, with the verification reasoning as its snippet.

Freshness

Verified searches (auto and deep) cache the public evidence behind each person. freshness.max_age_days caps how old that cached evidence may be:

{
    "query": "fintech founders in New York",
    "type": "auto",
    "num_results": 10,
    "freshness": { "max_age_days": 2 }
}

Every candidate's profile and page reads must then be at most 2 days old; anything older is re-read live before verification. max_age_days: 0 always re-reads live sources.

When freshness is omitted, verification derives a window from the time-sensitive facts the request depends on. Current role and employer facts assume a ~90-day shelf life and location facts ~180 days, so a default auto search lands around a 4.6-day window and deep around 1.8 days; a request with no decaying facts (for example, past employers or schools only) keeps the relaxed 7-day cache. The derived window applies to the top-ranked candidates (num_results on auto, twice that on deep); the rest use the relaxed window.

The response echoes what was applied under data.request.freshness: max_age_days is the window in days (fractional when derived) and source is request or default.

Tighter windows mean more live reads, so a tight search can take longer and return fewer results within its deadline. freshness requires verification: instant and fast return 422 unsupported_freshness.

Choosing a public surface

NeedChoose
Immediate list, 150 or fewer results/v1/search
Research one identified person/v1/person

Durable, multi-step list building uses People Sets (preview), which are available to API keys with the people:search scope.

Errors and limits

ConditionStatus and code
Category is not people422 unsupported_category
Filter is not in serving index422 unsupported_filters
Evidence-verified filter on instant or fast422 unsupported_filters
Criteria plus evidence-verified filters exceed 5422 too_many_criteria
Only exclusions or evidence-verified filters, no query422 unsupported_request
freshness on instant or fast422 unsupported_freshness
Fast search is not configured503 search_unavailable
Search timed out without results503 search_timeout
Search failed without results503 search_failed

POST /v1/search accepts at most 150 results (num_results, default 10). The workspace plan and API key set the request rate; rejected calls return Retry-After and are never billed. Timed-out or shard-partial index responses fail closed with a 503; the endpoint does not return partial index results. See Errors & rate limits.