POST /api/linkedin/search/sql/users
Price: 20 credits
Find LinkedIn people by role, seniority, company, industry, company size, location, skills and education. Built for ICP discovery, buying-committee mapping, alumni lists and lookalikes.
Combine `keywords` with at least one selective filter — it only helps for distinctive words. Most attributes here are sparse, so a filter on one also means 'and this person states it' — each field says how sparse it is, the `has_*` flags make the narrowing explicit, and `dry_run` sizes a filter set before it is run for real. The badge and engagement filters never combine with `similar_to`/`also_viewed`: no record carries both, so any pairing of the two returns nothing. When more people match than `count`, the answer is an unbiased sample of them and repeating the request returns the same people, so narrow the filters or walk the rest with `bucket_total` and `bucket_index` rather than calling again for more.
access-token string requiredtimeout integer — Max scrapping execution timeout (in seconds) (default: 300; min: 20; max: 1500)keywords string — Token search across name, headline, summary, every role title, every company name and the companies' speciality lists. Matches whole words, so a common one matches most people — always combine it with at least one selective filter. (default: "")name string — Search in `name`. Mini-DSL: whitespace=AND, `|`=OR (no spaces around `|`), `"phrase"`=exact phrase, `-token`=NOT. Example: `sales|revenue "account executive" -intern`. (default: "")headline string — Search in `headline`. Mini-DSL: whitespace=AND, `|`=OR (no spaces around `|`), `"phrase"`=exact phrase, `-token`=NOT. Example: `sales|revenue "account executive" -intern`. (default: "")summary string — Search in the profile summary. Stated by a minority of people, so the filter also drops everyone who states nothing. Mini-DSL: whitespace=AND, `|`=OR (no spaces around `|`), `"phrase"`=exact phrase, `-token`=NOT. Example: `sales|revenue "account executive" -intern`. (default: "")alias array — Batch lookup by exact LinkedIn slug. (default: [])urn array — Batch lookup by exact profile URN. All three forms this platform prints are accepted: 'fsd_profile:ACoAA…', 'urn:li:fsd_profile:ACoAA…', and the bare 'ACoAA…'. A value carrying a URL path, whitespace, or another type's prefix — a member URN, say — is rejected with a 422 naming the field to use. A bare token is read as a profile id whatever it looks like, so a public slug sent here is NOT rejected: it simply matches nobody. Slugs belong in `alias`, member ids in `member_id`. A URN that matches nobody comes back as an empty list, not an error, so an id that is merely absent is indistinguishable from one that is wrong or sent to the wrong field. (default: [])member_id array — Batch lookup by member id. All three spellings are accepted: 'member:115562011', 'urn:li:member:115562011', and the bare '115562011'. A value carrying a URL path, whitespace, or another type's prefix — a profile URN, say — is rejected with a 422 naming the field to use. A bare token is read as a member id whatever it looks like, so a public slug sent here is NOT rejected: it simply matches nobody. Slugs belong in `alias`, profile URNs in `urn`. A member id that matches nobody comes back as an empty list, not an error, so an id that is merely absent is indistinguishable from one sent to the wrong field. (default: [])last_name array — Exact surname, matched on a folded key: diacritics, case, punctuation and spacing are ignored, so 'van der Berg', 'Van Der Berg' and 'vanderberg' are one value. (default: [])first_initial array — First letter of the given name, lowercased. Pair with `last_name` for 'J. Smith'. (default: [])current_title string — Search in the current role title. Read from the current role, which resolves for about a third of people — `has_current_role` makes that narrowing explicit. Mini-DSL: whitespace=AND, `|`=OR (no spaces around `|`), `"phrase"`=exact phrase, `-token`=NOT. Example: `sales|revenue "account executive" -intern`. (default: "")any_title string — Search across ALL role titles, past included. Mini-DSL: whitespace=AND, `|`=OR (no spaces around `|`), `"phrase"`=exact phrase, `-token`=NOT. Example: `sales|revenue "account executive" -intern`. (default: "")seniority array — Current seniority. One of ['unknown', 'entry', 'ic', 'senior_ic', 'manager', 'head', 'vp', 'founder', 'cxo']. Read from the current role, which resolves for about a third of people — `has_current_role` makes that narrowing explicit. (default: [])seniority_min string nullable — Current seniority at or above this level — 'head' means Head, VP, founder, CXO. Read from the current role, which resolves for about a third of people — `has_current_role` makes that narrowing explicit.function array — Current function. One of ['unknown', 'other', 'none', 'sales', 'marketing', 'engineering', 'product', 'data', 'finance', 'hr', 'ops', 'legal', 'support', 'exec', 'education', 'healthcare', 'trades', 'admin']. Read from the current role, which resolves for about a third of people — `has_current_role` makes that narrowing explicit. (default: [])any_function array — Function held in ANY role, past included. (default: [])current_company_name string — Search in the current company. Read from the current role, which resolves for about a third of people — `has_current_role` makes that narrowing explicit. Mini-DSL: whitespace=AND, `|`=OR (no spaces around `|`), `"phrase"`=exact phrase, `-token`=NOT. Example: `sales|revenue "account executive" -intern`. (default: "")current_company_id array — Exact LinkedIn numeric company ids. Read from the current role, and only from what that role states about the employer, so it answers for about one person in five — narrower than `has_current_role`, which gates the role itself and not the employer's details. (default: [])current_company_domain array — Bare domains, e.g. ['acme.com']. Scheme, `www.` and path are stripped on both sides. Read from the current role, and only from what that role states about the employer, so it answers for about one person in five — narrower than `has_current_role`, which gates the role itself and not the employer's details. (default: [])any_company_id array — Worked there at any point, current or past. (default: [])past_company_id array — Worked there and has since left (S11 alumni). (default: [])any_company_domain array — Worked at a company on this domain at any point, current or past. (default: [])industry array — Current company industry. Either a taxonomy label or an industry URN — `software development`, `industry:4` and `4` all resolve to the same value, case-insensitively; a URN of any other type is rejected by name. A value this deployment cannot search is rejected with 422 naming the closest labels it can, so a typo never reads as an empty market. The vocabulary is LinkedIn's published industry-codes-v2 table, but only the part indexed here, which is narrower than what LinkedIn shows on a profile: labels outside it — finance, education, construction and hospitality among them — are stored as company keywords, so no filter reaches them yet. `linkedin/search/industries` resolves a name against LinkedIn live and can therefore return a URN this filter still rejects. Stated for roughly one person in eight — `has_industry` gates on ANY company, so it does not guarantee a match here; `any_industry` is the filter it belongs to. (default: []; examples: ["software development","industry:96"])any_industry array — Industry of ANY company worked at, past included — 'has worked in this sector'. Either a taxonomy label or an industry URN — `software development`, `industry:4` and `4` all resolve to the same value, case-insensitively; a URN of any other type is rejected by name. A value this deployment cannot search is rejected with 422 naming the closest labels it can, so a typo never reads as an empty market. The vocabulary is LinkedIn's published industry-codes-v2 table, but only the part indexed here, which is narrower than what LinkedIn shows on a profile: labels outside it — finance, education, construction and hospitality among them — are stored as company keywords, so no filter reaches them yet. `linkedin/search/industries` resolves a name against LinkedIn live and can therefore return a URN this filter still rejects. Stated by a minority of people, so the filter also drops everyone who states nothing. Gate it with `has_industry`. (default: []; examples: ["it services and it consulting"])employee_range array — Company size band of the current company, one of ['0-1', 'myself only', '2-10', '11-50', '51-200', '201-500', '501-1000', '1001-5000', '5001-10000', '10001+']; anything else is rejected with 422 rather than silently matching nobody. A profile prints the two edge bands as the bare '1' and '10001', and both are accepted here and read as 'myself only' and '10001+'. Read from the current role, and only from what that role states about the employer, so it answers for about one person in five — narrower than `has_current_role`, which gates the role itself and not the employer's details. `has_company_size` gates on ANY company, so it does not guarantee a match here. (default: []; examples: ["1001-5000","10001+"])employee_count_min integer nullable — Min current company headcount. Read from the current role, and only from what that role states about the employer, so it answers for about one person in five — narrower than `has_current_role`, which gates the role itself and not the employer's details.employee_count_max integer nullable — Max current company headcount. Read from the current role, and only from what that role states about the employer, so it answers for about one person in five — narrower than `has_current_role`, which gates the role itself and not the employer's details.country array — ISO2 country codes, e.g. ['US','GB']. Use this for a country, and add `location` alongside it for a place inside one, such as a city or a region. (default: [])location string — Search in the free-text location — a city, a region, a metro area. For a whole country use `country`. Mini-DSL: whitespace=AND, `|`=OR (no spaces around `|`), `"phrase"`=exact phrase, `-token`=NOT. Example: `sales|revenue "account executive" -intern`. (default: "")skills string — Search the skills list. Stated by a minority of people, so the filter also drops everyone who states nothing. Mini-DSL: whitespace=AND, `|`=OR (no spaces around `|`), `"phrase"`=exact phrase, `-token`=NOT. Example: `sales|revenue "account executive" -intern`. (default: "")languages string — Search the languages list. Stated by a minority of people, so the filter also drops everyone who states nothing. Mini-DSL: whitespace=AND, `|`=OR (no spaces around `|`), `"phrase"`=exact phrase, `-token`=NOT. Example: `sales|revenue "account executive" -intern`. (default: "")edu_slug array — Exact institution slugs, e.g. ['tu-delft']. (default: [])edu_institution string — Search institution names. Mini-DSL: whitespace=AND, `|`=OR (no spaces around `|`), `"phrase"`=exact phrase, `-token`=NOT. Example: `sales|revenue "account executive" -intern`. (default: "")edu_field string — Search field of study / degree text. Mini-DSL: whitespace=AND, `|`=OR (no spaces around `|`), `"phrase"`=exact phrase, `-token`=NOT. Example: `sales|revenue "account executive" -intern`. (default: "")edu_ended_year_min integer nullable — Graduated in or after this year.edu_ended_year_max integer nullable — Graduated in or before this year.months_in_role_max integer nullable — New in role: started at most this many months ago. Measured from today. Read from the current role, which resolves for about a third of people — `has_current_role` makes that narrowing explicit. (min: 0)months_in_role_min integer nullable — In the current role at least this long. Read from the current role, which resolves for about a third of people — `has_current_role` makes that narrowing explicit. (min: 0)experience_years_min integer nullable — First recorded role is at least this old. (min: 0)months_since_change_max integer nullable — Last started or ended a role at most this many months ago. (min: 0)n_roles_min integer nullable — At least this many recorded roles. (min: 0)n_roles_max integer nullable — At most this many recorded roles. (min: 0)n_companies_min integer nullable — Worked at at least this many companies. (min: 0)n_companies_max integer nullable — At most this many companies — stability, not job-hopping. (min: 0)promotion_count_min integer nullable — Changed title at least this many times without changing employer. Stated by a minority of people, so the filter also drops everyone who states nothing. It needs two dated roles at one employer, which is why it is the narrowest of the tenure filters. (min: 0)avg_tenure_months_min integer nullable — Mean length of the finished roles, in months. Ignores the current one. (min: 0)avg_tenure_months_max integer nullable — Upper bound on the same mean. (min: 0)profile_score_min integer nullable — How complete the profile is: one point each for roles, education, skills, headline, summary, photo, country and industry. Use it to demand rich profiles. (min: 0; max: 8)is_creator boolean nullable — Creator badge. Not carried by the response. Only a freshly scraped profile carries this flag at all; on everyone else it is unset, and unset matches neither setting. So `false` is not the complement of `true` — both narrow to the same small population, and `false` is no way to exclude the badge.is_influencer boolean nullable — Influencer badge. Not carried by the response. Only a freshly scraped profile carries this flag at all; on everyone else it is unset, and unset matches neither setting. So `false` is not the complement of `true` — both narrow to the same small population, and `false` is no way to exclude the badge. It is also the rarest badge by a wide margin — expect a handful of people, not a list.is_top_voice boolean nullable — Top Voice badge. Only a freshly scraped profile can carry the badge; everywhere else it is recorded as `false`. So `true` narrows hard, and `false` excludes almost nobody.is_premium boolean nullable — Premium subscriber. Only a freshly scraped profile can carry the badge; everywhere else it is recorded as `false`. So `true` narrows hard, and `false` excludes almost nobody.open_to_work boolean nullable — Open-to-work badge. `false` means no badge was observed, which is not the same as the person not looking. Only a freshly scraped profile can carry the badge; everywhere else it is recorded as `false`. So `true` narrows hard, and `false` excludes almost nobody.hiring boolean nullable — Hiring badge. Same caveat as `open_to_work`. Only a freshly scraped profile can carry the badge; everywhere else it is recorded as `false`. So `true` narrows hard, and `false` excludes almost nobody.verified boolean nullable — Identity-verified. Only a freshly scraped profile can carry the badge; everywhere else it is recorded as `false`. So `true` narrows hard, and `false` excludes almost nobody.follower_count_min integer nullable — At least this many followers. Only a small share of profiles state one, and it is the same freshly scraped population that carries the badges — gate it with `has_engagement`.connection_count_min integer nullable — At least this many connections. Stated about as rarely as the follower count, and by the same people — gate it with `has_engagement`.similar_to array — Aliases whose 'similar profiles' graph should be searched (lookalike seed). Stated by a minority of people, so the filter also drops everyone who states nothing. It is also the mirror image of the badge and engagement filters: no record carries both, so pairing this with one of those matches nobody at all. (default: [])also_viewed array — Aliases from the 'people also viewed' graph — a looser lookalike than `similar_to`. Stated by a minority of people, so the filter also drops everyone who states nothing. Same mutual exclusion with the badge and engagement filters. (default: [])has_current_role boolean nullable — Only people whose current employer can be resolved — a role with a start and no end. Left unset, people without one are included.has_industry boolean nullable — Only people where SOME company on the profile states an industry, past employers included. It is the gate for `any_industry`; the current company states one about half as often, so it does not guarantee a match on `industry`.has_company_size boolean nullable — Only people where SOME company on the profile states a size, past employers included. The current company states one about half as often, so it does not guarantee a match on `employee_range` or `employee_count_min`/`max`.has_education boolean nullable — Only people stating an education entry.has_roles boolean nullable — Only people stating any role history.has_role_dates boolean nullable — Only people with at least one dated role — required for the tenure filters.has_engagement boolean nullable — Only people stating a follower count or a creator badge — well under one person in a hundred, the narrowest gate here. Set it before using the engagement or badge filters so the narrowing is deliberate rather than accidental.fetched_after integer nullable — Only people whose profile was refreshed at or after this unix timestamp.bucket_total integer nullable — Divide the matching people into this many equal parts, so a team can split a territory without overlap. The same person always lands in the same part. (min: 2; max: 100)bucket_index integer nullable — Which part to return, counting from zero. (min: 0)count integer required — Max result count. A `dry_run` request ignores it. (max: 1000; >: 0)dry_run boolean — Return how many people match these filters instead of the people. The response is a 209 with an empty body and the number in the headers, so a filter set can be sized before it is run for real. It counts distinct people, the same unit a normal call returns, and stops at 100000 — a wider filter set reports exactly that and means 'at least'. (default: false)@type string (default: "LinkedinUser")internal_id object nullabletype string required (one of: "fsd_company", "fsd_group", "fsd_profile", "fsd_skill", "activity", "comment", "company", "group", "geo", "pulse", "member", "industry", "ugcPost", "job", "message", "conversation", "media", "share", "linkedInArticle")value string requiredurn object nullabletype string required (one of: "fsd_company", "fsd_group", "fsd_profile", "fsd_skill", "activity", "comment", "company", "group", "geo", "pulse", "member", "industry", "ugcPost", "job", "message", "conversation", "media", "share", "linkedInArticle")value string requiredname string requiredfirst_name string nullablelast_name string nullablealias string requiredurl string requiredheadline string nullableheadlines array nullable@type string (default: "LinkedinUserHeadline")locale string requiredtext string requiredis_primary boolean (default: false)follower_count integer nullableimage string nullablebackground_image string nullableconnection_count integer nullabledescription string nullabletop_skills array nullableframe string nullable (one of: "open_to_work", "hiring")location string nullablecountry_code string nullablecountry string nullablecity string nullablepronouns string nullablecustom_pronouns string nullableexperience array nullable@type string (default: "LinkedinUserExperience")company object required@type string (default: "LinkedinUserExperienceCompany")name string requiredurn object nullabletype object required (see schema LinkedinURNPrefix)value string requiredurl string nullablealias string nullableindustry object nullabletype string required (one of: "industry")value string requiredindustry_full object nullable@type string (default: "LinkedinIndustry")urn object required (see schema LinkedinURN_Literal_industry__)name string requiredhierarchy string requireddescription string requiredemployee_range string nullablelogo_url string nullableposition string nullablework_type string nullable (one of: "on-site", "hybrid", "remote")employment string nullable (one of: "full-time", "part-time", "permanent", "self-employed", "freelance", "contract", "internship", "apprenticeship", "indirect contract")interval string nullablestart_date string nullable — Role start, `YYYY-MM` or `YYYY`.end_date string nullable — Role end, `YYYY-MM` or `YYYY`. Absent while ongoing.period string nullablelocation string nullabledescription string nullablemedias array nullable@type string (default: "LinkedinUserExperienceMedia")id string nullableurl string nullabletext string nullableimage string nullableeducation array nullable@type string (default: "LinkedinUserEducation")company object required@type string (default: "LinkedinUserEducationCompany")name string requiredurn object nullabletype object required (see schema LinkedinURNPrefix)value string requiredurl string nullablealias string nullableindustry object nullabletype string required (one of: "industry")value string requiredindustry_full object nullable@type string (default: "LinkedinIndustry")urn object required (see schema LinkedinURN_Literal_industry__)name string requiredhierarchy string requireddescription string requiredemployee_range string nullablelogo_url string nullablemajor string nullableinterval string nullabledescription string nullablelanguages array nullable@type string (default: "LinkedinUserLanguage")name string requiredlevel string nullablecertificates array nullable@type string (default: "LinkedinUserCertificate")name string requiredcompany object nullable@type string (default: "LinkedinUserCertificateCompany")name string requiredurn object nullabletype string required (one of: "fsd_company", "company")value string requiredurl string nullablecreated_at string nullablelabel string nullableurl string nullablehonors array nullable@type string (default: "LinkedinUserHonor")name string requiredissued_by string nullableissued_at string nullabletext string nullablepatents array nullable@type string (default: "LinkedinUserPatent")name string requiredid string nullableissued_at string nullabletext string nullableurl string nullableinventor_count integer nullableskills array nullable@type string (default: "LinkedinUserSkill")name string requiredurn object nullabletype string required (one of: "fsd_company", "fsd_group", "fsd_profile", "fsd_skill", "activity", "comment", "company", "group", "geo", "pulse", "member", "industry", "ugcPost", "job", "message", "conversation", "media", "share", "linkedInArticle")value string requiredverified boolean (default: false)is_premium boolean (default: false)is_top_voice boolean (default: false)fetched_at integer nullable422 — The request body did not validate Check the fields against this schema. A URN with the wrong prefix is the most common cause.408 — The request ran past its time limit Raise `timeout` in the request body, up to the maximum this endpoint documents. Lowering `count` or turning off the `with_*` flags also helps, because less work finishes sooner.412 — The entity was not found, or a precondition failed Retrying will not help: either the entity does not exist, or the input points at a different one.429 — Too many requests: a rate limit or a usage window is exhausted When the response carries an X-Retry-After header, wait that many seconds and retry: the same number is in the body as `detail.retry_after`, and the limit clears once that window passes. The message in the body names the limit that was hit.500 — Something broke on our side Retrying will not help. If it keeps happening, send us the X-Request-ID from the response headers.529 — Rate limit reached, or the endpoint is overloaded Wait at least 30 seconds, then retry.X-Error — Error message text (present only on error)X-Request-ID — Unique request identifierX-Execution-Time — Execution time in secondsX-Result-Count — How many records the body carries. 0 means an empty result, which is a normal answer and not by itself an error. A non-zero count can come back together with X-Error when the failure happened partway through — read this header and X-Error independently.X-Total-Available-Results — How many records exist for this query, when the endpoint can say. On a `dry_run` request this is the answer and the body is empty. It saturates: the endpoint's documented maximum means 'at least that many', any smaller number is exact.X-Warning — Present when the request body carried keys this endpoint does not document. They were ignored, so any filter you meant to apply through them did not apply. Check the spelling against this schema and retry.X-Retry-After — Seconds to wait before retrying. Present only on 429.