LinkedIn Scraper - Jobs, Profiles, Posts & Companies avatar

LinkedIn Scraper - Jobs, Profiles, Posts & Companies

Pricing

from $1.00 / 1,000 results

Go to Apify Store
LinkedIn Scraper - Jobs, Profiles, Posts & Companies

LinkedIn Scraper - Jobs, Profiles, Posts & Companies

Extract LinkedIn jobs, profiles, posts, and company data across supported countries. Filter jobs by location, employer, seniority, and date. Pay per delivered row plus a small start fee.

Pricing

from $1.00 / 1,000 results

Rating

0.0

(0)

Developer

kane liu

kane liu

Maintained by Community

Actor stats

4

Bookmarked

46

Total users

5

Monthly active users

2 days ago

Last modified

Security

Limited permissions

Share

LinkedIn Scraper

Export LinkedIn jobs, posts, profiles, and organizations as structured rows for hiring research and analysis.

  • Job titles, employers, locations, descriptions, and disclosed salaries.
  • Company, industry, seniority, date, and workplace filters.
  • Direct job URLs, job IDs, post URLs, and organization targets.
  • Optional additional profile and recent-post rows.
  • $1 per 1,000 delivered rows on the Free plan, plus a small start fee.

What does LinkedIn Scraper do?

LinkedIn Scraper collects information available from LinkedIn pages and saves one entity per dataset row. Job search supports the country choices in the form, including the United States, United Kingdom, Canada, Germany, India, and Japan, plus free-text locations.

  • Jobs: search with keyword, scope an employer with company, or supply detailUrls or jobIds.
  • Posts: supply postUrls for text and published engagement counts.
  • Profiles and companies: use profileUrls; use orgUrls for companies, schools, or showcase pages.
  • Discovery: use discoverKeyword or discoverSeeds to find profile and company targets.
  • Additional rows: enrichProfiles is off by default. Enabling it can add profile/company rows to job searches or up to five recent posts for a profile. Each added row costs the same and shares that input's row limit.

What data can you extract from LinkedIn?

Every row has rowType, a stable id, and scrapedAt. Fields depend on the target and what LinkedIn exposes. Discovery returns the corresponding profile, organization, or post rows, not a guaranteed separate discovery summary.

Job rows (rowType=job)

FieldDescriptionExample
jobIdPosting identifier4012345678
jobTitleRole titlePython Developer
companyNameEmployer nameExample Company
companyUrlLinkedIn employer pagehttps://www.linkedin.com/company/example-company
locationAdvertised job locationLondon, England
jobUrlPosting URLhttps://www.linkedin.com/jobs/view/4012345678
postedAtPosting date when available2026-10-20
jobDescriptionDescription with details enabledBuild data applications.
employmentTypePublished employment typeFULL_TIME
experienceLevelPublished seniorityAssociate
jobFunctionPublished functionEngineering
industryPublished industrySoftware Development
salaryDisclosed amount, currency, periodGBP 60000-80000 YEAR
isRemoteRemote signal; unknown stays nulltrue
workplaceTypePublished workplace categoryTELECOMMUTE
skillsKeywords matched in description, not verified qualifications["Python", "SQL"]
easyApplyEasy Apply availability when showntrue
applyUrlApplication link when shownhttps://example.com/jobs/apply
applicantsCountExact count; bounds stay null25
datePostedDate published in posting details2026-10-20
validThroughPublished expiry, when available2026-11-20
externalIdYour supplied database identifierrecord-001
emailsPublic employer emails; not verified inboxes[]
addressEmployer address or job-location fallback{"locality": "London"}
geoPublished job coordinates, not headquarters{"lat": null, "lng": null}
webEmployer website and available social links{"website": "https://example.com", "socials": []}
leadAbsencesExplanations for missing contact fields{}

Post rows (rowType=post)

FieldDescriptionExample
postUrlSource post URLhttps://www.linkedin.com/posts/example-activity-1234567890123456789
postTextPublished textOur team is hiring.
authorAuthor information{"name": "Jane Doe"}
datePublishedPublication date2026-10-20
reactionCountPublished reactions12
commentCountPublished comment count2
repostCountPublished repost count1

Profile rows (rowType=profile)

FieldDescriptionExample
profileUrlSource profilehttps://www.linkedin.com/in/jane-doe
nameDisplay nameJane Doe
headlineProfessional headlineData Engineer
aboutPublic introductionBuilding data applications.
experiencesVisible work history[]
educationVisible education[]
followerCountCount when shown100

Organization rows (rowType=org)

FieldDescriptionExample
orgNameOrganization nameExample Company
orgGuestUrlSource organization pagehttps://www.linkedin.com/organization-guest/company/example-company
entityOrganization page typecompany
websiteExternal websitehttps://example.com
employeeCountPublished employee count100
specialtiesPublished specialties["Software"]
jobCountLinks found on an organization jobs page, not total vacancies9

How to scrape LinkedIn

  1. Open LinkedIn Scraper in Apify Console.
  2. Fill one target field, such as keyword.
  3. Set maxResults to 3 for a small first run.
  4. Click Start and wait for completion.
  5. Download the dataset or read its rows through the API.

Empty input starts an example search for python developer, limited to three rows. This is a billed run, not a free preview. A target field selects what to collect automatically; there is no mode field to fill. Prefer one target type per run.

Fill keyword; add country and location. scrapeDetails=false skips job-description enrichment. A location alone is not a search target.

Employer jobs

Use a company ID or company page URL in company, or a numeric companyId. Set keyword to an empty string for an employer-only search.

Known jobs

Use detailUrls or jobIds; these can be combined. Full LinkedIn job URLs are preferable when available. externalIds follows the order of URLs, then IDs.

Posts

Use postUrls with LinkedIn post URLs or activity URNs. Available text and counts vary by post.

Profiles and company pages

Use profileUrls with /in/ or /company/ URLs. Recent posts require enrichProfiles=true and enough remaining row allowance.

Organizations

Use orgUrls, for example company:microsoft or school:stanford-university. These return organization records; organization jobs pages are not a substitute for complete employer job search.

Discovery

Use discoverKeyword or seed tokens such as company:microsoft in discoverSeeds. Set a small discoverLimit; candidates may be unavailable or unrelated, so review the returned rows.

What to fill in

FieldWhat to enterDefault
keywordOne job title or search phraseSample: python developer
detailUrlsLinkedIn HTTPS job URLsEmpty
jobIdsJob posting IDsEmpty
companyCompany IDs or URLs, comma-separatedEmpty
companyIdOne numeric employer IDEmpty
postUrlsPost URLs or activity URNsEmpty
profileUrlsProfile or company URLsEmpty
orgUrlsOrganization URLs or typed slug tokensEmpty
locationCity, state, or regionEmpty
countryForm country code, such as gb, or remoteAny
industryForm option, such as softwareAny
jobFunctionForm option, such as engineeringAny
jobTypeF full-time, P part-time, C contract, T temporary, I internship, V volunteer, O otherAny
datePostedr86400 day, r604800 week, r2592000 monthAny
experienceLevel1 internship through 6 executive, as labeled in the formAny
remoteFilter1 on-site, 2 remote, 3 hybridAny
easyApplyOnlyOnly Easy Apply jobsfalse
under10ApplicantsJobs marked below ten applicantsfalse
sortByrelevance or recentRelevance
maxResultsRows per input, from 1 to 1,00070; form prefill 3
scrapeDetailsInclude available job detailstrue
enrichProfilesAdd separately billed related rowsfalse
discoverKeywordProfile/company discovery phraseEmpty
discoverSeedsTokens such as in:jane-doeEmpty
discoverLimitDiscovery candidate limit, 1–20020
offlineCorpusInclude indexed discovery candidatesfalse
liAtCookieOptional authorized LinkedIn session for profile fields; not required for jobs. Using your own session cookie is at your own risk and subject to LinkedIn's terms; the Actor works without it for public data.Empty
externalIdsYour IDs corresponding to direct job inputsEmpty
rowLayoutKeep one entity per rowrows

Keyword search

{"keyword": "python developer", "country": "gb", "datePosted": "r604800", "maxResults": 3}

Employer jobs

{"companyId": "1035", "keyword": "", "maxResults": 3}

Known jobs

{"jobIds": ["4012345678"], "externalIds": ["record-001"], "maxResults": 1}

Posts

{"postUrls": ["urn:li:activity:7133147405666959360"], "maxResults": 1}

Profiles

{"profileUrls": ["https://www.linkedin.com/in/jane-doe"], "maxResults": 1}

Organizations

{"orgUrls": ["company:microsoft"], "maxResults": 1}

Discovery

{"discoverKeyword": "data engineering", "discoverLimit": 3, "maxResults": 3}

The profile URL is a placeholder; replace it with your target.

maxItems and limit are aliases for maxResults; query maps to keyword, and startUrls to detailUrls. Close field-name misspellings are corrected; other unknown fields are ignored with a note. Invalid filter choices are ignored rather than stopping collection. Check INPUT_REPORT in the default key-value store to see how each run interpreted the input.

Invalid targets stop before row charges with INVALID_INPUT: <field> — <how to fix>. The start fee still applies. datePosted is a recency filter, not an automatically expanding date window.

Output example

Illustrative job row; actual values and field availability depend on the posting:

{
"rowType": "job",
"id": "4012345678",
"jobId": "4012345678",
"jobTitle": "Python Developer",
"companyName": "Example Company",
"location": "London, England",
"jobUrl": "https://www.linkedin.com/jobs/view/4012345678",
"jobDescription": "Build Python data applications.",
"salary": null,
"isRemote": null,
"easyApply": null,
"applicantsCount": null,
"skills": ["Python"],
"scrapedAt": "2026-10-24T08:00:00Z"
}

Export the dataset as JSON, CSV, Excel, XML, RSS, or an HTML table.

Why use this LinkedIn scraper?

  • Row-based billing: after the start fee, charges apply to delivered rows, not pages tried.
  • Partial results: rows already saved remain available after a stop. Collection interrupted by a deadline can deliver the rows gathered before it stopped.
  • Inspect failures: ERROR_SUMMARY explains failures; RUN_SUMMARY can include partial-result reasons and warnings even when a run succeeds.
  • Missing stays missing: undisclosed salaries and unavailable counts are not invented. Job skills are explicitly derived from description text.
  • Several inputs: URL and ID arrays let you submit multiple targets together.
  • No proxy setup: you do not need to set up proxies.

How much does it cost to scrape LinkedIn?

Pricing is pay-per-event. At the default 512 MB memory, starting a run incurs one $0.00005 start event. The start event counts once per GB, with a minimum of one event. Platform usage is included in these prices.

Apify planStart fee at 512 MBPrice per rowPrice per 1,000 rows
Free$0.00005$0.001$1.00
Starter$0.00005$0.001$1.00
Scale$0.00005$0.001$1.00
Business$0.00005$0.001$1.00

maxResults applies to each input, defaults to 70, and accepts up to 1,000. Larger requests are collected in parts of at most 70 rows. All row types for that input share its allowance. Free Apify plan runs are capped at 200 rows, with ten total runs of this Actor. Paid plans remove that ten-run cap.

The whole run stops at your Maximum cost per run (maxTotalChargeUsd in the API). Limits are ceilings, not guarantees of enough matching data.

Example: five delivered rows at 512 MB cost 5 × $0.001 + $0.00005 = $0.00505, on any listed plan.

What happens when the run timeout is too short

If collection needs longer than your timeout, the run can pause automatically instead of failing. Its status becomes ABORTED with the message "Queued on the collection backend; this run will resume automatically when results are ready (about N s)."

When ready, the same run resumes and writes to the same dataset, finishing as SUCCEEDED when delivery succeeds. Continued delivery can show "Resumed: delivering N rows." Previously delivered rows are skipped, so they are not delivered or charged twice. No manual restart is needed for this pause.

This can happen at most three times per run. Keep the default 1,800-second timeout to reduce interruptions. Actual collection failures can still fail a run.

Synchronous endpoints (run-sync, run-sync-get-dataset-items) wait at most 300 seconds and can return an empty dataset during a pause. For longer work, start asynchronously and read results after SUCCEEDED, or use an ACTOR.RUN.SUCCEEDED webhook. Calls that wait for completion can also return at the temporary ABORTED state.

Use with AI agents and the API

Apify MCP server

Add this remote MCP server in Claude, ChatGPT, Cursor, VS Code, or another compatible client:

https://mcp.apify.com?tools=lentic_clockss/linkedin-jobs-scraper

Sign in with Apify through OAuth, or send Authorization: Bearer <YOUR_APIFY_TOKEN>. The tool starts a run and returns run and dataset IDs; read rows with get-dataset-items. For clients without remote support, run npx @apify/actors-mcp-server --tools lentic_clockss/linkedin-jobs-scraper with APIFY_TOKEN configured.

Example prompt: "Find three data engineer jobs in London posted this week, including salary when disclosed."

Apify API

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("lentic_clockss/linkedin-jobs-scraper").call(
run_input={"keyword": "data engineer", "country": "gb", "maxResults": 3}
)
if run["status"] == "SUCCEEDED":
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
print(row)
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('lentic_clockss/linkedin-jobs-scraper').call({
keyword: 'data engineer', country: 'gb', maxResults: 3,
});
if (run.status === 'SUCCEEDED') {
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
}

For asynchronous HTTP, send POST https://api.apify.com/v2/acts/lentic_clockss~linkedin-jobs-scraper/runs with JSON input and an Authorization: Bearer header. After success, fetch GET https://api.apify.com/v2/datasets/<datasetId>/items?format=json.

Integrations

Use the Integrations tab for Google Sheets, Make, Zapier, n8n, Slack, Airtable, or webhooks. Apify Schedules can repeat a saved input.

FAQ

Public availability is not permission for every use. You are responsible for LinkedIn's terms and applicable data-protection law. Processing personal data requires a lawful basis; limit collection and retention to your purpose.

Why did my run end as ABORTED?

The automatic pause described above uses ABORTED temporarily. Check the status message; a manual abort or unrelated interruption is not necessarily resumable.

How many results can I get?

Up to 1,000 rows per input, subject to available matches, the run's cost limit, and Free-plan caps. Added profile or post rows reduce the remaining allowance.

Why are some fields empty?

LinkedIn may omit them, or a detail page may be unavailable. Salary is only returned when disclosed. Applicant bounds such as "Over 200" are not exact counts and remain null.

Do I need a LinkedIn account?

Not for public job search. Optional profile enrichment with liAtCookie uses your authorized session and cannot guarantee access to restricted fields. Never share session values in support requests.

Can I monitor one company?

Yes. Supply its LinkedIn URL or ID in company, or use companyId. Compare jobId values in your own storage to identify repeats. Missing rows alone do not prove vacancies closed.

Can I get only remote jobs?

Set remoteFilter to 2. Choosing country=remote supplies that filter when no workplace filter is already set. Inspect each returned job's location.

Limitations

  • Results are not a complete LinkedIn census; narrow filters and unavailable pages can reduce counts.
  • Location filtering is not a strict geographic boundary.
  • Phone and hiring-contact extraction are not implemented. Public employer emails are neither guaranteed nor verified for deliverability or outreach suitability.
  • Employer address and job geo can refer to different places; city-only addresses do not establish a headquarters street address.
  • Profile history, recent posts, and engagement counts can be incomplete. Discovery candidates are not guaranteed matches.

More job board and freelance marketplace scrapers from the same publisher:

Browse all of our scrapers at apify.com/lentic_clockss.

Support

Report problems or request a field through the Issues tab of this Actor's page. Include the run ID and input, with credentials removed.