LinkedIn Company URL - Mass Profile Finder & Employee List
Pricing
Pay per usage
LinkedIn Company URL - Mass Profile Finder & Employee List
Find LinkedIn company profiles in bulk from company names, websites, or domains. Extract LinkedIn company URLs, profile details, industry data, follower counts, and business information to streamline lead generation, sales prospecting, recruitment, and market research.
Pricing
Pay per usage
Rating
0.0
(0)
Developer
Scrapier
Maintained by CommunityActor stats
0
Bookmarked
9
Total users
7
Monthly active users
2 days ago
Last modified
Categories
Share
LinkedIn Company URL Finder — Company Pages & Employee Profiles
Turn a plain list of company names into their official LinkedIn company page URLs, then expand each one into a best-effort list of the public employee profiles working there — name, headline, job title, location, and profile URL. Every result lands as typed JSON rows in one dataset, ready to export or hand straight to an LLM, CRM, or monitoring pipeline. No LinkedIn login is required to run it, and the input list can be as short as one name or as long as you need.
What is LinkedIn Company URL - Mass Profile Finder & Employee List?
It is a bulk company-to-LinkedIn resolver that also discovers who works at each company. You submit company names; the Actor returns one parent row per company (its canonical linkedin.com/company/<slug> page) and, when enabled, a set of child rows for employees found via public search results and the company's own /about/ page — no login, no cookies, required by default. Where most LinkedIn "company URL finder" tools on Apify stop at the company page, this Actor also returns the people behind it in the same dataset.
- Bulk company name input — one name per line, no per-run cap on how many you submit
- Employee discovery per company, capped and filterable by job title
- Region/language control for the underlying search (
us-en,uk-en,ca-en,au-en,in-en, or worldwide) - Adjustable concurrency (1–100 companies in parallel)
- Optional
li_atsession cookie to reduce LinkedIn's guest blocks on profile pages - Self-escalating proxy ladder (direct → datacenter → residential) with no proxy configuration required to start
Whether you're searching for a bulk LinkedIn company lookup, a LinkedIn employee finder for a list of target accounts, or a way to turn a spreadsheet of company names into a lightweight LinkedIn org chart starting point, this Actor is built around the same bulk input: a plain list of names in, structured company-and-people rows out.
🎯 Employee profiles — the differentiator
This is the capability the three closest LinkedIn company-URL finders on the Apify Store do not offer in the same Actor: none of their documented output fields include a person's name, headline, job title, or profile URL — they return company rows only, and point you at a separate Actor for people (as of 2026-07-26, Anchor's own README recommends chaining to a second Actor, "Mass people finder," to get individual LinkedIn URLs). This Actor keeps the company step and adds employee rows in the same run, same dataset, distinguished by type and isChild:
{"type": "employee","isChild": true,"parentId": 1,"mySearch": "Stripe","queryId": 1,"linkedinUrl": "https://www.linkedin.com/company/stripe","fullName": "Jane Doe","headline": "Head of Sales at Stripe","jobTitle": "Head of Sales","location": "San Francisco, California","profileUrl": "https://www.linkedin.com/in/janedoe","scrapedAt": "2026-07-16T12:00:03Z"}
Coverage is honest, not complete — see the constraint below before you plan a workflow around it.
How employee discovery works
Discovery is a two-step, logged-out process run for every resolved company. First, the Actor issues search-engine queries scoped to site:linkedin.com/in combined with the company name — a precise "at <company>" current-employee phrasing, then a broader fallback — and pulls every linkedin.com/in/<slug> URL out of the results. Second, it fetches the company's own public /about/ page and extracts any additional /in/ profile links found in that HTML. Both sources are de-duplicated into one candidate list. Because a meaningful share of candidates will hit LinkedIn's guest block, the Actor deliberately over-discovers — it attempts up to three times as many candidate profiles as your maxEmployeesPerCompany cap before giving up on that company, stopping early the moment it has kept enough. Every candidate profile is parsed from og: meta tags and, where present, a schema.org/Person JSON-LD block; a profile whose page comes back as the guest sign-up wall (an og:title of "LinkedIn," "Sign Up," or similar) is discarded rather than kept as a hollow record.
What data can you get with this Actor?
Every run can return two result types in the same dataset — a resolved company page and, for each company, the public employees discovered under it.
| Result Type | Extracted Fields | Primary Use Case |
|---|---|---|
Company page (type: "company") | mySearch, queryId, linkedinUrl, info, scrapedAt | Resolving a name into its canonical LinkedIn URL for CRM enrichment or link-building |
Employee profile (type: "employee") | parentId, mySearch, queryId, linkedinUrl, fullName, headline, jobTitle, location, profileUrl, scrapedAt | Finding named contacts at a target company for sales, recruiting, or research |
Company page rows
Each row is the single, highest-ranked linkedin.com/company/<slug> page for a submitted name, with info carrying the page's own title (e.g. "Stripe - LinkedIn"). A non-company LinkedIn link — a login page or feed URL — is deliberately never treated as a match, so linkedinUrl is either a real company page or null.
⚠️ Employee coverage is partial by design
Employee discovery is logged-out and best-effort. LinkedIn returns an HTTP 999 guest block (an authwall) to a large share of anonymous /in/ profile fetches, so a typical run recovers a handful of employees per company, not a full roster. The source code never fabricates a person to fill the gap — a blocked or unparseable profile is skipped and counted, and any field it can't read (name, headline, job title, or location) comes back as null rather than a guess. Pasting your own LinkedIn li_at session cookie into the optional sessionCookie field reduces — but does not eliminate — the guest blocks. If you need a complete, paginated roster of every employee at a company, that requires an authenticated LinkedIn session and sits outside this Actor's keyless scope.
Why not build this yourself?
LinkedIn does not publish a self-serve API for resolving arbitrary company names to their public page or for listing a company's employees — its official Talent/Marketing APIs are partner-gated, require an approved application, and are scoped to specific advertising and recruiting integrations, not open company/people lookup. Building a homegrown scraper means maintaining your own HTML parsing against a layout that changes without notice, handling the guest authwall's HTTP 999 responses, and running a proxy escalation ladder to avoid getting blocked outright — all before you've resolved a single company. This Actor already does that work: it browser-impersonates Chrome at the HTTP layer for every request, parses LinkedIn's public search and profile HTML, and walks a direct → datacenter → residential proxy ladder automatically the moment a request is throttled or blocked, retrying with exponential backoff (capped at 8 seconds between search retries, 6 seconds between profile-page retries, plus a small random jitter) and a fresh proxy IP on every attempt. Once the ladder escalates to residential, it sticks there for the rest of the run rather than dropping back down.
What is the difference between a company URL finder and an employee finder?
A LinkedIn "company URL finder" and a LinkedIn "employee finder" are usually two separate product categories on the Apify Store, and this Actor deliberately collapses them into one. The older category — pure company-URL resolution — was built for a single job: turning a name into a link, useful for CRM hygiene but useless the moment the actual task is "who do I contact here." Sales, recruiting, and account-based marketing workflows need a name attached to that company, not just a URL, which is why the top LinkedIn company-URL finders on the Apify Store (checked 2026-07-26) explicitly send users to a second, separate Actor for people data. This Actor returns both in one run: the company object (type: "company") and its employee objects (type: "employee"), keyed together by queryId/parentId in the same dataset, so a single job answers both "what's their LinkedIn page" and "who works there" without chaining two Actors or paying for two runs.
How to scrape LinkedIn company and employee data
- Open LinkedIn Company URL - Mass Profile Finder & Employee List in Apify Console.
- Enter your company names, one per line, in 🏢 Company Names (bulk input).
- Set your real query controls — 🌍 Search Region, 👥 Find employees for each company, 🔢 Max employees per company, and optionally 🎯 Job-title filter.
- Click Start.
- Stream results from the Output tab as the run progresses, or export to JSON, CSV, or XLSX once it finishes.
A minimal request that resolves three companies and pulls up to 6 employees each, keeping only leadership titles:
{"companyNames": ["Stripe", "OpenAI", "Notion Labs"],"fetchEmployees": true,"maxEmployeesPerCompany": 6,"titleFilter": ["Founder", "CEO", "Head of Sales"]}
How to run multiple companies in one job
companyNames accepts a full list, not a single value — the input schema's stringList editor takes one company per line (or a comma/newline-separated string; the Actor also still accepts the legacy key name queries for backward compatibility). Every unique name in the list is processed in the same run; maxConcurrency (default 10, 1–100) controls how many companies are worked on in parallel. Employees within a single company are always fetched one at a time, to stay gentle on LinkedIn regardless of how high you set concurrency.
⬇️ Input
All ten parameters are read directly from .actor/actor.json's input schema; the table below reproduces every name, type, default, and constraint exactly as declared there — nothing simplified, nothing renamed.
| Parameter | Required | Type | Constraints | Description |
|---|---|---|---|---|
companyNames | No | array | editor: stringList | One company name per line, e.g. Stripe, OpenAI, Notion Labs. Each resolves to its LinkedIn company page and, if enabled, its employees. |
fetchEmployees | No | boolean | default true | When ON, discovers public LinkedIn profiles of people at each resolved company and emits them as child rows (type=employee). Coverage is partial and logged-out. |
maxEmployeesPerCompany | No | integer | default 6, min 0, max 40 | Upper bound on employee rows kept per company. 0 means unlimited, capped internally at 40. |
titleFilter | No | array | editor: stringList | Keep only employees whose headline or job title contains one of these keywords (case-insensitive). Empty keeps every employee found. |
region | No | string | default us-en; enum us-en, uk-en, ca-en, au-en, in-en, wt-wt | Region/language used for the company and employee lookup. us-en returns English titles like "Stripe - LinkedIn". |
maxConcurrency | No | integer | default 10, min 1, max 100 | How many companies are processed in parallel. Employees within a company are always fetched sequentially. |
sessionCookie | No | string (secret) | editor: textfield, isSecret: true | Optional LinkedIn li_at session cookie value to reduce HTTP 999 guest blocks and recover more employee profiles. Masked in the Console UI and run logs. Leave empty to run fully logged-out. |
companySearchSuffix | No | string | default "linkedin company" | Phrase appended to each company name to surface its LinkedIn page. |
includeNotFound | No | boolean | default true | When ON, companies with no LinkedIn page still get a row (empty URL) so company output lines up 1-to-1 with your input. |
proxyConfiguration | No | object | default {"useApifyProxy": false}, editor: proxy | Runs with no proxy by default. On a block, the Actor automatically falls back to a Datacenter proxy, then Residential, and sticks with Residential for the rest of the run. |
None of the ten parameters are required — an empty run simply logs a warning and does nothing.
For backward compatibility with the base company-URL Actor this variant is built on, the source also accepts the legacy input keys queries (alias for companyNames), employeeJobTitles (alias for titleFilter), linkedInSessionCookie (alias for sessionCookie), and querySuffix (alias for companySearchSuffix) — none of these appear in the input schema UI, but a JSON body using the old names still works.
Three further tuning keys are read from the input but are not exposed as fields in the Console UI — set them by editing the run's JSON input directly if you need to override the defaults:
| Key | Type | Default | Behavior |
|---|---|---|---|
requestTimeout | number | 20 | Per-request timeout, in seconds, for both the company search and the profile-page fetches. |
retryBackoff | number | 1.5 | Backoff multiplier used to space out retries after a throttle or block. |
maxRetries | integer | 6 | Retry attempts per request before giving up; the Actor clamps whatever value you pass to between 1 and 12. |
Because these aren't declared in the input schema, they won't appear on the Console's Input tab — they only take effect when included in a JSON payload sent through the API or the "Input JSON" editor.
Example input
{"companyNames": ["Stripe", "Notion Labs", "OpenAI"],"fetchEmployees": true,"maxEmployeesPerCompany": 6,"titleFilter": ["Founder", "CEO", "Head of Sales"],"region": "us-en","maxConcurrency": 10,"includeNotFound": true,"proxyConfiguration": { "useApifyProxy": false }}
Common pitfall: proxyConfiguration defaults to {"useApifyProxy": false} — this Actor runs with no proxy at all until it hits a block, unlike Actors that default to Apify Proxy. For high-volume runs or better employee coverage, turn on Apify Proxy with the RESIDENTIAL group explicitly rather than assuming it's already active.
⬆️ Output
Every row — company or employee — is pushed live to the dataset the moment it's found, as flat, typed JSON. There's no batching delay: a crash mid-run never loses already-collected results. Export the dataset as JSON, CSV, XLSX, HTML, XML, or RSS from the Output tab, same as any Apify dataset.
Both row types share one flat schema of 13 keys; unused fields for a given row type are null rather than omitted. The default dataset view (🏢 Companies & 👥 Employees) already renders all 13 keys — there is nothing hidden beyond what the row-building code writes. queryId and parentId are the join keys that tie the two row types together: a company row's own queryId is the value every one of its employee rows carries in parentId, so you can group a dataset export by parentId (or filter type == "employee" and parentId == 3) to reconstruct "everyone found at company #3" without re-matching on company name.
| Field | Description |
|---|---|
type | "company" for a parent row, "employee" for a child row. |
isChild | false for company rows, true for employee rows. |
parentId | null on company rows; the parent company's queryId on employee rows. |
mySearch | The company name you submitted (shared by a company row and all of its employee rows). |
queryId | 1-based index matching your companyNames input order. |
linkedinUrl | Canonical https://www.linkedin.com/company/<slug> URL, or null if no page was found. Employee rows carry their parent company's URL here too. |
info | The LinkedIn company page title, e.g. "Stripe - LinkedIn". null on employee rows and on unmatched companies. |
fullName | Employee full name, or null on company rows or when the profile page couldn't be read. |
headline | Employee LinkedIn headline, cleaned of LinkedIn's connection-count and "join LinkedIn" boilerplate, or null. |
jobTitle | Best-effort current title, parsed from structured profile data or the headline; null if none could be extracted without guessing. |
location | Employee location when public, or null. |
profileUrl | Canonical https://www.linkedin.com/in/<slug> URL for an employee row, or null on company rows. |
scrapedAt | ISO-8601 UTC timestamp of when that specific row was collected. |
Every row pushed to the default dataset — company or employee — is billed under the row_result event. The Actor pushes no separate uncharged accounting or error rows to the main dataset.
When fetchEmployees is on, every employee row is also pushed a second time to a separate, uncharged mirror dataset named <runId>-employees (visible in the run's Storage tab, or via the Apify API's dataset list, using the run ID as the name prefix). This gives you a clean employees-only table alongside the combined company-and-employee view in the default dataset, at no extra cost.
Scraped results
[{"type": "company","isChild": false,"parentId": null,"mySearch": "Stripe","queryId": 1,"linkedinUrl": "https://www.linkedin.com/company/stripe","info": "Stripe - LinkedIn","fullName": null,"headline": null,"jobTitle": null,"location": null,"profileUrl": null,"scrapedAt": "2026-07-16T12:00:00Z"},{"type": "employee","isChild": true,"parentId": 1,"mySearch": "Stripe","queryId": 1,"linkedinUrl": "https://www.linkedin.com/company/stripe","info": null,"fullName": "Jane Doe","headline": "Head of Sales at Stripe","jobTitle": "Head of Sales","location": "San Francisco, California","profileUrl": "https://www.linkedin.com/in/janedoe","scrapedAt": "2026-07-16T12:00:03Z"},{"type": "employee","isChild": true,"parentId": 1,"mySearch": "Stripe","queryId": 1,"linkedinUrl": "https://www.linkedin.com/company/stripe","info": null,"fullName": null,"headline": null,"jobTitle": null,"location": null,"profileUrl": "https://www.linkedin.com/in/j-doe-blocked","scrapedAt": "2026-07-16T12:00:05Z"},{"type": "company","isChild": false,"parentId": null,"mySearch": "Acme Widgets LLC","queryId": 2,"linkedinUrl": null,"info": null,"fullName": null,"headline": null,"jobTitle": null,"location": null,"profileUrl": null,"scrapedAt": "2026-07-16T12:00:07Z"}]
How can I use the data extracted with this Actor?
- Sales and recruiting research: go from a target-account list straight to named contacts, filtered to the roles you're prospecting or sourcing (
titleFilter: ["Founder", "CEO", "Head of Sales"]), usingmySearch,fullName,headline, andprofileUrl. - AI engineers and LLM developers: feed the JSON rows directly into an agent or RAG pipeline as grounded context — an agent asks for a company, receives the resolved
linkedinUrlplus anyemployeechild rows, and answers with real names and titles instead of a hallucinated org chart. - CRM enrichment: backfill missing
linkedinUrlcompany links and seed key-person profiles for accounts already in your CRM, matching rows back to source records withqueryId. - Recruiters and talent sourcers: scope
titleFilterto the seniority or function you're sourcing (e.g.["Recruiter", "Talent"]on a competitor's own talent team, or the target role itself), and pullfullNameplusprofileUrlstraight into an outreach sequence. - Market and competitor research: compare
headlineandjobTitlepatterns across a set of competitor companies to see who they're hiring into which functions, without opening LinkedIn manually for each one.
How do you monitor employee headcount and hiring changes over time?
Run the same companyNames list on a recurring schedule and diff the results between runs. Because coverage is partial and logged-out, treat each run as a sample rather than a census — the signal worth tracking is the change in what gets discovered, not an absolute headcount. Compare fullName and profileUrl sets per mySearch between two runs: new names that weren't present before are a reasonable hiring signal for that company; names that disappear may mean a departure, a profile that went private, or simply that this run's guest-block draw missed them — the source code's per-run coverage log (discovered/fetched/blocked/kept counts) tells you which. Also watch jobTitle and headline changes on names you've already captured, which can surface promotions or role moves. Keeping titleFilter fixed across runs (rather than changing it run to run) keeps the comparison honest, since a wider or narrower filter will change which employees are kept independent of any real change at the company. Schedule the run using Apify's built-in Schedules (cron-based, in Apify Console or via the API) so each run's dataset is timestamped and comparable, and pull results after each run with the Apify API rather than relying on a webhook the Actor doesn't emit.
Integrate this Actor and automate your workflow
LinkedIn Company URL - Mass Profile Finder & Employee List works with any language or tool that can call the Apify API — there is no separate signup flow or credential system beyond your Apify account token.
REST API with Python
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run_input = {"companyNames": ["Stripe", "Notion Labs", "OpenAI"],"fetchEmployees": True,"maxEmployeesPerCompany": 6,"titleFilter": ["Founder", "CEO", "Head of Sales"],}run = client.actor("<YOUR_USERNAME>/linkedin-company-url-mass-profile-finder-employee-list").call(run_input=run_input)for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["type"], item["mySearch"], item.get("linkedinUrl") or item.get("profileUrl"))
Scheduled monitoring uses Apify's native Schedules feature — set a cron expression on this Actor in Apify Console (or via the schedules API endpoint) and each run lands as a new, timestamped dataset you can pull with the same apify_client call above; the Actor itself does not push results to a webhook.
Is it legal to scrape LinkedIn company and employee data?
Scraping publicly accessible LinkedIn pages is generally lawful in most jurisdictions, and this Actor returns only what any logged-out visitor to a public company page or profile can already see — it never bypasses a login wall to reach private data. The two row types carry different legal weight: employee rows contain personal data (name, headline, location), so GDPR in the EU/UK and CCPA in California apply if you process EU or California residents' data, meaning you need a legitimate basis for processing it, should honor data-subject access and deletion requests, and should avoid retaining rows longer than your stated purpose requires. Company rows are business/public-record data, where LinkedIn's own Terms of Service and database-rights claims are the more relevant framing rather than privacy law. Scraping for one-off operational monitoring and scraping to build a training dataset carry different risk profiles — the latter draws far more scrutiny. Consult your legal team for commercial use cases involving bulk data storage.
❓ Frequently asked questions
Does this Actor require a LinkedIn login?
No. It runs fully logged-out by default. The optional sessionCookie (li_at) input only lifts employee-profile coverage; it is never required to resolve company pages.
Which regions can I search in?
Set region to us-en, uk-en, ca-en, au-en, in-en, or wt-wt (worldwide, no region bias). This controls the language/region of the underlying search, which affects titles like "Stripe - LinkedIn" versus a localized equivalent.
How does this Actor handle LinkedIn's anti-bot measures?
It impersonates a real Chrome browser at the HTTP layer, starts every run with no proxy, and automatically escalates one-way through a datacenter proxy and then a residential proxy the moment a request is throttled or blocked, retrying with exponential backoff and a fresh IP on each attempt. LinkedIn's permanent HTTP 999 guest block on a profile page is not retried — that profile is skipped and logged rather than hammered.
Does this Actor extract employee profiles, not just company pages?
Yes — employee data arrives as child rows with type: "employee" in the same dataset as the company rows, carrying fullName, headline, jobTitle, location, and profileUrl. It is absent (the row simply doesn't exist for that candidate) whenever LinkedIn's guest block prevented the profile from being read at all, and individual fields come back null when the page loaded but a specific field wasn't parseable.
How many results does this Actor return per query?
For companies: exactly one row per name you submit (or zero, if includeNotFound is off and no page was found) — the schema places no cap on how many company names you can list. For employees: up to maxEmployeesPerCompany per company, defaulting to 6, with a hard internal ceiling of 40 even when you set it to 0 for "unlimited."
How do I use this Actor to monitor a company's headcount over time?
Schedule a recurring run over the same companyNames list using Apify Schedules, then diff fullName/profileUrl sets per mySearch between consecutive runs to see who's new, and watch jobTitle/headline changes on names you already have to catch promotions and role moves.
Does this Actor work with Claude, ChatGPT, and AI agent frameworks?
It is callable as a standard HTTP endpoint through the Apify API by any agent framework that can issue a POST request and read JSON back — an agent resolves a company, receives the structured rows, and can ground its answer in the real linkedinUrl and employee fields instead of guessing.
Can I use this Actor without managing proxies or LinkedIn credentials?
Yes. Proxy escalation (direct → datacenter → residential) is handled automatically inside the Actor with no proxy configuration required to start, and the default run needs no LinkedIn account or cookie at all — sessionCookie is strictly optional.
How do I speed up a large run?
Raise maxConcurrency (default 10, up to 100) to process more companies in parallel — this only affects company-to-company parallelism, since employees within a single company are always fetched one at a time regardless of this setting. Pushing concurrency higher uses your proxy pool faster and increases how quickly the run escalates to residential proxy if LinkedIn starts throttling, so raise it gradually for very large company lists rather than jumping straight to 100.
How does this Actor compare to other LinkedIn company-URL scrapers?
As observed on their live Apify Store listings on 2026-07-26, Anchor's LinkedIn Company URL Finder and this Actor's own sibling linkedin-company-url-mass-profile-finder both return company rows only (mySearch, linkedinUrl, info, queryId) and, for people data, point you at a separate Actor. This Actor keeps the same company-resolution step and adds employee child rows — name, headline, job title, location, profile URL — in the same dataset, with no second Actor to chain.
What if a company name doesn't resolve to a LinkedIn page?
With includeNotFound on (the default), you still get a company row with linkedinUrl and info set to null, so your output count matches your input count 1-to-1. Turn it off to only receive rows for companies that were actually found.
Can I export the results as CSV or Excel, not just JSON?
Yes. This is a standard Apify dataset, so the Output tab lets you export to JSON, CSV, XLSX, HTML, XML, or RSS regardless of fetchEmployees or any other input setting — the row schema is identical across every export format.
What does the "Company Search Suffix" input actually do?
companySearchSuffix (default "linkedin company") is appended to each company name before it's searched, e.g. Stripe linkedin company, so the company's own LinkedIn page ranks first in the underlying search rather than a news article or an unrelated company with a similar name. Leave it on the default unless your target companies have unusual names that need a different bias phrase.
🔗 Related scrapers
If you need to go deeper on a specific LinkedIn entity once you have a company or a person, these Scrapier Actors pick up where this one leaves off:
- LinkedIn Career History Analyzer — turn a resolved profile URL into a structured work-history timeline.
- LinkedIn Phone & Company Enricher — enrich a profile or company with additional contact and firmographic data.
- LinkedIn Post Comments Scraper (Post Reactors) — pull the people who commented on or reacted to a specific post.
- LinkedIn Posting Cadence Scraper — track how often a company or profile posts, over time.
- LinkedIn Profile Phone Validator — validate phone numbers associated with a LinkedIn profile.
Each is a separate Apify Actor with its own input schema and pricing — chain them together in an Apify integration, a scheduled pipeline, or a simple script that passes this Actor's linkedinUrl and profileUrl output into the next one's input.
💬 Your feedback
Found a bug, or a field that looks wrong — a company that should have resolved, or an employee row that came back with a field it shouldn't have missed? Open an issue from the Actor's page in Apify Console so we can reproduce it, or leave a review — both help prioritize fixes and new capabilities for this Actor.