Getting accurate results from search
Write people and company searches that return exactly the people you mean — the rules that matter, what's available today, and worked examples of common mistakes with their fixes.
Getting accurate results from search
Most "missing results" in a search aren't missing — the request asked for something narrower than intended. A seniority that doesn't cover owners, one industry name where five apply, a revenue filter on companies that don't publish revenue. This page shows how each filter actually matches, what's available today, and the request patterns that return what you mean, with worked examples you can copy.
Running a large analysis or comparing Fiber with another data provider? Read the checklist and comparing providers first. Most gaps in side-by-side tests come from how the requests were translated, and each one has a fix below.
Checklist
- Read
warningson every response. Unknown filters insidesearchParamsare rejected with400; unknown top-level fields are dropped and reported inwarnings. See validation. - Send owner, partner and intern levels as title words, not
c-suite. See levels. - Express a department as a keyword list in a
functionalblock. See departments. - Use every industry name that applies, spelled exactly as the
industries list (
GET /v1/enums/industries) returns it. See industries. - Put the industry on the company side with combined search when you mean "people at companies in X": employer filters combine with the rest of your company conditions. See industries.
- Use employee count, not revenue, to size small companies.
- Choose exact or non-exact titles on purpose.
- Set
sortwhen you page through results. - Pass
getFastEstimate: falsewhen you need an exact combined count. - Compare the people, not just the counts, when you benchmark.
What's available today
The table is the quick reference; each row links to the details.
| You want to filter on | How to express it today | Status |
|---|---|---|
| A job title | jobTitleV3 with plain terms, exact or non-exact | Available |
| A seniority level | jobSeniority — six levels, or a functional block | Available |
| Owner, partner, intern, entry level | Title words in jobTitleV3 | Workaround |
| A department (finance, legal, …) | jobFunction — 44 values, or a keyword list in a functional block | Available |
| Past or any job, not just the current one | jobStatus | Available |
| Words anywhere on a profile, or only in titles | keywordsV2 with options.fieldsToSearchOver | Available |
| The person's own industry | industry (people search) | Available |
| The employer's industry | linkedinIndustries or industriesV2 (combined search) | Available |
| Employer size | employeeCountV2 — any range | Available |
| Employer revenue | revenueRangeUSD — one range | Available, limited for small companies |
| Companies in a city | headquartersLocation free-form-city + radius | Available |
| Attributes of a past employer | Combined search + jobStatus: previously-employed | Available, read the caveat |
| Employer domain and industry on each result | getDetailedWorkExperience: true | Available |
| A person from an email or phone number | Reverse lookup | Available |
| Stable pages | sort + cursor | Available |
| Exact counts | Count endpoints; getFastEstimate: false for combined | Available |
| Several size or revenue ranges, size/revenue excludes | — | Not yet |
| Gender and other protected characteristics | — | Not offered |
| Email, phone or social profile as a search filter | Use reverse lookup instead | Not offered as a filter |
Job titles
Job title filters match the person's current job by default (see
current, past or any job). Each plain term
matches one of two ways:
| Setting | Matches | Example: term customer success manager |
|---|---|---|
exact: true | The whole title equals the term (case ignored) | "Customer Success Manager" — not "Senior Customer Success Manager" |
exact: false (default) | Every word of the term appears in the title, in any order, including common synonyms | "Customer Success Manager", "Senior Customer Success Manager", "Manager, Customer Success" |
- Use
exact: truefor like-for-like comparisons with a system that matches normalized titles exactly, or when a word order matters. - Use
exact: falsefor reach. In our tests, the non-exact version of a common title returned about twice as many people, all holding that role. - Add abbreviations and alternate spellings as extra terms ("O&M manager", "CSM") when you rely on them: it's the reliable way to cover every form.
Seniority and levels
People search also has a direct seniority filter, jobSeniority — six
values: Entry level, Associate, Mid-Senior level, Director, Executive and
Internship. For owner, partner and intern audiences it's not enough on its
own; the functional block below covers what the filter can't.
A functional block generates the common title forms for a seniority and an
optional list of keywords: ["vp"] with ["sales"] covers "VP of Sales",
"Vice President, Sales", "VP Sales" and similar.
| Seniority value | Covers titles like |
|---|---|
c-suite | Chief … Officer, CEO, CTO, CFO, Founder, Co-Founder |
svp, vp | Senior Vice President …, Vice President …, VP … |
head | Head of … |
director | Director of …, … Director |
manager | … Manager, Manager of … |
lead, principal, staff, senior | Lead …, Principal …, Staff …, Senior … |
There is no owner, partner, entry or intern seniority. c-suite covers
"Chief … Officer" and founder titles only, so owners of small businesses and
partners at firms are missed. Add them as title words next to the
functional block.
"jobTitleV3": {
"anyOf": [
{ "type": "functional", "seniority": ["c-suite"] },
{ "type": "plain", "term": "owner", "exact": false },
{ "type": "plain", "term": "co-owner", "exact": false },
{ "type": "plain", "term": "partner", "exact": false },
{ "type": "plain", "term": "managing partner", "exact": false },
{ "type": "plain", "term": "principal", "exact": false }
]
}For entry-level roles use terms such as intern, trainee, junior, graduate and apprentice.
Departments
Departments have a dedicated filter on people search, jobFunction:
44 values from Accounting to Writing / Editing. The mapping from another
provider's department values is in
migrating from another data provider.
The keyword-list method below still earns its keep when a department's roles are titled inconsistently: one keyword covers only titles containing that word; a list covers the ways that department's roles are actually titled.
| Department | Keywords |
|---|---|
| Finance | finance, financial, accounting, controlling, controller, treasury, tax, audit |
| Legal | legal, legal affairs, compliance, counsel, contracts, regulatory affairs |
| Support | support, customer support, customer service, customer care, customer success, technical support, help desk |
| Creative | creative, design, art, art director, content, video, graphic design, ux, copywriting |
| Human resources | human resources, hr, people, talent, talent acquisition, recruiting, recruit, personnel |
| Operations | operations, supply chain, logistics, production, manufacturing, procurement, plant, facilities |
| Sales | sales, business development, commercial, account management, account executive |
| Marketing | marketing, brand, growth, communications, digital marketing, product marketing |
| Engineering | engineer, engineering, software, developer, technology |
- Add local-language words for non-English markets (for example "Leiter", "Directeur", "Gerente").
- A broader list trades a little precision for reach: check a page of results before you run a large pull.
Current, past or any job
Titles and company filters apply to the current job unless you set
jobStatus:
jobStatus | Matches |
|---|---|
omitted, or { "status": "currently-employed" } | The person's current job |
{ "status": "previously-employed" } | A past job (optionally with leftAt) |
{ "status": "ever-employed" } | Any job, current or past |
A title search over any job typically returns two to three times as many people as the current-job default.
Keywords
keywordsV2 matches phrases: the words of each term, in order, case
ignored. By default it searches most of a profile: headline, summary, current
and past titles, skills, education and more. That's right for "mentions X
anywhere"; for "works as X", limit it to titles:
"keywordsV2": {
"clauses": [{ "terms": ["machine learning"], "operator": "OR" }],
"options": { "fieldsToSearchOver": { "currentJobTitles": true, "summary": false, "headline": false, "pastJobTitles": false, "pastJobSummaries": false, "pastCompanyNames": false, "currentJobSummaries": false, "currentCompanyNames": false, "interests": false, "skills": false, "industry": false, "education": false, "publications": false, "certifications": false, "articles": false, "courses": false, "projects": false, "patents": false, "volunteering": false, "languages": false } }
}Terms in one clause combine with operator (OR by default); clauses combine
with AND; negate: true excludes a clause. Keywords don't match inside
words — "eng" won't match "engineer".
Industries
Two different filters are called "industry":
| Filter | What it is | Where |
|---|---|---|
industry | The industry on the person's own profile | People search |
linkedinIndustries | The employer's industry, using current LinkedIn industry names | Company search, combined search (companyParams) |
industriesV2 | The employer's industry in Fiber's broader standard categories | Company search, combined search (companyParams) |
- For "people at companies in an industry", use combined search with
linkedinIndustriesorindustriesV2: the industry then applies to the employer and combines with the rest of your company conditions in one query. - One broad industry often spans several current names. Retail, for example, includes Retail, Retail Groceries, Online and Mail Order Retail, Retail Apparel and Fashion and more. Send all of them.
- Get names from the industries list (
GET /v1/enums/industries, free). It returns every valid name with its company count, so you can drop names that match no companies. industriesV2is the quick way to a broad category;linkedinIndustriesis precise.
The full picture, including how to pick values that actually match companies, is in industry filtering.
linkedinIndustries values must match exactly. A misspelled or retired
name (for example the older "Computer Software" instead of "Software
Development") returns zero people with no error or warning. Build your
lists from the industries list.
Company size and revenue
employeeCountV2takes one range:{ "lowerBoundExclusive": 10, "upperBoundInclusive": 200 }: arbitrary bounds, not just preset bands. Watch the boundary rule: the lower bound is exclusive, except 0, which is inclusive. Details and examples: sizing and locating companies.revenueRangeUSDtakes one range:{ "lowerBound": 1000000, "upperBound": 10000000 }. It matches companies whose revenue figure falls in the range.
A revenue filter only returns companies that have a revenue figure. Many small and private companies don't publish one, so revenue filters on small companies return a small share of them. To target small businesses, filter on employee count instead.
Company filters in combined search reach people whose current employer Fiber has identified. For broad sizing, compare a combined count with the same people search without company filters.
Past employers
To find people by what a past employer looked like (its industry, size,
location), use combined search with profileParams.jobStatus set to
previously-employed. The title and company conditions then apply to the same
past job.
This matches a past job entry, not "has left". Someone who held the role earlier at the same company, and still works there, also matches. If you need people who have left, check the current job in the results.
Employer details on each person
Set getDetailedWorkExperience: true in people search to get
detailed_work_experiences, where each job carries company_details:
the employer's domains, LinkedIn org ID and industries. No extra charge, and
no separate company lookup per employer.
Validation, errors and warnings
| You send | You get |
|---|---|
An unknown field inside searchParams, profileParams or companyParams (for example gender, or a typo) | 400 — Unrecognized key(s) in object: 'gender' |
An invalid value for a fixed list (a person industry, a country code) | 400 listing the valid values |
An unknown top-level field (for example includeCounts instead of includeCount) | 200 — the field is ignored and reported in warnings |
A misspelled free-text value (linkedinIndustries names) | 200 with zero results, no warning |
A top-level typo still returns results, so it's easy to miss:
{
"output": { "data": ["…"], "nextCursor": "…" },
"warnings": [
{
"field": "includeCounts",
"message": "You passed an extraneous field 'includeCounts'. Did you mean to pass this field somewhere else? …"
}
]
}Fail loudly on warnings in your integration:
const res = await fetch("https://api.fiber.ai/v1/people-search", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body) });
const json = await res.json();
if (!res.ok) throw new Error(json.message);
if (json.warnings?.length) throw new Error(`Search warnings: ${JSON.stringify(json.warnings)}`);res = requests.post("https://api.fiber.ai/v1/people-search", json=body)
res.raise_for_status()
if res.json().get("warnings"):
raise RuntimeError(f"Search warnings: {res.json()['warnings']}")Prefer the current fields: jobs instead of pastJobs/currentJobs,
jobTitleV3 instead of jobTitle/jobTitleV2, keywordsV2 instead of
keywords.
What search doesn't filter on
- Gender and other protected characteristics are not available as search filters.
- Email, phone and social profiles aren't search filters. To go from an email or phone number to a person, use reverse lookup (the reverse email and reverse phone operations, linked from the operations index).
- Several size or revenue ranges, or size/revenue excludes, aren't
supported yet. Run one search per range, or use a single wider range.
Industry and country filters do support excludes (
noneOf). - Natural-language search reports anything it can't express in
unsupportedFilters.
Counting
includeCount: trueon a search and the matching count endpoints return the same number. Counts cover all matches — they aren't capped.- The combined count operation estimates the people count by default.
Pass
getFastEstimate: falsefor an exact number when you report or compare results; it takes a little longer. The response'sisEstimateflag tells you which mode produced the number. - Exclusion lists apply to results, not to counts.
Caching, what counts skip, and the fair-benchmark recipe are in search counts.
Paging
Set sort whenever you page. Without it, results have no guaranteed
order, and the same person can appear on two pages. With sort, page order
is stable.
{
"searchParams": {
"country3LetterCode": { "anyOf": ["USA"] },
"jobTitleV3": { "anyOf": [{ "type": "functional", "seniority": ["vp"], "keywords": ["sales"] }] },
"sort": [{ "field": "followerCount", "direction": "desc" }]
},
"pageSize": 100
}Pass nextCursor from each response as cursor in the next request, with the
same searchParams. See pagination.
Comparing Fiber with another provider
- Translate vocabularies deliberately. Levels (owner/partner as title words), departments (keyword lists), industries (every current name, on the employer). The translation tables are in migrating from another data provider.
- Match semantics. Exact vs non-exact titles; current job vs any job; country vs radius vs state.
- Use exact counts (
getFastEstimate: false) and readwarningson every call. - Sample the people. Pull 25 or more profiles from each side for the same search and check they're the people you meant. A bigger number isn't automatically better — and a smaller one isn't automatically missing data.
- Report per filter type, not one blended number.
- Send us your request bodies if a result looks off — we'll help you write them.
Worked examples
Each example shows a request that looks right, what goes wrong, and the fix.
Partners at small accounting firms
Looks right: combined search, linkedinIndustries: ["Accounting"],
employees ≤ 50, seniority c-suite.
What goes wrong: partners and owners aren't a seniority, so the search returns only "Chief …" and founder titles.
Fix: keep c-suite and add owner/partner title words — the corrected
request returned nearly three times as many people.
{
"companyParams": {
"linkedinIndustries": { "anyOf": ["Accounting"] },
"employeeCountV2": { "lowerBoundExclusive": 0, "upperBoundInclusive": 50 }
},
"profileParams": {
"country3LetterCode": { "anyOf": ["USA"] },
"jobTitleV3": {
"anyOf": [
{ "type": "functional", "seniority": ["c-suite"] },
{ "type": "plain", "term": "owner", "exact": false },
{ "type": "plain", "term": "partner", "exact": false },
{ "type": "plain", "term": "managing partner", "exact": false },
{ "type": "plain", "term": "principal", "exact": false }
]
}
}
}Heads of legal
Looks right: functional with seniority head, director, vp and
keywords ["legal"].
What goes wrong: only titles containing "legal" match; "VP, Compliance" and "Director of Regulatory Affairs" don't.
Fix: a department keyword list — about five times as many people, all legal and regulatory leaders.
"jobTitleV3": {
"anyOf": [{
"type": "functional",
"seniority": ["head", "director", "vp"],
"keywords": ["legal", "legal affairs", "compliance", "counsel", "contracts", "regulatory affairs"]
}]
}Product leaders at software companies
Looks right: linkedinIndustries: ["Computer Software"].
What goes wrong: that name is retired, so the search returns zero — with no error.
Fix: current names from the industries list (GET /v1/enums/industries):
["Software Development", "Desktop Computing Software Products", "Mobile Computing Software Products", "Embedded Software Products"].
Managers at banks
Looks right: people search with industry: { "anyOf": ["Banking"] }.
What goes wrong: that's the industry on the person's own profile. It answers "people who describe themselves as banking", not "people who work at companies in banking" — and only the employer's industry combines with company conditions like size or location.
Fix: combined search with the employer's industry:
{
"companyParams": { "linkedinIndustries": { "anyOf": ["Banking"] } },
"profileParams": {
"country3LetterCode": { "anyOf": ["FRA"] },
"jobTitleV3": { "anyOf": [{ "type": "functional", "seniority": ["manager", "director"] }] }
}
}Founders of small companies
Looks right: revenueRangeUSD: { "lowerBound": 0, "upperBound": 5000000 }.
What goes wrong: most small companies have no revenue figure, so they're left out.
Fix: size by headcount —
employeeCountV2: { "lowerBoundExclusive": 0, "upperBoundInclusive": 20 }
returned dozens of times more founders.
Customer success managers
Looks right: { "type": "plain", "term": "customer success manager", "exact": true }.
What goes wrong: exact matching skips "Senior Customer Success Manager" and "Manager, Customer Success".
Fix: "exact": false — about twice as many people, all in the role.
"Machine learning" people
Looks right: keywordsV2 with ["machine learning"].
What goes wrong: keywords search the whole profile, so founders, speakers and managers who mention machine learning match too.
Fix: limit to currentJobTitles when you mean "works as" — the results
become machine learning engineers. Keep all fields when you mean "has
experience with".
Anyone who has been a product designer
Looks right: plain term "product designer".
What goes wrong: titles match the current job only.
Fix: add "jobStatus": { "status": "ever-employed" } — about two and a
half times as many people.
A typo that fails silently
Looks right: "includeCounts": true next to searchParams.
What goes wrong: the response is 200 with results but no count; the
field is listed in warnings.
Fix: "includeCount": true — and treat any warnings as an error.
Cost and rate limits
| Operation | Rate limit (per minute) |
|---|---|
peopleSearch, peopleSearchCount | 180 |
companySearch, companyCount | 180 |
combinedSearchCount | 120 |
paginatedCombinedSearch | 30 |
| Typeaheads | 240 |
getIndustries and other lists | 120 (free) |
Searches are billed per result returned; see Billing and
search cost. Every response's chargeInfo is the
authoritative record of what a call cost.
Related
- Search — filters, ordering, pagination and combined search
- Search counts — exact vs estimated, caching, benchmarking
- Industry filtering — person vs employer industry, valid values
- Sizing and locating companies — arbitrary ranges, city search
- Migrating from another data provider — department, seniority and title translation tables
- Typeaheads — resolve names to exact values
- Natural-language search — describe the search in plain English
- Reverse email lookup — email or phone to person
- Exclusion lists — skip people you've already reached
Search
Query 50M+ companies and 500M+ professional profiles with structured filters — count for free, then pull only the results you want.
Search counts
Count matching companies and people before you pull a single result — what's exact, what's estimated, and the two caveats that matter when a count feeds a report or a benchmark.