# Find people at the right company

Use `people.search` to find people by employer and role. For a known company, start with its website domain and the job titles you need. A company name alone can refer to several different businesses.

## Start with qualified companies

If you only have an ideal customer profile, discover candidate company domains first. Check the required industry, company size, technologies and geography against supporting data before searching for their people. A generic company search does not prove a company uses a particular tool or meets a size threshold. Keep those requirements when changing data sources; leave an unconfirmed criterion as unknown.

Apollo searches people at known companies, or reveals people from preview IDs. For a broad people search without employer names or domains, use automatic routing with a budget that admits another eligible route.

## Start with a domain and specific titles

Inspect the capability before running it:

```bash
curl https://api.routergrowth.com/v1/inspect \
  -H "Authorization: Bearer $ROUTERGROWTH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"capability":"people.search"}'
```

Then search one company. This example uses a small limit to find technical leaders:

```bash
curl https://api.routergrowth.com/v1/run \
  -H "Authorization: Bearer $ROUTERGROWTH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "capability": "people.search",
    "input": {
      "companies": ["Microsoft"],
      "company_domains": ["microsoft.com"],
      "titles": ["Chief Technology Officer", "VP Engineering"],
      "detail": "full",
      "limit": 5
    },
    "routing": {"provider": "auto", "allow_fallback": true, "max_cost": "0.25"},
    "wait_seconds": 120
  }'
```

`max_cost` is a spending ceiling, not the expected charge. If the response is `202`, poll the returned run ID with `GET /v1/runs/{run_id}?wait=60`; do not submit the search again. See [Run](/docs/api/run) and [Runs](/docs/api/runs).

For a broader employee list, increase `limit` to 25 only when you will use those results. Keep the employer filter and add `titles`, `seniority` or `locations` when relevant. Without title filters, a company search can return engineers, recruiters, interns and advisors; it is not automatically a decision-maker list.

## Let the router select eligible providers

Use `routing.provider: "auto"` unless you deliberately need one provider. Pinning `apollo` or any other provider disables cross-provider fallback, even if `allow_fallback` is `true`. Raw endpoints always require their provider and never fall back.

Automatic routing still respects `max_cost`. A $0.042 cap may cover one database result but cannot cover a company-constrained LinkedIn search, which quotes $0.217087 for one full profile at one employer at list price. Read the run's `hints`, error and `attempts` before retrying. On an unbilled no-match or provider failure, budget-exclusion guidance identifies eligible alternatives that cost more and the smallest quoted cap that admits one. Review that cost against your budget; a higher cap does not guarantee a result.

Include equivalent title spellings in the first query, for example “VP Engineering” and “Vice President of Engineering.” Adding directors broadens the seniority target; do that only if directors fit your requirements.

## Choose the employer precisely

| Input | Best use |
|---|---|
| `company_domains` | The company's actual website domain, such as `microsoft.com`. Preferred when known. |
| `companies` plus `company_domains` | A company name or LinkedIn company URL plus its website domain. If supplying several, pair the two arrays in the same order for the LinkedIn route. |
| A LinkedIn company URL in `companies` | The exact company page, especially when a name is ambiguous. Add its domain when known. |
| A name in `companies` alone | When you do not yet know the domain or company page. Ambiguous or unresolved employers may return no match. |

Start with one company per request so it is easy to review the results and diagnose misses. A paired request for two employers looks like:

```json
{
  "companies": ["Microsoft", "Salesforce"],
  "company_domains": ["microsoft.com", "salesforce.com"],
  "titles": ["Chief Technology Officer"],
  "limit": 5
}
```

Domains identify the employer; `locations` restrict the people. Adding a headquarters city can accidentally exclude remote staff, so use a location only when it matters to your search.

## Understand the two result types

The database route can return work emails with full profiles when available. For known companies and a small result limit, this can avoid a separate email lookup. `detail: "short"` on that route returns a masked preview and `person_id` values; use `person_ids` to reveal selected people.

On the LinkedIn route, RouterGrowth resolves the employer before searching. When a domain is supplied, the company website must match it. Returned people must have a current position carrying the resolved employer's ID or LinkedIn URL. A matching company name by itself is insufficient.

LinkedIn results include:

- `current_company`, `current_title` and `company_linkedin_url`: the position matching the requested employer, even when the person also has another job or board seat.
- `current_positions`: the other explicitly current positions available in the profile.
- `quality_flags`: review `retirement_mentioned` and `missing_current_title` before using a row for outreach.
- `quality.raw_profiles`, `quality.excluded_profiles` and `quality.employer_identity_checked`: how many profiles were examined and excluded, and whether employer identity was checked. These fields are inside the run's `result`.

These fields are route-specific; do not require them on database-route responses. An unconstrained LinkedIn search has `employer_identity_checked: false` because no employer was requested.

Employer matching checks the provider's profile evidence. It does not independently verify a person's employment or prove that they are a qualified buyer. Review the role and flags. Identical profile URLs are deduplicated, but two accounts with the same person's name may still need manual review.

## Get emails only after reviewing the people

The LinkedIn route does not perform email enrichment. For a selected profile whose `email` is empty, pass its actual `first_name`, `last_name` and the matching employer's domain to `contact.find`. Do not invent a surname from initials. Then use `contact.verify` on the returned email. If the database route already supplied an email, skip the redundant lookup and verify that address.

Report company candidates, qualified companies, matched people, found emails and verified emails separately. A successful people search does not mean every row has an email, or that any returned email has been verified.

## When a search returns no match

1. Check the domain for typos and confirm it belongs to the intended employer.
2. Supply the exact LinkedIn company URL in `companies`, paired with its domain when known. This avoids relying on a name lookup.
3. Check `hints`, routing settings and the budget: remove an unintended provider pin, and permit another route only within your spending limit.
4. Broaden title variants or remove an unnecessary location restriction, while keeping the employer constraint.
5. If you know a particular person's LinkedIn URL, use `person.enrich` to inspect their role history. A name alone is not enough evidence to change the employer.

An unresolved employer or a search where every profile lacks acceptable employer evidence returns `no_match` on the LinkedIn route and releases that attempt's customer hold. Automatic routing may try another eligible provider. A final no-match does not mean the company has no employees; it may mean there is insufficient data to identify them reliably. Do not immediately repeat the same query unchanged.

## Budget for the route and the result limit

At list price, the LinkedIn route quotes $0.175 per search page of up to 25 profiles plus $0.007 per requested full profile. A company-constrained search adds a lookup allowance of up to $0.035087 per employer. Examples for one employer:

| Requested full profiles | List-price quote |
|---|---:|
| 5 | $0.245087 |
| 25 | $0.385087 |

The quote includes the lookup allowance even when you provide a LinkedIn company URL. Workspace discounts can change these amounts. The requested-limit quote remains the billing floor for a successful LinkedIn search: filtering out unsuitable profiles does not proportionally reduce its charge. Empty or unresolved attempts are not charged to the customer; the platform can still incur provider costs.

The database route has different pricing: full results are normally $0.042 per person actually returned, and masked previews use the platform minimum. Always check `inspect`, keep `max_cost` on the request, and read the run's actual `billing.charged` amount. See the [people.search catalog entry](/catalog/people.search) for the current contract.
