> ## Documentation Index
> Fetch the complete documentation index at: https://www.forager.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Forager is a REST API for B2B people, company and job post data: contact lookups (phone numbers, personal emails, work emails), person, company and job post search, and bulk data feeds.
> Server: https://api-v2.forager.ai. Send the API key in the X-API-KEY header. Most paths include {account_id}. Read FORAGER_API_KEY and FORAGER_ACCOUNT_ID from the environment; never put the key in client-side code, logs or prompts.
> To add Forager to a project, follow https://www.forager.ai/docs/guides/agent-quickstart.md. To pick an endpoint, read https://www.forager.ai/docs/guides/choose-an-endpoint.md. For end-to-end builds, see https://www.forager.ai/docs/recipes/overview.md.
> Most requests spend credits. Do not guess costs; use https://www.forager.ai/docs/api-overview/credit-pricing.md and ask the user before spending credits.
> Use only endpoints and fields defined in https://www.forager.ai/docs/openapi.yaml. Forager has no MCP server for the API yet; the /mcp endpoint on this site searches the documentation only.

# Candidate sourcing by title and skill

> Search people by job title, skill and location with role search, resolving skill and location IDs through autocomplete first.

```text Recipe prompt theme={"theme":{"light":"github-light","dark":"github-dark"}}
Implement this recipe in my project: https://www.forager.ai/docs/recipes/source-candidates.md

Build a candidate sourcing search. Resolve skill and location names to IDs with the Forager person skills and locations autocomplete endpoints, let the user choose the matches, then run a person role search with role_title, role_is_current, person_skills and person_locations. Show name, headline, location and LinkedIn profile URL, with paging through the page field. Handle empty results, a 403, and a 429 with backoff, and cache autocomplete results. Keep the API key server-side in FORAGER_API_KEY with FORAGER_ACCOUNT_ID. Add tests that stub the HTTP calls.
```

![Candidate sourcing: title, skill and location filters return a list of candidates](https://mintcdn.com/forager/OnhSHNo_LBQ7yKjR/images/recipes/candidate-sourcing-title-skill-location.svg?fit=max\&auto=format\&n=OnhSHNo_LBQ7yKjR\&q=85\&s=ed4e43de3689ddd756f362783d442b25)

## What you'll build

A sourcing search for a recruiting tool. A recruiter types a title, a skill and a place. Your server turns the skill and place into IDs, runs the search, and returns a page of candidates to review.

```mermaid theme={"theme":{"light":"github-light","dark":"github-dark"}}
flowchart LR
  A[Title, skill, place] --> B[Autocomplete IDs]
  B --> C[Count with totals]
  C --> D[Role search]
  D --> E[Candidate list]
```

## Steps

**1. Resolve skills and locations**

Search filters take IDs. Call [Person skills lookup](https://www.forager.ai/docs/openapi/autocomplete/v1_person_skill_lookup.md) and [Locations lookup](https://www.forager.ai/docs/openapi/autocomplete/v1_location_lookup.md) with `q`. Each returns `results` with an `id` and `text`. Show the `text` values so the recruiter can choose.

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -G "https://api-v2.forager.ai/api/$FORAGER_ACCOUNT_ID/datastorage/autocomplete/person_skills/" \
  -H "X-API-KEY: $FORAGER_API_KEY" --data-urlencode "q=python"

curl -G "https://api-v2.forager.ai/api/$FORAGER_ACCOUNT_ID/datastorage/autocomplete/locations/" \
  -H "X-API-KEY: $FORAGER_API_KEY" --data-urlencode "q=Berlin"
```

```python Python (requests) theme={"theme":{"light":"github-light","dark":"github-dark"}}
import os, requests

BASE = f"https://api-v2.forager.ai/api/{os.environ['FORAGER_ACCOUNT_ID']}/datastorage"
HEADERS = {"X-API-KEY": os.environ["FORAGER_API_KEY"]}

def suggest(kind, q):
    r = requests.get(f"{BASE}/autocomplete/{kind}/", headers=HEADERS, params={"q": q}, timeout=30)
    r.raise_for_status()
    return [(int(i["id"]), i["text"]) for i in r.json()["results"]]

skills = suggest("person_skills", "python")
places = suggest("locations", "Berlin")
```

```javascript JavaScript (fetch) theme={"theme":{"light":"github-light","dark":"github-dark"}}
const BASE = `https://api-v2.forager.ai/api/${process.env.FORAGER_ACCOUNT_ID}/datastorage`;
const headers = {
  "X-API-KEY": process.env.FORAGER_API_KEY,
  "Content-Type": "application/json",
};

async function suggest(kind, q) {
  const r = await fetch(`${BASE}/autocomplete/${kind}/?q=${encodeURIComponent(q)}`, { headers });
  if (!r.ok) throw new Error(`Forager ${r.status}`);
  return (await r.json()).results.map((i) => [Number(i.id), i.text]);
}

const skills = await suggest("person_skills", "python");
const places = await suggest("locations", "Berlin");
```

**2. Search by role, skill and location**

Send a `POST` to [Person role search](https://www.forager.ai/docs/openapi/people/datastorage_person_role_search_create.md) with the chosen IDs. `role_title` supports a boolean text query, such as `"backend engineer" OR "software engineer"`. To count matches before you fetch them, send the same body to [Person role search totals](https://www.forager.ai/docs/openapi/people/datastorage_person_role_search_totals_create.md).

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X POST "https://api-v2.forager.ai/api/$FORAGER_ACCOUNT_ID/datastorage/person_role_search/" \
  -H "X-API-KEY: $FORAGER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"role_title": "Backend Engineer", "role_is_current": true, "person_skills": [101], "person_locations": [202], "page": 1}'
```

```python Python (requests) theme={"theme":{"light":"github-light","dark":"github-dark"}}
r = requests.post(
    f"{BASE}/person_role_search/",
    headers=HEADERS,
    json={
        "role_title": "Backend Engineer",
        "role_is_current": True,
        "person_skills": [skills[0][0]],
        "person_locations": [places[0][0]],
        "page": 1,
    },
    timeout=30,
)
r.raise_for_status()
candidates = [hit["person"] for hit in r.json()["search_results"]]
```

```javascript JavaScript (fetch) theme={"theme":{"light":"github-light","dark":"github-dark"}}
const r = await fetch(`${BASE}/person_role_search/`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    role_title: "Backend Engineer",
    role_is_current: true,
    person_skills: [skills[0][0]],
    person_locations: [places[0][0]],
    page: 1,
  }),
});
if (!r.ok) throw new Error(`Forager ${r.status}`);
const candidates = (await r.json()).search_results.map((hit) => hit.person);
```

**3. Show the candidates**

Each `person` has `id`, `full_name`, `headline`, `skills` and `location`. Its `linkedin_info` carries `public_profile_url` and `public_identifier`. Show these and keep the `id` for the next step. Use `person_headline` or `person_description` to narrow the search by text, and `role_years_on_position_start` and `role_years_on_position_end` to filter by time in role.

**4. Get contact details for shortlisted people**

Only for the people a recruiter shortlists, follow the [candidate contact recipe](https://www.forager.ai/docs/recipes/candidate-contact.md).

## Handle the edge cases

* **Not found.** An empty `search_results` means no match. Offer to drop the location or a skill. If autocomplete returns no results for a name, try a shorter term.
* **403.** The key is missing or invalid. Fix the credentials; do not retry.
* **429.** Autocomplete allows 10 requests per second per account, so cache IDs and debounce typeahead. See [errors and rate limits](https://www.forager.ai/docs/errors-and-rate-limits.md).
* **Paging.** Use `page` to request more results.
* **Credits.** A role search costs 1 credit per request, and so does a role search totals call. Autocomplete is free. See [credit pricing](https://www.forager.ai/docs/api-overview/credit-pricing.md).

## Related

> [card] [Search people by role](https://www.forager.ai/docs/guides/search-people-by-role.md)
>
> Every role search filter.

> [card] [Find filter values](https://www.forager.ai/docs/guides/find-filter-values.md)
>
> Which autocomplete feeds which filter.

> [card] [Person skills lookup](https://www.forager.ai/docs/openapi/autocomplete/v1_person_skill_lookup.md)
>
> Autocomplete reference.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.