# LinkedIn Profile Data & LinkedIn Profile Finder, No Cookies (`afanasenko/linkedin-profile-api-scraper`) Actor

Scrape LinkedIn profile data in bulk — no login, no cookies. Profiles, companies and verified emails where available: search decision-makers by company and job title, or paste profile and company URLs. Returns name, headline, contact data, experience, education and 70+ fields. CSV, JSON or Excel.

- **URL**: https://apify.com/afanasenko/linkedin-profile-api-scraper.md
- **Developed by:** [Andrey Afanasenko](https://apify.com/afanasenko) (community)
- **Categories:** Lead generation, Social media, Jobs
- **Features:** Limited permissions
- **Stats:** 142 total users, 34 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $30.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 Data & LinkedIn Profile Finder, No Cookies

[![Apify Actor](https://apify.com/actor-badge?actor=afanasenko/linkedin-profile-api-scraper)](https://apify.com/afanasenko/linkedin-profile-api-scraper)

> **Build and enrich LinkedIn lead lists without login or cookies — search for decision-makers by company & job title, or paste profile/company URLs in bulk. Get name, headline, experience, education, followers, company size, industry and 70+ fields per record.**

### 🎯 What it does

You feed the actor LinkedIn URLs (profiles or companies) OR a search criteria (keyword + optional industry, or "decision-makers at this company") — it returns clean, structured rows ready for a CRM, sheet, or downstream agent.

| Mode | Input | What it returns |
|---|---|---|
| **1: Lookup Profile by URL** (`lookupByUrl`) | LinkedIn profile URLs | 1 row per URL, 46 fields, plus a work email when `findEmails` is on. Cost cap: `maxItemsMode1`. |
| **2: Lookup Company by URL/Domain** (`companyLookup`) | Company URLs or raw domains | 1 row per input, 26 fields. Cost cap: `maxItemsMode2`. |
| **3: Search Leads** (`searchLead`) | Company URLs + optional job title | Slim profile rows for decision-makers matching the title. Cost caps: `maxItemsMode3` (total) + `searchLeadCount` (per-company). |
| **4: Search Companies** (`searchCompany`) | Keyword + optional industries | Full company rows (the same 26 fields as Mode 2). Cost cap: `maxItemsMode4`. |

- **46 fields per profile** — `full_name`, `headline`, `about`, current `job_title` + `company`, full `experiences[]` / `educations[]`, `follower_count`, verification flags, parsed location, current-employer enrichment (industry, employee count, year founded), `languages`, and a work `email` (verified) or `emailGuess` (unverified) with its `email_status` when you turn on `findEmails`.
- **26 fields per company** — `company_name`, `description`, `tagline`, `industries[]`, `specialties[]`, `employee_count`, `employee_range`, `year_founded`, `website`, `logo_url`, `follower_count`, full HQ address, `locations[]`, `affiliated_companies[]`.
- **6 advanced filters** — follower range, must-have email, open-to-work, country, industry — applied across all modes.

**Work emails:** turn on `findEmails` (Mode 1) and the actor looks for each person's work email address. An address is found for about half of profiles, and `email_status` says how sure it is. A **verified** address (`valid` — the mailbox accepts mail) goes in `email`. An **unverified** one (`risky` — the company's mail server accepts any address, so delivery is not guaranteed) goes in `emailGuess` instead, and `email` stays `N/A`. It is slower — up to a minute per profile. From 6 November 2026 each profile delivered with a verified email in `email` costs an extra $0.03 ("Email found"); an `emailGuess` is free, and a profile without an address costs the profile price only. `mustHaveEmail` turns the search on and keeps only profiles with an address in either column; fetched profiles are billed even if your filters exclude them. Phone numbers are not available.

### 📦 What you get — output sample

```json
{
  "entity_type": "profile",
  "input": "https://www.linkedin.com/in/satyanadella/",
  "linkedin_url": "https://www.linkedin.com/in/satyanadella",
  "full_name": "Satya Nadella",
  "first_name": "Satya",
  "last_name": "Nadella",
  "headline": "Chairman and CEO at Microsoft",
  "job_title": "Chairman and CEO",
  "company": "Microsoft",
  "company_industry": "Software Development",
  "company_employee_count": 228000,
  "follower_count": 11489320,
  "city": "Redmond",
  "country": "United States",
  "is_premium": true,
  "is_verified": true,
  "experiences": [ { "title": "CEO", "company": "Microsoft", "starts_at": "2014-02-01" } ],
  "educations": [ { "school": "University of Chicago", "degree": "MBA" } ],
  "profile_image_url": "https://media.licdn.com/dms/image/.../satya-nadella.jpg"
}
```

```json
{
  "entity_type": "company",
  "input": "microsoft.com",
  "linkedin_url": "https://www.linkedin.com/company/microsoft",
  "company_name": "Microsoft",
  "tagline": "Empowering every person and organization on the planet to achieve more.",
  "industries": ["Software Development"],
  "specialties": ["Software", "Cloud", "AI", "Productivity"],
  "employee_count": 228000,
  "employee_range": "10,001+",
  "year_founded": 1975,
  "follower_count": 25190000,
  "domain": "microsoft.com",
  "website": "https://news.microsoft.com",
  "logo_url": "https://media.licdn.com/dms/image/.../microsoft-logo.png",
  "hq_city": "Redmond",
  "hq_country": "US"
}
```

Missing optional fields come back as the string `"N/A"` — every always-emitted column appears in every row, so downstream tools (Sheets / Airtable / CSV) don't have to special-case missing values. See [.actor/dataset_schema.json](.actor/dataset_schema.json) for the full per-column declaration.

### ⚡ Quick start

Minimal input that works on the free plan:

```json
{
  "operationMode": "lookupByUrl",
  "profileUrls": ["https://www.linkedin.com/in/satyanadella/"]
}
```

Run, open **Storage → Dataset**, see one enriched row. Add more URLs to scale up.

### 🎯 Example tasks

Ready-to-run examples — each opens a pre-configured task you can run in one click (no setup):

- **[Scrape LinkedIn profiles by URL](https://apify.com/afanasenko/linkedin-profile-api-scraper/examples/scrape-linkedin-profiles-by-url)** — Paste LinkedIn profile URLs and export full data — name, headline, location, company, follower count and work email.
- **[Scrape LinkedIn company data](https://apify.com/afanasenko/linkedin-profile-api-scraper/examples/scrape-linkedin-company-data)** — Enter LinkedIn company URLs and export firmographics — industry, employee count, followers, logo, domain and headquarters.
- **[Find LinkedIn leads by company & job title](https://apify.com/afanasenko/linkedin-profile-api-scraper/examples/find-linkedin-leads-by-company)** — Find decision-makers at any company on LinkedIn by job title — export names, headlines, profile links and contact details.

### 🛠 Input

| Section | Fields |
|---|---|
| Mode picker | `operationMode` (required) |
| Mode 1 | `profileUrls`, `findEmails`, `maxItemsMode1` |
| Mode 2 | `companyInputs`, `maxItemsMode2` |
| Mode 3 | `searchLeadCompanyUrls`, `searchLeadJobTitle`, `searchLeadCount`, `maxItemsMode3` |
| Mode 4 | `searchCompanyKeywords`, `searchCompanyIndustries`, `searchCompanyCount`, `maxItemsMode4` |
| Advanced filtering | `minFollowers`, `maxFollowers`, `mustHaveEmail`, `openToWorkOnly`, `countryFilter`, `industryFilter` |

See [.actor/input_schema.json](.actor/input_schema.json) for the authoritative declaration.

### 💰 Pricing

Pay-per-event. You're charged once per fetched record, regardless of mode.

| Event | Price | Trigger |
|---|---|---|
| **Profile Analyzed** | **$0.030** | Each profile or company successfully retrieved and processed by the actor |
| **Email found** (from 6 November 2026) | **$0.030** | Each profile delivered with a **verified** work email in `email` (`email_status` = `valid`), only when `findEmails` or `mustHaveEmail` is on. An unverified address in `emailGuess` is never charged |

**Examples:**

- 100 profiles in Mode 1 → 100 × $0.030 = **$3.00**
- 100 profiles in Mode 1 with `findEmails` on, 20 of them with a verified email (from 6 November 2026) → $3.00 + 20 × $0.030 = **$3.60**; unverified guesses add nothing
- 5 companies in Mode 2 → 5 × $0.030 = **$0.15**
- Mode 3 with 4 target companies × 25 leads each = 100 leads → **$3.00**
- Mode 4 returning 25 company matches → 25 × $0.030 = **$0.75**

**Filters and billing:** Filters narrow your **output**, not your **bill**. The paid event fires when the row is fetched — even if your filter then drops it. Use cost-control caps (`maxItemsModeN`) to bound spend; use filters to narrow signal.

### 🆓 Free vs paid plan

| | Free | Paid |
|---|---|---|
| Items per run | 50 max | unlimited (capped only by your cost-control field) |
| Profiles per month | 100 (resets on the 1st) | unlimited |
| Trial run cap | 10 (auto, when input matches the example) | n/a |
| All 4 modes | ✅ | ✅ |
| Advanced filters | ✅ | ✅ |
| Live status page | ✅ | ✅ |

### 🧪 Filter recipes

Drop these straight into the input editor.

**Find SaaS founders in the US (Mode 4 → Mode 3 → Mode 1):**

Step 1 — find SaaS companies:

```json
{
  "operationMode": "searchCompany",
  "searchCompanyKeywords": "saas",
  "searchCompanyIndustries": ["software"],
  "countryFilter": "United States",
  "searchCompanyCount": 50
}
```

Step 2 — find founders at those companies (paste company URLs from Step 1):

```json
{
  "operationMode": "searchLead",
  "searchLeadCompanyUrls": ["...", "...", "..."],
  "searchLeadJobTitle": "founder",
  "searchLeadCount": 25
}
```

**Engineering managers at top tech companies (Mode 3 with a follower filter):**

```json
{
  "operationMode": "searchLead",
  "searchLeadCompanyUrls": [
    "https://www.linkedin.com/company/microsoft/",
    "https://www.linkedin.com/company/google/",
    "https://www.linkedin.com/company/anthropic/"
  ],
  "searchLeadJobTitle": "engineering manager",
  "minFollowers": 500,
  "searchLeadCount": 50
}
```

**Bulk enrich your CRM list (Mode 1 with relevance filter):**

```json
{
  "operationMode": "lookupByUrl",
  "profileUrls": ["...100 URLs..."],
  "minFollowers": 1000,
  "industryFilter": "software"
}
```

### 📡 Live status & storage records

Every run writes structured JSON records to its key-value store, AND serves a live status page over HTTP while running.

| Key | Format | Content |
|---|---|---|
| `RUN_SUMMARY` | JSON | End-of-run aggregate: stop reason, mode, processedCount, paidEventsFired, itemsScraped/Filtered, demoCapped, wallClockSec |
| `USER_MESSAGE` | JSON | First-paid-run welcome / 3rd-run check-in (paid plan) |
| `FREE_LIMITS_APPLIED` | JSON | Which free-plan caps fired (e.g. `freeLimitPropertyCount`) |
| `SKIPPED_ITEMS` | JSON | Inputs we couldn't process + reason |
| `status.html` | HTML | Live progress page (auto-refreshes every 3s) |

While the run is active, the live page is reachable at the actor's container URL (Apify shows it under "Live view"). For programmatic monitoring:

```bash
## Poll JSON status
curl https://<run-container-url>/api/status
```

Returns `{ isRunning, progress: {total, analyzed, saved, skippedByFilters, percentage}, cost: {spent, currency}, timing: {elapsedSeconds, startedAt}, settings: {mode, plan} }`.

### 🤖 Programmatic / API use

```bash
## Trigger a run via Apify API
curl -X POST "https://api.apify.com/v2/acts/afanasenko~linkedin-profile-api-scraper/runs?token=$APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "operationMode": "lookupByUrl",
    "profileUrls": ["https://www.linkedin.com/in/satyanadella/"]
  }'
```

Fetch dataset items:

```bash
curl "https://api.apify.com/v2/datasets/<datasetId>/items?token=$APIFY_TOKEN&clean=1&format=json"
```

Read RUN_SUMMARY:

```bash
curl "https://api.apify.com/v2/key-value-stores/<storeId>/records/RUN_SUMMARY?token=$APIFY_TOKEN"
```

### ❓ FAQ

**Are filters charged?**
Filters narrow output, not bill. The paid event fires when a row is fetched; filtering it out doesn't refund. Use `maxItemsModeN` to cap spend.

**Can I scrape private profiles?**
No. Only public LinkedIn data is available. Profiles set to private return "Profile not found" with no charge.

**What's the difference between Mode 3 (slim) and Mode 1 (full)?**
Mode 3 returns slim rows (10 fields per match) from the search index — cheap way to discover relevant profiles. Feed those URLs back into Mode 1 for full 46-field enrichment.

**Is data live?**
Yes. Each lookup hits LinkedIn's public profile in real time (no stale cache).

**Why do I sometimes see a row where most fields are "N/A"?**
For Mode 3/4 search results, the slim row holds only the search-index fields. Re-run those URLs through Mode 1 / Mode 2 to fill the full schema.

**How do I pause / resume a long run?**
Apify's Resurrect feature works — the actor doesn't keep internal state across resurrections, so each resurrection starts fresh from the input. Better pattern for big lists: split inputs into batches of 500-1000 per run.

**Do I need my own LinkedIn account, cookies, or login?**
No. You don't connect your LinkedIn account and there's nothing to log into — paste URLs or search criteria and run. Only public LinkedIn data is returned.

**Can I bulk-enrich a big list of profile URLs?**
Yes. Mode 1 takes many profile URLs at once. For very large lists, split into batches of 500–1000 per run and set `maxItemsMode1` to cap spend.

### 🔗 Other LinkedIn / lead-gen scrapers (same author)

| You start with… | You want to find… | Use this actor |
|---|---|---|
| LinkedIn profile URLs | Bulk-enrich profiles + companies | **This actor** — Mode 1 / Mode 2 |
| Search criteria (keyword / company / job title) | Decision-makers + companies via search index | **This actor** — Mode 3 / Mode 4 |
| Job titles, companies or countries | A list of people — employees and decision makers, up to 2,500 per search | [LinkedIn People Search](https://apify.com/afanasenko/linkedin-people-search) |
| LinkedIn job criteria / job-posting URLs / company URLs | Job listings + full description, skills, salary, hiring team | [LinkedIn Jobs Scraper](https://apify.com/afanasenko/linkedin-jobs-scraper) |
| Instagram handles | Profile data + 5 discovery modes (followers, similar, keyword, location) | [Instagram Profile Scraper](https://apify.com/afanasenko/instagram-profile-scraper) |
| TikTok profile / hashtag | Profile data + posts | [TikTok Profile Scraper](https://apify.com/afanasenko/tiktok-profile-scraper) |
| YouTube channel URL / handle | Channel + video metadata | [YouTube Channel Scraper](https://apify.com/afanasenko/youtube-channel-scraper) |
| US ZIP / address | Property listings + market data | [Zillow Scraper](https://apify.com/afanasenko/zillow-scraper) |

### 🛟 Support & feedback

Found a bug? Have a feature request? Open an issue on the actor's Apify Store page **Issues** tab — that's the canonical channel and I get a notification on every new issue.

### 💡 Tips & Best Practices

#### Getting max results

- For Mode 3 (Search Leads): job-title filter is fuzzy — `engineer` matches `software engineer`, `staff engineer`, `principal engineer`. Use specific titles (`VP of engineering`) when you want narrow.
- For Mode 4 (Search Companies): keywords are AND-style — `saas analytics` matches companies that mention both. Try single keywords first to gauge volume.
- For Mode 1: company-URL inputs auto-route through company lookup, so you can mix profile and company URLs in one run.

#### Cost optimization

- Use `maxItemsModeN` aggressively when testing — 5-10 first to validate output, then scale up.
- Mode 3 / Mode 4 find leads and companies you don't have links for yet: a single search returns up to 100 slim rows (25 by default), at the same $0.030/row that Mode 1 / Mode 2 charge per full record.
- Filters don't reduce billing but reduce noise — apply `industryFilter` + `countryFilter` for tighter targeting BEFORE pasting URLs into a Mode 1 follow-up pass.

#### Performance

- Mode 1 and Mode 2 look up several profiles or companies at once — usually a few seconds each, up to a minute each with `findEmails` on. The live status page shows progress. Runs you start at the same time share capacity, so each one finishes more slowly while they overlap.
- Mode 3 / Mode 4 searches answer directly — usually a few seconds for 25 people or companies. A search with no matches ends in seconds with a clear no-results message.

#### Data quality

- LinkedIn profiles update daily; running the same URL twice in a week may return slightly different `follower_count` / `headline`.
- "N/A" is intentional — always-emitted columns let you write `IF(field == "N/A", ...)` instead of null-checking.
- Mode 3 lead rows are slim by design (name, title, company, location, about, profile URL) — feed their URLs into Mode 1 for full profiles and work emails.

### ⚖️ Disclaimer

This actor scrapes only **publicly available** LinkedIn data. You are responsible for using the data in accordance with LinkedIn's Terms of Service, applicable privacy laws (GDPR, CCPA), and ethical-use guidelines. The actor does not scrape private profiles, paid LinkedIn features (Sales Navigator), or content behind login walls.

# Changelog

This Actor's version history is a separate document: https://apify.com/afanasenko/linkedin-profile-api-scraper/changelog.md

# Actor input Schema

## `operationMode` (type: `string`):

Select what you want to look up. The fields appearing below depend on this choice.

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

LinkedIn profile URLs (one per line). Format: https://www.linkedin.com/in/<username>/

## `findEmails` (type: `boolean`):

Look for each profile's work email address — found for about half of profiles. A verified one ("valid": the mailbox accepts mail) goes in email; an unverified one ("risky": the mail server accepts any address, so delivery is not guaranteed) goes in emailGuess. Up to a minute per profile. From 6 November 2026 each profile delivered with a verified email costs an extra $0.03 ("Email found"); an emailGuess is free.

## `maxItemsMode1` (type: `integer`):

Hard cost ceiling for Mode 1 — each enriched profile is one paid event. Free plan ceiling: 50 items regardless of this value. 0 = unlimited (paid plan only). Default 0.

## `companyInputs` (type: `array`):

LinkedIn company URLs (https://www.linkedin.com/company/<slug>/) OR company domains (microsoft.com). Mix both freely — each line is auto-detected and routed to the right lookup.

## `maxItemsMode2` (type: `integer`):

Hard cost ceiling for Mode 2. Free plan ceiling: 50 items. 0 = unlimited. Default 0.

## `searchLeadCompanyUrls` (type: `array`):

LinkedIn company URLs to search decision-makers at (e.g. https://www.linkedin.com/company/microsoft/). For each company, the actor finds employees matching the optional job title filter.

## `searchLeadJobTitle` (type: `string`):

Filter results to leads whose job title matches this text (e.g. "data scientist", "VP sales", "head of marketing"). Leave blank to return all decision-makers at the target companies. Tip: broad titles match many people; a very specific title like "VP of Data Engineering" can match nobody — start broad, then narrow.

## `searchLeadCount` (type: `integer`):

How many leads to retrieve per target company. Max 100. Default 25.

## `maxItemsMode3` (type: `integer`):

Hard cost ceiling for Mode 3 — each retrieved lead is one paid event. Free plan ceiling: 50 items. 0 = unlimited. Default 0.

## `searchCompanyKeywords` (type: `string`):

Free-text keywords describing the companies you want to find (e.g. "saas analytics", "renewable energy", "e-commerce"). One search keyword string per run. Tip: use one core concept (e.g. "fintech"); extra words sharply narrow company matches.

## `searchCompanyIndustries` (type: `array`):

Restrict company search to specific industries. Multi-select; leave empty to search across all industries.

## `searchCompanyCount` (type: `integer`):

How many companies to retrieve. Max 100. Default 25.

## `maxItemsMode4` (type: `integer`):

Hard cost ceiling for Mode 4 — each retrieved company is one paid event. Free plan ceiling: 50 items. 0 = unlimited. Default 0.

## `minFollowers` (type: `integer`):

Skip records with fewer followers than this. 0 = no minimum. Applies to all modes.

## `maxFollowers` (type: `integer`):

Skip records with more followers than this. 0 = no maximum.

## `mustHaveEmail` (type: `boolean`):

Keep only records with an email address — verified (email) or unverified (emailGuess). Turns on Find work emails for Mode 1. Profiles without an address are excluded but still count as analyzed for billing.

## `mustHavePhone` (type: `boolean`):

No longer available: LinkedIn records here carry no phone numbers, so this filter would exclude every row.

## `openToWorkOnly` (type: `boolean`):

Keep only profiles flagged as #OpenToWork. Profile-only filter; ignored in company modes.

## `countryFilter` (type: `string`):

Keep only rows whose country matches. Leave blank to skip filtering.

## `industryFilter` (type: `string`):

Keep only rows whose industry matches. Leave blank to skip filtering.

## Actor input object example

```json
{
  "operationMode": "lookupByUrl",
  "profileUrls": [],
  "findEmails": false,
  "maxItemsMode1": 0,
  "companyInputs": [],
  "maxItemsMode2": 0,
  "searchLeadCompanyUrls": [],
  "searchLeadJobTitle": "",
  "searchLeadCount": 25,
  "maxItemsMode3": 0,
  "searchCompanyKeywords": "",
  "searchCompanyIndustries": [],
  "searchCompanyCount": 25,
  "maxItemsMode4": 0,
  "minFollowers": 0,
  "maxFollowers": 0,
  "mustHaveEmail": false,
  "mustHavePhone": false,
  "openToWorkOnly": false,
  "countryFilter": "",
  "industryFilter": ""
}
```

# Actor output Schema

## `liveStatus` (type: `string`):

No description

## `results` (type: `string`):

No description

## `runSummary` (type: `string`):

Aggregate run statistics — counts, mode, paid events fired, wall-clock time.

## `userMessage` (type: `string`):

Onboarding tip, paid-plan welcome, or diagnostic message — only present when the run has something to surface.

## `freeLimitsApplied` (type: `string`):

Free-tier caps that affected this run. Empty if no caps applied or user is on a paid plan.

# 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 = {
    "operationMode": "lookupByUrl"
};

// Run the Actor and wait for it to finish
const run = await client.actor("afanasenko/linkedin-profile-api-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 = { "operationMode": "lookupByUrl" }

# Run the Actor and wait for it to finish
run = client.actor("afanasenko/linkedin-profile-api-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 '{
  "operationMode": "lookupByUrl"
}' |
apify call afanasenko/linkedin-profile-api-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,afanasenko/linkedin-profile-api-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/QSuUu2p6LAaM3MRXr/builds/y1BHkB6LQuZmGNxTR/openapi.json
