Skip to content
SeekOutDevelopers

Guides

Search

Search finds people across public, GitHub, academic, healthcare, nursing, and authorized ATS or internal talent sources in one request. Preview is free. Full profiles use credits.

POST /v1/candidates/search takes a searches array. Each member names one source and a query of free text and/or typed filters. Public searches need at least one criterion beyond regions. Set include to preview so the call does not spend credits.

Optional page_size (1-25) sets the most people each page returns — this one and every continuation, because the size is carried on the cursor. With include: full_profile it is also exactly how many credits are held before the search runs, so a wallet that can fund the page you asked for is never refused. Omit it for the default page of 25.

A full_profile page can hold fewer people than page_size. A person whose profile came back empty, or whose profile would take the response past the 2 MiB delivery limit, is released: not returned, not charged, and counted in billing.released_units. The cursor still moves past them, and you are only charged for the people you receive. Real pages are far below the limit, so there is no need to shrink page_size to avoid it.

ATS filters include nested application criteria and tags. Internal talent filters include department, manager, internal skills, and organization size. Use GET /v1/search-source-bindings?source=ats to select an authorized ATS connection. Internal talent uses the authenticated organization's binding; neither source accepts a request-supplied organization as authority.

Search public candidates
curl --request POST "https://developer-api.seekout.io/v1/candidates/search" \
  --header "Authorization: Bearer $SEEKOUT_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: $(uuidgen)" \
  --data '{
    "searches": [
      {
        "source": "public",
        "query": {
          "current_titles": ["Software Engineer"],
          "regions": ["north_america"]
        }
      }
    ],
    "include": "preview"
  }'

The response lists ranked people with an opaque person_id and a search_result_ref. Continue with GET /v1/candidates/search/pages?cursor=… using pagination.cursor. That request carries the cursor and nothing else: the page_size you asked for is recorded on the cursor, so every later page is the same size without repeating it. Cursors issued before this field existed keep the default page.

{
  "schema_version": "candidate_search_response.v1",
  "search_id": "sset_example",
  "include": "preview",
  "results": [
    {
      "rank": 1,
      "person_id": "person_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
      "search_result_ref": "sr_example",
      "sources": ["public"],
      "matched_sources": ["public"],
      "summary": {
        "full_name": "Example candidate",
        "current_title": "Software Engineer"
      }
    }
  ],
  "pagination": { "cursor": "cur_example", "has_more": true },
  "billing": { "charge_units": 0, "include": "preview" }
}

From search to unlock

Copy results[0].person_id into POST /v1/profiles/unlock. A made-up id is rejected — person identifiers are issued by Search for your organization. In the API reference, paste a key, send this sample, then open Unlock profiles: Try it fills the id from the first result.

Sources

GET /v1/search/sources lists the indexes this key may use and the filters each one accepts. ATS and internal-talent need a separate entitlement and are off by default.

Run it from Candidate search.

From search to contacts

The same person_id is what POST /v1/contacts accepts. Retrieve one person's email or phone from contacts, or a batch of them from contact jobs.