LinkedIn Profile Search Scraper - $0.50/1k, No Login
Pricing
from $0.50 / 1,000 profile founds
LinkedIn Profile Search Scraper - $0.50/1k, No Login
120 profiles a run is the ceiling here, and no LinkedIn account or cookie is used to get them. Name, headline, location, current role, company, education and profile URL, by keyword, job title, company, school or location. $0.50 per 1,000 plus a $0.001 run start.
Pricing
from $0.50 / 1,000 profile founds
Rating
0.0
(0)
Developer
Dami's Studio
Maintained by CommunityActor stats
0
Bookmarked
47
Total users
30
Monthly active users
2 days ago
Last modified
Categories
Share
LinkedIn Profile Search Scraper
Type a job title, a skill or a name, narrow it with a city or a company if you want, and get back public LinkedIn profiles as rows: full name, headline, location, current role, current company, education, connection count and the profile URL.
It doesn't use a LinkedIn account or a session cookie, so there's nothing for you to paste in and nothing that quietly expires a week later.
$0.50 per 1,000 profiles, plus a $0.001 run start fee. Flat on every plan.
Where the rows come from
LinkedIn's own people search sits behind the login wall. You can't open linkedin.com/search/results/people/ signed out, and you can't script it without an account.
The profile pages are a different matter. LinkedIn publishes every /in/<name> page to the open web so search engines can index it, with the member's name and headline in the title and a description spelling out experience, education and location. That published version is what this reads. It builds a query out of your keywords and filters, runs it against the public web index over rotating addresses, and turns the matching pages into rows.
That cuts both ways. Nothing here breaks when a cookie expires, because there is no cookie. But a profile that opted out of public visibility, or one the indexes never picked up, won't appear at all.
Input
Everything is optional. Give it a searchQuery, or filters, or both.
{"searchQuery": "software engineer","locations": ["San Francisco"],"currentCompanies": ["Stripe"],"maxItems": 50}
| Field | Notes |
|---|---|
searchQuery | Free text: "software engineer", "head of growth fintech", "Sarah Chen". |
locations | Keep profiles whose public page mentions one of these places. Several values are OR'd. |
currentJobTitles | Same, for job titles. |
currentCompanies | A company name or a full LinkedIn company URL, either works. |
schools | School or university name. |
maxItems | 1 to 120. Default 20. |
Output
{"ok": true,"recordType": "profile","profileUrl": "https://www.linkedin.com/in/shireennagdive","publicIdentifier": "shireennagdive","fullName": "Shireen Nagdive","firstName": "Shireen","lastName": "Nagdive","headline": "Engineering Leader @ Salesforce","location": "San Francisco Bay Area","currentPosition": "Engineering Leader","currentCompany": "Salesforce","education": "Stony Brook University","connections": "500+","snippet": "Experience: Salesforce · Education: Stony Brook University · Location: San Francisco Bay Area · 500+ connections on LinkedIn.","searchQuery": "site:linkedin.com/in software engineer \"San Francisco\"","foundVia": "primary-index","scrapedAt": "2026-08-21T16:20:44.453Z"}
| Field | Notes |
|---|---|
profileUrl | Country subdomains (uk.linkedin.com, ug.linkedin.com) are kept, because that's where the page lives. |
publicIdentifier | The slug after /in/. Use it as your dedupe key across runs. |
lastName | null for single-word names. |
currentPosition, currentCompany | Split out of the headline on "at" or "@", or read from the published "Experience:" line. A headline written as a keyword list is left alone — you get null rather than a guessed employer. |
connections | A string, because LinkedIn publishes "500+" as often as a number. |
snippet | The raw indexed description, so you can see what the match was based on. |
charged | true only on rows you actually paid for. |
Anything that couldn't be read is null. Nothing is inferred or padded.
Run it with empty input and you get one labelled sample row, uncharged. A search that finds nothing, or one the indexes refuse, gets a diagnostic row that says which of the two happened:
{"ok": false,"charged": false,"recordType": "diagnostic","code": "NO_RESULTS","requestsMade": 3,"droppedOffTarget": 40,"details": "The indexes answered, but all 40 profile(s) they returned failed your own filters, so none were kept or charged. Loosen a filter."}
Neither is billed, and neither fails the run.
How many profiles you can actually get
120 per run, and the input box stops there on purpose. Two cloud runs from 17 August 2026:
| Search | maxItems | Delivered | Time |
|---|---|---|---|
| "marketing manager" + London | 120 | 120 / 120 distinct | 18 s |
| "software engineer" + San Francisco | 20 | 20 / 20 distinct | 5 s |
An attempt at 200 came back with 169 and spent more than twice the requests getting there. 200 isn't a number worth printing next to a price, so the cap is 120.
Three caveats before you set maxItems to 120:
- A narrow search returns what exists and then stops. If only 40 public profiles anywhere match your terms, you get 40 and the run ends early. You're charged for what was delivered, never for what you asked for.
- Going deep trades relevance for volume. The first results are the closest matches. The deeper ones come from LinkedIn's international profile hostnames, where the index has confirmed your terms appear on the page but the person may not live in the city you typed. A Milan profile that mentions London will show up in a London search. If precision matters more, ask for fewer and add a job-title filter.
- Big runs back to back return less. The public index rate-limits by address. Several 120-profile runs fired within a few minutes of each other will start hitting refusals, and a run refused everywhere writes a free diagnostic row. Space them out, or prefer several smaller runs.
What it doesn't do
- No email addresses or phone numbers. They aren't on the public profile page, so they aren't here. This is people search, not contact enrichment.
- No full work history, skills, certifications or recommendations. Current role and headline as published, not the whole CV.
- No profile photos.
- No connection degree, no "who viewed you", no InMail. All of that needs an account.
- Private and unindexed profiles are invisible, and there's no keyless way around that.
- Filters match the whole published page, not just the snippet you see. A returned profile does contain your terms even when the short description doesn't repeat them.
- Location is a text match, not a geo radius. "San Francisco" won't pull in Oakland, and "Greater London Metropolitan Area" matches far less than plain "London". Use the short, common form of a place name.
- Ordering is the public index's relevance, not recency, and you can't control it.
Reliability
The public indexes rate-limit hard per address, so every request leaves through a different rotating datacenter address with a real browser TLS fingerprint. Two independent indexes are read in parallel and merged, so one being slow doesn't empty your run.
If everything is refused at once, which happens for a few minutes at a time, you get a diagnostic row, the run still succeeds, and no profiles are billed. Try again shortly after.
Each request is capped at 8 seconds and the whole search at 90, so a stalled network turns into a short run and an honest diagnostic instead of a long expensive one.
Billing
$0.001 when a run starts, then $0.0005 per profile row, which is $0.50 per 1,000. Flat on every plan.
One charge per profile actually written to your dataset. Sample rows, diagnostic rows and duplicates are never charged.