Skip to content

LinkedIn Profile Scraper

Try for free

Extract public LinkedIn profile details from profile URLs, public identifiers, or profile IDs: name, headline, location, about, follower counts, full experience, and education.

LinkedIn Profile Scraper 👤

Public LinkedIn profiles, in bulk, without a browser or an account.

Built for recruiting, sales research, and CRM refresh jobs that already have profile URLs or public identifiers and need the fields a logged-out visitor can see.

✨ Features

  • 🔗 Accepts profile URLs, public identifiers, and LinkedIn profile IDs (queries, urls, publicIdentifiers, profileIds)
  • ⚡ HTTP only. No browser, no cookies, and no LinkedIn account
  • 🪪 Returns the public name, headline, about text, location line, and profile photo when the page includes them
  • 👥 Returns follower and connection counts when the page prints an exact figure, including K and M abbreviations
  • 💼 Returns experience: title, company, company URL, company slug, start and end dates, duration, location, and the role description when the page shows them
  • 🏢 Returns each current company from roles that are still marked Present
  • 🎓 Returns education: school, school URL, degree, field of study, and years when the page shows them
  • ⭐ Returns the influencer flag when the page shows that badge
  • 👥 Returns the similar profiles linked from the page (name, subtitle, public identifier, URL)
  • 🔁 Retries a profile on a new residential session, in another country, until the public profile page is stored
  • 🏠 On Scrapely, requests go out through the residential proxy group. No browser and no account

🚀 Why teams use this

You already have a list of people. This actor turns that list into structured public profiles fast enough to run on a schedule.

LinkedIn sometimes answers the same public URL with an authwall from one edge and the profile page from another. Each try uses a new residential session, and the next try uses another country, until the public profile page is what comes back. There is no browser and no account in the loop.

The run fails if any requested profile is missing. An authwall is not a stored profile. Invalid URLs are not profiles either.

The public page does not include an email address, and this actor does not add one. Older inputs that still send profileScraperMode keep working; the field is ignored.

💡 Use cases

  • Enrich a lead or candidate list with current title, company, and location.
  • Research decision makers before outreach.
  • Keep CRM contact records up to date with public profile data.

🧪 Example input

{
  "queries": [
    "https://www.linkedin.com/in/williamhgates"
  ]
}

🧾 Sample output

One item from a real run of the example input, shortened. Long text is cut and lists show their first entries.

{
  "publicIdentifier": "williamhgates",
  "linkedinUrl": "https://www.linkedin.com/in/williamhgates",
  "firstName": "Bill",
  "lastName": "Gates",
  "headline": "Chair, Gates Foundation and Founder, Breakthrough Energy",
  "about": "Chair of the Gates Foundation. Founder of Breakthrough Energy. Co-founder of Microsoft. Voracious reader. Avid traveler. Active blogger.",
  "photo": "https://media.licdn.com/…",
  "influencer": true,
  "location": {
    "linkedinText": "Seattle, Washington, United States"
  },
  "connectionsCount": 8,
  "followerCount": 41000000,
  "currentPosition": [
    {
      "companyName": "Gates Foundation"
    },
    {
      "companyName": "Breakthrough Energy"
    }
  ],
  "experience": [
    {
      "position": "Co-chair",
      "companyName": "Gates Foundation",
      "companyLinkedinUrl": "https://www.linkedin.com/company/gates-foundation",
      "companyUniversalName": "gates-foundation",
      "duration": "26 years",
      "startDate": {
        "year": "…",
        "text": "…"
      },
      "endDate": {
        "text": "…"
      }
    },
    {
      "position": "Founder",
      "companyName": "Breakthrough Energy",
      "companyLinkedinUrl": "https://www.linkedin.com/company/breakthrough-energy",
      "companyUniversalName": "breakthrough-energy",
      "duration": "11 years",
      "startDate": {
        "year": "…",
        "text": "…"
      },
      "endDate": {
        "text": "…"
      }
    }
  ],
  "education": [
    {
      "schoolName": "Harvard University",
      "schoolLinkedinUrl": "https://www.linkedin.com/school/harvard-university",
      "startDate": {
        "year": "…",
        "text": "…"
      },
      "endDate": {
        "year": "…",
        "text": "…"
      },
      "period": "1973 - 1975"
    },
    {
      "schoolName": "Lakeside School",
      "schoolLinkedinUrl": "https://www.linkedin.com/school/lakeside-school"
    }
  ],
  "moreProfiles": [
    {
      "firstName": "Melinda",
      "lastName": "French Gates",
      "position": "Pivotal",
      "publicIdentifier": "melindagates",
      "linkedinUrl": "https://www.linkedin.com/in/melindagates"
    },
    {
      "firstName": "Tyler",
      "lastName": "Alterman",
      "position": "Fractal University",
      "publicIdentifier": "tyleralterman",
      "linkedinUrl": "https://www.linkedin.com/in/tyleralterman"
    }
  ],
  "query": {
    "publicIdentifier": "williamhgates"
  },
  "status": 200,
  "inputUrl": "https://www.linkedin.com/in/williamhgates"
}

📥 Input

FieldWhat to send
urlsProfile URLs only
queriesProfile URLs or public identifiers, mixed in one list
publicIdentifiersThe slug at the end of the profile URL, such as williamhgates
profileIdsLinkedIn profile IDs such as ACoAAA8BYqEBCGLg_vT_ca6mMEqkpp9nVffJ3hc

Send at least one of urls, queries, publicIdentifiers, or profileIds.

{
  "queries": ["https://www.linkedin.com/in/williamhgates"]
}

📤 Output

One dataset item per target. Empty values are left off. A real false or 0 would stay; this page usually does not send those.

Present when the public page has them:

  • publicIdentifier, linkedinUrl, firstName, lastName, headline, about, photo
  • influencer when the page shows the influencer badge
  • location.linkedinText
  • followerCount, connectionsCount (a capped value such as 500+ is omitted)
  • currentPosition[].companyName
  • experience[]: position, companyName, companyLinkedinUrl, companyUniversalName, location, duration, description, startDate, endDate
  • education[]: schoolName, schoolLinkedinUrl, degree, fieldOfStudy, startDate, endDate, period
  • moreProfiles[]: firstName, lastName, position, publicIdentifier, linkedinUrl
  • query, status, inputUrl
  • id and entityId only when the input itself was a profile ID

firstName and lastName are the public display name split on the first space. The page does not send them as separate fields.

Not on the public page, so not in the item: email, member id, registration date, Open to Work, hiring, premium, verified, skills, certifications, projects, volunteering, recommendations, courses, publications, patents, honors, languages, employment type, and workplace type. A profile ID is requested on the same public URL path as a slug. Nothing is invented when the page does not include a field.

If LinkedIn answers with the signup page from every edge, that profile is not written. An authwall is not a dataset row, and the profile is not invented. When every requested target ends that way, the run exits with code 1 and the dataset stays empty.

A failed target looks like this:

{
  "inputUrl": "https://example.com/not-a-profile",
  "error": "invalid_profile",
  "errorDescription": "invalid_profile"
}

errorDescription is a status and code, or an exception type name.

Related actors

G2
4.7/5
Excellent
Trustpilot

The internet is full of data.
Start owning yours.

Scrape.ly gives you the infrastructure, the tooling, and the team to extract, process, and operationalize web data at any scale. Setup takes minutes. The advantage lasts forever.

No credit card. No setup calls.