LinkedIn Profile Scraper avatar

LinkedIn Profile Scraper

Pricing

from $2.67 / 1,000 results

Go to Apify Store
LinkedIn Profile Scraper

LinkedIn Profile Scraper

Extract public LinkedIn profiles without cookies or an account: name, headline, location, follower count, current employer, education, work history, plus the person's public posts and articles. HTTP-only, no login, no browser.

Pricing

from $2.67 / 1,000 results

Rating

0.0

(0)

Developer

Farhan Febrian Nauval

Farhan Febrian Nauval

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

13 days ago

Last modified

Categories

Share

Extract public LinkedIn profiles — no cookies, no account, no browser. Give it profile URLs or slugs and it returns the person's name, headline, location, follower count, work history, education, and the public posts and articles shown on their profile.

HTTP-only (curl_cffi), public data only. Nothing behind the login wall is touched.

Input

FieldTypeDefaultDescription
profilesarrayrequiredProfile URLs (https://www.linkedin.com/in/williamhgates) or bare slugs (williamhgates)
includePostsbooleantruePublic posts embedded in the profile page, plus their activity IDs
includeArticlesbooleantrueLinkedIn articles authored by this person
maxAttemptsinteger4Retries (fresh exit IP + different country host) before accepting a redacted render
maxConcurrencyinteger4Profiles in parallel. Keep it low
proxyConfigurationobjectRESIDENTIALResidential strongly recommended

Output

One row per input, always — including failures, so downstream joins never silently lose a key.

{
"_input": "https://www.linkedin.com/in/satyanadella",
"_source": "S1-jsonld+html",
"_scrapedAt": "2026-09-06T16:08:08Z",
"_host": "uk.linkedin.com", // which country host served this render
"_proxyCountry": "GB",
"_masked": false, // true when LinkedIn redacted the work history
"slug": "satyanadella",
"profileUrl": "https://www.linkedin.com/in/satyanadella",
// --- raw schema.org Person node, upstream field names kept verbatim ---
"name": "Satya Nadella",
"jobTitle": ["Chairman and CEO", "Member Board Of Trustees"],
"description": "As chairman and CEO of Microsoft, I define my mission…",
"address": { "@type": "PostalAddress", "addressLocality": "Redmond, Washington, United States" },
"worksFor": [{ "name": "Microsoft", "url": "…/company/microsoft",
"member": { "startDate": "2014-02" } }],
"alumniOf": [{ "name": "Starbucks", "member": { "startDate": 2017, "endDate": 2024 } }],
// --- derived conveniences ---
"followerCount": 12152113,
"experienceEducationCards": [{ "text": "…", "logo": "…" }],
"posts": [ /* schema.org DiscussionForumPosting nodes */ ],
"activityIds": ["7502385664945111040"] // feed into a post-detail run
}

Failure rows carry _error (not_found, blocked, bad_input, unexpected_shape) and _errorDetail, and no payload.

How it works

LinkedIn ships a <script type="application/ld+json"> block with a schema.org Person node on every public profile. That is the primary source — it survives redesigns that break CSS selectors. The HTML pass only adds the rendered Experience/Education cards.

Redacted work history, and why it retries

LinkedIn does not treat every anonymous visitor the same. On some renders the work history comes back as asterisks ("jobTitle": ["********"]); on others, for the same profile, it is complete.

It is worth being precise about what drives that, because the obvious explanations are all wrong. Measured on 2026-09-06, three profiles fetched under three proxy modes:

Proxywilliamhgatessatyanadellareidhoffman
Residentialcompletecompleteredacted
Datacentercompletecompletecomplete
Nonecompleteredactedredacted

The same profiles flipped between redacted and complete across consecutive runs on the same proxy mode. So it is not the profile, not the country subdomain, and not the proxy type — it is decided per request.

That makes retrying the correct and only fix, with one catch: the retries have to be genuinely independent. An earlier build walked nine country subdomains on a single shared session and got a redacted render nine times in a row. Every attempt now gets its own exit IP and its own cookie jar; the country subdomain is varied alongside it only to keep the request coherent (a GB exit IP asking uk.linkedin.com is an ordinary visitor).

Measured effect on a 6-profile run with maxAttempts: 6:

Shared session, 9 hostsIndependent sessions, 6 attempts
Complete1 of 45 of 6 (4 on the first attempt)

If every attempt is redacted the row is still emitted, with _masked: true and _warning: experience_masked_by_linkedin. Name, headline, location and follower count are correct on a redacted render — only parts of the work history are hidden.

Block detection

Two things are deliberately not used to detect a block:

  • Status code alone. LinkedIn serves its guest sign-in wall as a 200 with a full-size body, and answers a throttled request with 999 (its own status code, not an HTTP one).
  • Body substrings. Every LinkedIn page carries the LiX flag data-recaptcha-v3-integration-lix-value, so a substring test for "captcha" marks good renders as blocked. That false positive threw away an entire cloud run's worth of valid data before it was caught.

What is used: the final URL (a redirect to /authwall, /checkpoint/, /uas/login), and a positive data marker — the presence of the Person node. A render without one is the wall, whatever its status code or size.

TLS fingerprinting

LinkedIn's guest surface does not gate on JA3/JA4. The profile ladder chrome131 / chrome146 / firefox144 / safari2601 was run against /in/<slug> from one IP: all four returned an identical 200 with the same JSON-LD payload. The gate here is IP reputation and request rate. chrome146 is the default because it is the most common real UA; rotation is deliberately not implemented because it buys nothing.

Known limits

LimitDetail
Work history redactionDecided per request. maxAttempts: 6 cleared it for 5 of 6 profiles; raise it if you need higher completeness
No pagination of posts/in/<slug>/recent-activity/ redirects back to the profile for anonymous visitors. You get the posts embedded in the profile page, nothing deeper
Rate limiting is aggressiveA single IP is throttled to 999 within a few dozen requests. Use a residential proxy; a bare local run will produce blocked rows almost immediately
Contact detailsEmail and phone are never exposed to anonymous visitors and are not returned
Not coveredcompany/<slug>/people/ and company/<slug>/posts/ redirect to the login wall — employee lists are not obtainable this way
  • LinkedIn Company Profile Scraper — company overviews
  • LinkedIn Jobs Scraper — public job postings via the guest jobs API

Use activityIds from this actor's output as input to a post-detail run.