LinkedIn Profile Scraper - No Cookies, No Login avatar

LinkedIn Profile Scraper - No Cookies, No Login

Pricing

$2.99 / 1,000 profiles

Go to Apify Store
LinkedIn Profile Scraper - No Cookies, No Login

LinkedIn Profile Scraper - No Cookies, No Login

Pricing

$2.99 / 1,000 profiles

Rating

0.0

(0)

Developer

Lantern Lab

Lantern Lab

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

10 days ago

Last modified

Categories

Security

Limited permissions

Share

Turn public LinkedIn profile URLs into structured career data: full name, location and country, profile photo, exact follower count, connections, About text, certifications, languages, volunteering, projects, publications, honours and courses - plus headline and the full experience and education history on the profiles LinkedIn shows those for. $2.99 per 1,000 profiles, no start fee - and only profiles we actually read are charged. No LinkedIn login, no cookies, no account of your own, ever.

Read this before you buy. LinkedIn puts the work and study history of most profiles behind its sign-in blur, and no logged-out scraper can get past it. In our measurement of 22 real profiles, 4 returned the full experience and education history and 8 did not. The 8 still returned everything else in full - name, location, photo, followers, connections, About, certifications, languages, volunteering, projects, publications, honours, courses. Those rows are marked experienceEducationBlurred: true with partialReason: "experience_education_blurred", so you always know which kind you got. If full job history on every profile is what you need, no cookie-free Actor can give it to you.

Input:

{
"profileUrls": [
"https://www.linkedin.com/in/williamhgates",
"uk.linkedin.com/in/satyanadella",
"melindagates"
]
}

Output - one row per URL you gave, in your order. Sample from the real page of /in/williamhgates:

{
"recordType": "profile",
"status": "ok",
"inputUrl": "https://www.linkedin.com/in/williamhgates",
"profileUrl": "https://www.linkedin.com/in/williamhgates",
"publicIdentifier": "williamhgates",
"canonicalUrl": "https://www.linkedin.com/in/williamhgates",
"duplicateOf": null,
"partial": false,
"partialReason": null,
"statusText": "This profile was read from its public LinkedIn page.",
"fullName": "Bill Gates",
"firstName": "Bill",
"lastName": "Gates",
"headline": "Chair, Gates Foundation and Founder, Breakthrough Energy",
"location": { "text": "Seattle, Washington, United States", "country": "US" },
"profilePictureUrl": "https://media.licdn.com/dms/image/v2/D5603AQF-RYZP55jmXA/profile-displayphoto-shrink_200_200/…",
"followersCount": 40747516,
"followersText": "41M followers",
"connectionsText": "8 connections",
"about": "Chair of the Gates Foundation. Founder of Breakthrough Energy. Co-founder of Microsoft. Voracious reader. Avid traveler. Active blogger.",
"experience": [
{
"title": "Co-chair",
"companyName": "Gates Foundation",
"companyLinkedinUrl": "https://www.linkedin.com/company/gates-foundation",
"location": null,
"startDate": "2000",
"endDate": null,
"isCurrent": true,
"durationText": "26 years",
"description": null
}
],
"education": [
{
"school": "Harvard University",
"schoolLinkedinUrl": "https://www.linkedin.com/school/harvard-university/",
"degree": null,
"fieldOfStudy": null,
"startDate": "1973",
"endDate": "1975"
}
],
"certifications": [],
"languages": [],
"volunteering": [],
"projects": [],
"publications": [],
"honors": [],
"courses": [],
"collectedAt": "2026-10-24T15:32:10.411Z"
}

Limits - read these before you buy:

  • Most profiles' experience and education are behind LinkedIn's sign-in blur. LinkedIn serves them one combined "Experience & Education" block with a single entry visible and the rest blurred out, and masks the same entries inside the page's structured data with asterisks. Those masked values are never written out as if they were data; experience and education then hold whatever fragment was actually visible, or nothing, and the row carries experienceEducationBlurred: true plus a statusText sentence saying so. An empty experience on a flagged row does not mean the person has no work history. The same profiles also get their About text cut short behind a "see more" prompt (aboutTruncated: true).
  • No email addresses, no phone numbers, no personal websites. LinkedIn does not show them to a logged-out visitor, and this Actor does not buy them from a contact-enrichment service either. If you need them, this is the wrong Actor.
  • No headline on a blurred profile. LinkedIn renders no headline element at all on that variant, so headline is null there rather than guessed from the About text or the current role.
  • No skills. LinkedIn renders the skills section only after sign-in, so there is nothing to read.
  • No posts, no activity, no other people. The profile page also carries the member's articles and posts and lists of other members ("Other similar profiles", "People also viewed"). None of it is read or written.
  • Guest-visible content only. What you get is what LinkedIn itself publishes to a visitor with no account. A member who hides their About section, or whose experience LinkedIn truncates for guests, gives you less - and the row says so rather than pretending the profile is empty.
  • Fields LinkedIn leaves out are null, sections it does not have are []. Nothing is guessed from another field. location.country is the ISO code LinkedIn's own structured data carries, or null - never derived from the location words. followersCount is the exact figure when LinkedIn's structured data carries it; the page itself rounds ("41M followers"), and the rounded wording is kept in followersText instead of being turned into a made-up number.
  • firstName / lastName are the first word and the rest of the displayed name. LinkedIn does not publish the two parts separately, so compound given names and some name orders split wrongly. fullName is always the name as LinkedIn displays it.
  • Dates are LinkedIn's own strings ("2000", "Jan 2019"), kept verbatim rather than reformatted, because LinkedIn itself only shows a year for older roles.
  • Some members have public profile visibility switched off. LinkedIn then sends the sign-in wall for them, to everyone, from every IP. Those rows get status: "not_public" and are not charged. In our 22-profile test 10 were like this, and the figure says nothing about your proxy: a datacenter run and a residential run were refused the same 10 and read the same 12, and re-fetching those 10 from fresh IPs reproduced it exactly while readable profiles kept working. Switching to the residential pool does not help - it cost 2.8x more for an identical result - so the default datacenter pool is the right one.

What it does

  • Reads one page per profile: linkedin.com/in/<identifier>, logged out. No cookie is sent and none is kept - a cookie is not even accepted as input.
  • Accepts the URL forms you actually have: full URLs, country subdomains (uk.linkedin.com/in/…, which LinkedIn redirects to www itself), URLs with tracking or locale parameters, /in/<id> paths, and bare identifiers. Everything is normalised to one canonical URL, so /in/WilliamHGates and /in/williamhgates are one profile.
  • One row per input line, in your order, always - including a line that was invalid, refused, or never reached. You can join the output straight back onto your own list with no holes. The same profile listed twice is fetched once and charged once; the repeat row carries the same data and names the earlier entry in duplicateOf.
  • Reads LinkedIn's own schema.org Person block first (the authoritative name, location, country code, photo and exact follower count) and the rendered page sections second (headline, About, each role's own job title, the month-level date ranges, the duration LinkedIn prints, and the secondary sections).
  • Never reports an incomplete read as an empty profile. status is ok, not_public (the sign-in wall on every attempt), invalid_url (not a LinkedIn profile address - costs no request and is free), upstream_error, not_collected (the run stopped before this line) or not_found (HTTP 404). statusText on every row says which it is in a sentence. Note that LinkedIn gives a guest the same sign-in wall whether a profile is hidden or simply does not exist, so not_public covers both and says so; a typo in your list is not distinguishable from a private profile, by anyone.
  • Flags a row that was read but is not the whole picture with partial: true and a partialReason: experience_education_blurred (LinkedIn paywalled the work and study history - see the warning above), no_structured_data (LinkedIn served the page without its Person block, so the exact follower count, country code and photo may be missing), empty_profile (a page with no name on it - written, flagged, not charged), upstream_request_cap, charge_limit_reached.
  • Never writes out a masked value. Where LinkedIn substitutes asterisks for a company or school name, the field is null and the row is flagged - "******* ******" is not a company name and does not belong in your database.
  • Keeps the source identity of every row: your inputUrl, the canonical profileUrl, LinkedIn's publicIdentifier, the canonicalUrl the page says it is (which differs when LinkedIn redirected the identifier), and our own collectedAt. LinkedIn publishes no "last updated" time for a profile, so collectedAt is the only time a row can carry.
  • Caps itself: maxUpstreamRequests is a hard ceiling on requests to LinkedIn for the whole run, retries included, derived from your list when you leave it empty, so a run is never unbounded.

Input

FieldWhat it does
profileUrlsPublic LinkedIn profiles, one per line. Full URL, country subdomain, /in/<id> path or bare identifier. Required.
maxUpstreamRequestsOptional hard ceiling on requests to LinkedIn for the whole run, retries included. Default: derived from your list.
proxyConfigurationWhere requests come from. Default: the Apify datacenter proxy, which measured identical results to residential at a third of the cost.

Output

  • recordType: "profile" - one per input line. Charged only when status is ok and partialReason is not empty_profile, and only once per distinct profile.
  • recordType: "RUN_SUMMARY" - the last row, also stored under the key RUN_SUMMARY: rows written and charged, a count per status, incomplete rows by reason, repeated and invalid lines, the success rate over the profiles a request was actually sent for, average requests per profile, requests and retries sent to LinkedIn, and why collection stopped. Free.

Pricing

Pay per result: $2.99 per 1,000 profiles, no start fee. Rows with any status other than ok are free, an empty_profile row is free, a repeated profile is charged once, and the run summary is free. Set a maximum charge per run in Apify and the Actor stops at it, keeping what it already collected and marking the rest not_collected.

Responsible use

This Actor reads only what LinkedIn publishes to visitors who are not logged in, and it keeps to professional information. It is still personal data, and using it is your responsibility, not ours:

  • You need a lawful basis. Under the GDPR and comparable laws, scraping publicly available personal data is still processing personal data. Decide and document your lawful basis (usually legitimate interests, with the balancing test done) before you run this at scale, and give data subjects the information those laws require.
  • Do not use it for spam. Unsolicited bulk outreach to scraped contacts is prohibited by this Actor's terms of use, and in most jurisdictions by law. This Actor deliberately returns no email address and no phone number.
  • Honour deletion and objection requests. If a person asks you to delete their data or objects to your processing, do it - including in any copy you derived from this output. Keep the collectedAt timestamp so you can tell how old a record is, and refresh or drop stale records.
  • LinkedIn's terms are your responsibility. LinkedIn's User Agreement restricts automated collection. This Actor does not log in and therefore does not accept that agreement on your behalf, but you must satisfy yourself that your own use is lawful and acceptable where you operate. Consider whether you need the data at all, and collect the minimum you do need.
  • Never use it for decisions that need accuracy you cannot verify. A profile is self-reported and may be out of date. Do not use it as the sole basis for employment, credit, insurance or any other decision that materially affects a person.