LinkedIn Public Profile Scraper (No Login) avatar

LinkedIn Public Profile Scraper (No Login)

Under maintenance

Pricing

from $1.25 / 1,000 results

Go to Apify Store
LinkedIn Public Profile Scraper (No Login)

LinkedIn Public Profile Scraper (No Login)

Under maintenance

Scrape public LinkedIn profiles by slug or /in/ URL, with no login and no cookies. Each row carries the full name, headline, About text, dated work history and education with start and end years, location, current company, languages, profile photo and an exact follower count.

Pricing

from $1.25 / 1,000 results

Rating

0.0

(0)

Developer

String

String

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

1

Monthly active users

14 days ago

Last modified

Share

This Actor collects public LinkedIn profiles. You give it profile slugs or /in/ URLs and it returns one row per person: the headline, the About text, work history and education with the years attached, location, languages and an exact follower count. No LinkedIn account, cookie or session token is used at any point.

What does the LinkedIn Profile Scraper do?

LinkedIn publishes each public profile as schema.org JSON-LD inside the page, and this Actor reads that structured data rather than handing rendered markup to a model. The difference shows up in three places a buyer cares about.

Work history comes back dated. positions and education are arrays, each entry carrying the organisation, its LinkedIn URL and startYear and endYear, so tenure is a subtraction rather than a parse of "3 yrs 4 mos". Values are stable: the same profile read twice gives the same strings, where the model-driven extraction this replaced returned a job title as "Chair" on one run and "Co-chair" on the next. And counts are exact, so followerCount arrives as 40560540 rather than "40M".

The profile page's JSON-LD graph also holds the person's articles and posts, each with a stub author node. The Actor picks the Person node that actually carries profile fields instead of the first one it finds, so a prolific poster does not come back as an empty row.

What data does it extract?

FieldTypeDescription
handlestringThe profile slug, e.g. "janedoe". Your join key
fullNamestringName as shown on the profile
headlinestringThe short line under the name
aboutstringThe About section text
jobTitlesstring[]Every title the profile lists, e.g. ["Founder", "Board Member"]
locationstringCity or region as stated on the profile
countrystringCountry from the same address block
currentCompanystringThe first employer in positions, so the most recent one
positionsobject[]Work history: { company, url, startYear, endYear } per role
educationobject[]Schools: { school, url, startYear, endYear } per entry
followerCountnumberExact follower count, not rounded
languagesstring[]Languages listed on the profile
imageUrlstringProfile photo URL
sourceUrlstringThe canonical profile URL that was read
collectedAtstringISO 8601 timestamp of the run

An entry still in progress has endYear of null. Any field the profile does not publish is null or an empty array, never a guess.

There are no email addresses and no phone numbers in this list, and the Actor does not look them up anywhere else. What you get is what the public profile shows.

Why scrape LinkedIn profiles?

Most of the value here is tenure. A job title on its own says very little; a title with a start year next to it tells you whether someone just took the seat or has been in it for six years, and that is usually what decides whether an outreach lands. Sales teams use it to enrich CRM records, recruiters use it to sort candidates by time in role without opening a single profile.

Other things people run it for:

  • Executive move tracking. Re-run a watchlist weekly and diff currentCompany against the top entry of positions.
  • Org mapping before an account plan, from a list of slugs the team already has.
  • Alumni and cohort lists, grouping people whose education years overlapped at the same school.

How to use it

  1. Open the Actor on Apify Store and click Try for free.
  2. Paste your profiles into the Profiles field, one per line. Slugs (janedoe) and full URLs (https://www.linkedin.com/in/janedoe) both work, and the two forms for the same person collapse to a single fetch.
  3. Click Start. Profiles are fetched in parallel, five at a time by default.
  4. Export from the Dataset tab as JSON, CSV or Excel, or read it through the API. Slugs that did not resolve are listed in the SUMMARY record in the key-value store.

The Actor takes profiles you already have. It does not search LinkedIn, so pair it with a list you built elsewhere: from a CRM export, a conference attendee list, or the companies in a funding announcement.

Input

FieldTypeDefaultDescription
profilesstring[]requiredPublic profile slugs or /in/ URLs, 1 to 500 per run
maxItemsinteger1000Cap on dataset rows, 1 to 50000. Free plans stop earlier, see below
concurrencyinteger5Profiles fetched in parallel, 1 to 10
{
"profiles": ["janedoe", "https://www.linkedin.com/in/john-smith-7a3b21"],
"concurrency": 5
}

Only linkedin.com URLs are accepted. Anything else is rejected before it is fetched and reported as a failed target, so a stray URL in a list of five hundred cannot route traffic somewhere else under this Actor's pricing.

Output

One row per profile. Illustrative values for a fictional person, not a captured run.

{
"handle": "janedoe",
"fullName": "Jane Doe",
"headline": "VP Engineering at Meridian Logistics",
"about": "I build platform teams and the tooling that keeps them shipping...",
"jobTitles": ["VP Engineering", "Engineering Manager"],
"location": "Amsterdam",
"country": "NL",
"currentCompany": "Meridian Logistics",
"followerCount": 4821,
"positions": [
{ "company": "Meridian Logistics", "url": "https://nl.linkedin.com/company/meridian-logistics", "startYear": 2022, "endYear": null },
{ "company": "Bellweather Systems", "url": "https://www.linkedin.com/company/bellweather-systems", "startYear": 2017, "endYear": 2022 }
],
"education": [
{ "school": "Delft University of Technology", "url": "https://nl.linkedin.com/school/tudelft", "startYear": 2010, "endYear": 2014 }
],
"languages": ["Dutch", "English"],
"imageUrl": "https://media.licdn.com/dms/image/v2/example/profile-displayphoto.jpg",
"sourceUrl": "https://www.linkedin.com/in/janedoe",
"collectedAt": "2026-08-20T09:31:02.118Z"
}

Reliability

Measured across 30 profile slugs in one run: every profile that exists was collected, 19 of 19. The other 11 were slugs that do not resolve on LinkedIn, and they were reported as failures rather than emitted as empty rows.

Because fields come from the profile's own structured data, a value is either present and correct or absent. It does not drift between runs for the same profile.

A profile that cannot be read lands in the run's SUMMARY under failures with the URL and the error, and the rest of the batch still returns. A run where every profile failed exits with an error, so a schedule notices instead of silently recording an empty day.

Limitations

Public profile fields only. No connections, no posts or activity feed, no skills or endorsements, no recommendations, and no search or discovery. Profiles set to private publish no JSON-LD, so they return nothing and are reported as failures.

positions and education carry years, not months, because years are what the public profile's structured data holds. Up to 500 profiles per run, one row each.

How much does it cost?

Pay per event: you are charged per result row written to the dataset, plus Apify's own platform usage for the run. The current per-result price is on this Actor's Store page under Pricing.

A slug that does not resolve writes no row and costs nothing, and duplicate entries for the same person are fetched and billed once.

Runs started from an Apify free plan stop at 250 requests and 250 results, and say so in the run's status message. Any paid plan runs the full input and whatever maxItems you set. The limit exists because this Actor fetches through our own anti-bot infrastructure, which Apify does not cover for free-plan runs. It binds on requests as well as rows so that a long input list cannot spend those fetches on rows the run will never return.

Using it with the Apify API

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('usestring/linkedin-profiles').call({
profiles: ['janedoe', 'https://www.linkedin.com/in/john-smith-7a3b21']
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
const thisYear = new Date().getFullYear();
for (const person of items) {
const current = person.positions.find((role) => role.endYear === null);
const years = current?.startYear ? thisYear - current.startYear : null;
console.log(person.fullName, person.currentCompany, years === null ? '' : `${years} yrs in role`);
}

The Python client and the REST API take the same input. The run's SUMMARY record, with the item count and every slug that failed, is in the default key-value store.

This Actor reads public LinkedIn profiles as a logged-out visitor. It sends no account credentials, no session cookie and no li_at token, and it reads nothing that a signed-in member can see but a signed-out one cannot. It does not create accounts, send connection requests or interact with the platform in any way.

It returns no contact details. Email addresses and phone numbers are not on the public profile, and the Actor does not enrich, guess or look them up from another source.

What it does return is still personal data. Names, employers and education relate to identifiable people, so GDPR, the CCPA and their equivalents apply to what you do with the rows once you have them: you need your own lawful basis for holding and using them, and a person may have the right to ask you to delete their record. Whether the collection itself is permitted is a separate question from whether your intended use is, and the second one is the one that usually bites.

Please treat this section as orientation rather than legal advice. If people data is core to what you are building, get your own.

A common pairing is this Actor with one of the job scrapers: the job board tells you a company is hiring, and the profiles tell you who already runs the team.

FAQ

Do I need a LinkedIn account, cookies or a session token? No. Only the public, logged-out profile page is read, and no credentials of any kind are supplied.

Does it return email addresses or phone numbers? No. Those are not on the public profile, and this Actor does no contact enrichment of any kind. If you need contact data, that is a different tool and a different legal analysis.

Does the work history include dates? Yes. Each entry in positions has startYear and endYear, with endYear null for a current role, and education follows the same shape. Years, not months.

Is the follower count exact? Yes. It comes from the profile's structured data as an integer, so you get 4821 rather than "4.8K".

Can I search LinkedIn for people to scrape? No. You supply the profiles. There is no keyword search, no filter by company or title, and no discovery step in this Actor.

What happens with a private profile or a slug that does not exist? It is recorded under failures in the run's SUMMARY and the rest of the batch still returns. A private profile publishes no structured data, so there is nothing to read and nothing is invented in its place.

Feedback

If a profile came back with a field you expected to see filled, open an issue from this Actor's Store page and include the slug. Requests for fields that are on the public profile but not in the table above are worth sending too.