# LinkedIn Profile Scraper: Public Profiles by URL, No Login (`agnes.developer.queen/linkedin-profile-scraper`) Actor

LinkedIn profile scraper with no login or cookies. Paste profile URLs and get name, headline, location, current and past companies, education and followers. $3 per 1,000 profiles, private ones free.

- **URL**: https://apify.com/agnes.developer.queen/linkedin-profile-scraper.md
- **Developed by:** [Agnes Maina](https://apify.com/agnes.developer.queen) (community)
- **Categories:** Lead generation, Social media
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 profiles

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## LinkedIn Profile Scraper: public profiles by URL, no login, no cookies

[![Run on Apify](https://apify.com/actor-badge?actor=agnes.developer.queen/linkedin-profile-scraper)](https://apify.com/agnes.developer.queen/linkedin-profile-scraper)

This LinkedIn profile scraper takes a list of profile URLs or public identifiers and returns what each public profile shows a logged out visitor: name, headline, location, current and past companies, education, followers and more. It never logs in and requires no account cookies. You pay $0.003 per readable profile, which is $3 per 1,000. Private, missing and failed profiles are free.

Limits: up to 1,000 profile URLs per run, and a residential proxy is required. It does not return emails, phone numbers, connections or anything behind the login wall, and it is not a full work history tool.

Measured on Apify on October 7, 2026, with 50 profile URLs that were already known to be public: 49 of 50 came back readable and were charged, and the one network failure was free. Network errors now get one retry, like blocked requests. On the 49 profiles: name, location and photo 49, followers 46, headline and current company 40, past companies 34, education 28, about 22, languages 18. LinkedIn shows full job titles and dates to logged out visitors on only a few profiles (2 of 49 here). These are measured results, not a promise of coverage.

### What you get

One row per unique profile, plus a free reason row for each invalid input item. Equivalent URLs are deduplicated. Missing source values are `null`.

| Field | What it holds |
| --- | --- |
| `input` | First supplied value for the profile, or the rejected item |
| `profileUrl`, `publicIdentifier` | Normalized profile URL and public identifier |
| `status` | `ok`, `not_public`, `not_found`, `invalid_input` or `failed` |
| `fullName`, `firstName`, `lastName` | Public name; first and last names use published components where available, otherwise a split of the full name |
| `headline` | Published page headline, with listed role titles as fallback |
| `location` | Published profile location |
| `about` | Public About text, with the source description as fallback |
| `profilePictureUrl` | Public profile picture URL |
| `currentCompany`, `currentCompanyLinkedinUrl` | First current employer listed in the source and its LinkedIn company URL |
| `experience` | LinkedIn shows logged out visitors full job titles and dates on only some profiles, while past companies come from the page's structured data. |
| `pastCompanies` | Past employers in page order with `company`, `linkedinUrl`, `startDate`, `endDate` and plain text `description` capped at 500 characters; dates retain their source values |
| `followers` | Integer follower count from the page's structured data |
| `education` | Entries with `schoolName`, `degree`, `dates` and `url` |
| `skills` | Skills listed in the public view, when available |
| `languages` | Language names from the page's structured data |
| `awards` | Award names from the page's structured data |
| `organizations` | Membership organization names from the page's structured data |
| `websites` | Website URLs from the page's structured data, excluding LinkedIn URLs |
| `charged`, `reason` | Whether the row uses a paid event and an explanation for free rows |
| `scrapedAt` | Collection timestamp in UTC |

A readable profile can have missing sections. Private fields, connections, private contact details and content behind login are not collected. `RUN_SUMMARY` and `DIAGNOSTICS` report outcomes, request counts, response bytes, retries and the stop reason outside the profile dataset.

### Try it in 30 seconds

1. Open this actor's Input tab in Apify Console.
2. Paste public LinkedIn profile URLs or identifiers.
3. Leave the residential proxy default selected and click Start.
4. Download the dataset as JSON, CSV or Excel.

```json
{
  "profileUrls": [
    "https://www.linkedin.com/in/williamhgates",
    "satyanadella"
  ],
  "maxConcurrency": 5
}
```

### Example output

Selected fields from the Bill Gates fixture captured on October 7, 2026. This example shows a paid profile row. A delivered row includes all standard fields, including missing values.

```json
{
  "input": "williamhgates",
  "profileUrl": "https://www.linkedin.com/in/williamhgates",
  "publicIdentifier": "williamhgates",
  "status": "ok",
  "fullName": "Bill Gates",
  "firstName": "Bill",
  "lastName": "Gates",
  "headline": "Chair, Gates Foundation and Founder, Breakthrough Energy",
  "location": "Seattle, Washington, United States",
  "currentCompany": "Gates Foundation",
  "currentCompanyLinkedinUrl": "https://www.linkedin.com/company/gates-foundation",
  "education": [
    {
      "schoolName": "Harvard University",
      "degree": null,
      "dates": "1973 - 1975",
      "url": "https://www.linkedin.com/school/harvard-university/"
    },
    {
      "schoolName": "Lakeside School",
      "degree": null,
      "dates": null,
      "url": "https://www.linkedin.com/school/lakeside-school/"
    }
  ],
  "charged": true,
  "reason": null
}
```

### Pricing

| Event | When it applies | Price |
| --- | --- | --- |
| `profile` | Each delivered row with status `ok` | $0.003 |
| `apify-actor-start` | Platform start event, one per GB of run memory, minimum one | $0.00005 |

1,000 readable profiles cost 1,000 x $0.003 = $3.00, plus $0.00005 for the run start at the default 512 MB of memory. Every Apify account gets $5 of free platform credit each month, about 1,660 profiles at this price. Profile rows with status `not_public`, `not_found`, `invalid_input` or `failed` are free and have `charged: false`. Duplicate profiles are neither delivered nor charged twice within a run.

The actor checks the remaining spending limit before every dataset write. If the next row is unaffordable, it stops with reason `budget`. A dataset write precedes its charge. An uncertain write or charge stops the run for review; it is never retried automatically by the actor. On an uncertain charge, the last row's `charged` flag describes the intended charge and must be reconciled with the run's event log.

### Input

| Field | Type | Default | What it does |
| --- | --- | --- | --- |
| `profileUrls` | array of strings | required | From 1 to 1,000 URLs or public identifiers. Country hosts, trailing slash, query and fragment are accepted. |
| `maxConcurrency` | integer | 5 | From 1 to 20 simultaneous profile fetches. |
| `proxyConfiguration` | object | Apify RESIDENTIAL, US | Residential proxy is required. Direct, custom and datacenter proxies are refused. |

URLs normalize to `https://www.linkedin.com/in/<identifier>` without a trailing slash. Bare identifiers cannot contain dots. Member identifiers beginning with `ACo` retain their case. An invalid item produces a free reason row while the remaining inputs continue. Input array limits and invalid run settings fail validation before collection begins.

### Use cases

- Lead list hygiene: check where each contact works now, and what their headline says, before a campaign goes out.
- Recruiting: refresh public professional information for a list of candidates.
- CRM maintenance: update public company and role information for known profile URLs.
- Research: compare published career histories and education.
- Data cleanup: normalize profile URLs and identify profiles unavailable to public visitors.

### Integrations

Actor: `agnes.developer.queen/linkedin-profile-scraper`.

API:

```bash
curl -X POST "https://api.apify.com/v2/acts/agnes.developer.queen~linkedin-profile-scraper/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"profileUrls":["williamhgates"]}'
```

Python:

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("agnes.developer.queen/linkedin-profile-scraper").call(
    run_input={"profileUrls": ["williamhgates"]}
)
for profile in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(profile["fullName"], profile["status"])
```

Node.js:

```js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('agnes.developer.queen/linkedin-profile-scraper').call({
    profileUrls: ['williamhgates'],
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

In n8n, use the Apify integration or an HTTP Request node with the API example. In Make, run the actor through the Apify app and fetch its dataset items. In Zapier, trigger the next step when an Apify run succeeds. Map the stable fields to a spreadsheet, ATS or CRM.

AI assistants and MCP clients can call the Actor as a tool through the Apify MCP server:

https://mcp.apify.com/?tools=agnes.developer.queen/linkedin-profile-scraper

### FAQ

#### How much does it cost to scrape 1,000 LinkedIn profiles?

$3.00 for 1,000 readable profiles, plus $0.00005 per run at the default memory. Private, missing, invalid and failed profiles are free.

#### Does it require a LinkedIn login?

No. The actor never logs in and does not accept account cookies. It reads public profiles only.

#### Will every URL return a profile?

No. A login wall or a blocked response can produce `not_public`. A missing page produces `not_found`. Transport and unexpected response failures produce `failed`. Each is free and includes a reason.

#### Why are experience, skills or education missing?

The public page may omit those sections. The actor returns only visible source information and leaves unavailable values null. It does not infer a full career history.

#### Does it return emails or phone numbers?

No. It returns the public profile only. Contact details are not collected, and the `email`, `emailStatus` and `emailPattern` columns stay null.

#### Why did the run stop early?

The spending limit or run deadline can stop collection. The actor reserves 30 seconds before the deadline to finish and save records. An uncertain dataset write or charge also stops delivery. See `RUN_SUMMARY` and `DIAGNOSTICS`. A restarted run skips completed deliveries and continues with the remaining inputs. An unresolved pending delivery stops the run for review before collection resumes. Summary outcome counts describe the current process.

#### Is this legal to use?

The actor collects public profiles only, accesses no private data and never logs in. Follow LinkedIn's terms and the privacy law that applies to your use. Public availability does not remove your obligations when collecting, storing or using personal information.

### Related actors

- [LinkedIn People Search Scraper](https://apify.com/agnes.developer.queen/linkedin-people-search-scraper) finds public profiles by job title, company and location.
- [LinkedIn Company Scraper](https://apify.com/agnes.developer.queen/linkedin-company-scraper) returns company facts from a URL, slug or name.
- [LinkedIn New Hires Finder](https://apify.com/agnes.developer.queen/linkedin-new-hires-finder) lists decision makers who joined a company recently.

### Support

Include your input, run ID, `RUN_SUMMARY` and `DIAGNOSTICS` when reporting a problem through the actor's Issues tab. Do not include API tokens or proxy credentials.

# Actor input Schema

## `profileUrls` (type: `array`):

Public profile URLs on LinkedIn country hosts, or bare public identifiers. Duplicates are removed. Invalid entries return a free reason row.

## `maxConcurrency` (type: `integer`):

Maximum simultaneous profile fetches.

## `findEmail` (type: `boolean`):

Resolve the current company domain and check a work email. Only verified addresses incur the profile-email event.

## `proxyConfiguration` (type: `object`):

Apify RESIDENTIAL is required. Direct, custom and datacenter proxies are refused.

## Actor input object example

```json
{
  "profileUrls": [
    "williamhgates"
  ],
  "maxConcurrency": 5,
  "findEmail": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

## `summary` (type: `string`):

No description

## `diagnostics` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "profileUrls": [
        "williamhgates"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("agnes.developer.queen/linkedin-profile-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "profileUrls": ["williamhgates"] }

# Run the Actor and wait for it to finish
run = client.actor("agnes.developer.queen/linkedin-profile-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "profileUrls": [
    "williamhgates"
  ]
}' |
apify call agnes.developer.queen/linkedin-profile-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,agnes.developer.queen/linkedin-profile-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/ZULHnAPmjl95HRtmf/builds/nLBqa5c89m1s4OEZU/openapi.json
