LinkedIn Profile Phone Number Scraper: Dedup & CSV Export
Pricing
from $3.99 / 1,000 results
LinkedIn Profile Phone Number Scraper: Dedup & CSV Export
LinkedIn Profile Phone Number Scraper — Scrape publicly available phone numbers from LinkedIn profiles, remove duplicate contacts, and export clean data to CSV. Build organized B2B lead lists for sales prospecting, outreach, recruitment, and contact research.
Pricing
from $3.99 / 1,000 results
Rating
0.0
(0)
Developer
Scrapio
Maintained by CommunityActor stats
0
Bookmarked
31
Total users
0
Monthly active users
2 days ago
Last modified
Categories
Share
LinkedIn Phone Number Scraper — Deduped Leads, Hits & Summaries
LinkedIn Phone Number Scraper searches Google for public LinkedIn results that expose a phone number, normalizes every number it finds to E.164, and then globally deduplicates the result across every keyword and URL you searched. Instead of a noisy hit log with the same contact repeated under five different job-title searches, you get one enriched row per unique phone number — with the keywords and LinkedIn URLs that led to it attached. Unlike scraping frameworks that return raw HTML, this Actor returns typed JSON, ready for a CRM import, a spreadsheet, or an LLM context window without any parsing.
The rest of this guide covers exactly what fields each output mode returns, the dedup key the Actor uses under the hood, and three concrete ways sales, research, and data teams put the deduped export to work.
What Does This LinkedIn Phone Number Scraper Do?
This Actor runs a targeted Google search — site:linkedin.com "<dial code>" "<keyword>" — for every keyword, username, or LinkedIn URL string you provide, then parses the results page for phone numbers that match your selected country's dial code. It does not log into LinkedIn, does not require a LinkedIn account or session cookie, and never touches LinkedIn's servers directly — every request goes to Google's search results page over Apify's GOOGLE_SERP proxy. Two output modes are available: a deduplicated "unique phone" export (default) or a raw "one row per hit" export.
- Searches Google for LinkedIn content matching your keywords, usernames, or profile URL strings
- Extracts and normalizes phone numbers to E.164 format using the selected country's dial code
- Filters out numbers that don't match the selected country's dial code
- Globally deduplicates phone numbers across every keyword and URL in the same run
- Tracks which keywords and which LinkedIn URLs each deduped number was found under
- Emits a run summary row with raw-hit count, unique-phone count, and a dedupe ratio
- Requires no LinkedIn login, cookie, or session — only a keyword list and a country
Features & Capabilities
Everything below is driven by what the Actor's source code actually does — no marketing filler, no invented benchmarks.
Core features
- Global E.164 dedup, not per-page dedup. Phone numbers are normalized (leading
00rewritten to+, non-digit characters stripped, missing country codes prefixed with the selected dial code) and then collapsed into one row per unique normalized number across the entire run, not just within one keyword's results. The exact dedup key is the normalized number re-stripped to digits-only and re-prefixed with+— two raw hits collapse into the same row only if their normalized digit strings are identical, regardless of formatting differences (spaces, dashes, or parentheses) in how the number originally appeared on the page. - Dial-code filtering at extraction time, not just display. A candidate number is only kept if, once normalized, it starts with the selected country's dial code — a French number surfacing on a page while
countryis set to"United Kingdom (+44)"is discarded before it ever reaches the output, rather than being labeled with the wrong country. - Enriched merge metadata on every deduped row:
foundUnderKeywords(every distinct keyword the number appeared under),sourceUrls(every distinct LinkedIn URL it was found on), andduplicateHitCount(how many raw hits collapsed into that row). - Two output modes, switchable per run via
outputFormat:unique_phones(deduped and enriched) orrows(one row per raw SERP hit, no merging). - Fail-safe empty handling. If a keyword returns three consecutive empty or failed search pages, the Actor stops that keyword and moves on — it never fabricates a placeholder row.
- Corroborated block detection. A Google "unusual traffic" or CAPTCHA phrase is only treated as a real block if the page also lacks a genuine result container (
<h3>,MjjYud,tF2Cxc,N54PNb,Gx5Zad) — this avoids the common false positive where defensive JS boilerplate appears on completely normal result pages. - Automatic proxy rotation on retry. Each failed or blocked request is retried up to 3 times with a fresh GOOGLE_SERP proxy URL and a randomized 1–2 second delay between requests, plus a 3–6 second cool-down between retries.
How this scraper compares to other LinkedIn phone number scrapers
| Feature | This Actor | api-empire/linkedin-profile-phone-number-scraper | scraper-engine/linkedin-profile-phone-number-scraper |
|---|---|---|---|
| Global cross-keyword dedup | Yes — normalized E.164 key, merge metadata attached | Not documented | Not documented |
| Country dial-code filtering | 194-country dropdown, dial code used to normalize and filter | Listing example uses "country": "Global" | Listing example uses "country": "Global" |
| Raw-hit vs. deduped output toggle | Yes — outputFormat parameter | Not documented | Not documented |
| Run summary with dedupe ratio | Yes — totalRawHits, uniquePhones, dedupeRatio | Not documented | Not documented |
| Pricing model | Pay per event (row_result) | FLAT_PRICE_PER_MONTH (as listed 2026-07-26) | FLAT_PRICE_PER_MONTH (as listed 2026-07-26) |
| Run summary row | totalRawHits, uniquePhones, duplicatesCollapsed, dedupeRatio on every run | Not documented | Not documented |
| Anti-block handling documented | Corroborated block detection, proxy rotation, jittered retries | Not documented | Not documented |
If your use case is feeding structured contact data to a CRM or an LLM agent, the dedup and merge-metadata rows are the decision-maker — reconciling the same lead found under six job-title searches by hand is the kind of error a script should not have to catch. Competitor claims above reflect only what is published on the cited listings; every other capability that isn't documented on their end is left blank rather than assumed absent.
When another tool might suit you better
If you already have a clean list of LinkedIn profile URLs and only need to enrich each one individually — rather than discovering leads through keyword search — a dedicated profile-URL enrichment tool (such as the weighty_marshmallow phone-enrichment Actor referenced in the competitor set) may be a better fit, since it's built around one-profile-in, one-result-out rather than keyword-driven discovery across many profiles at once. This Actor is built for the opposite direction: you supply search terms, not URLs, and it discovers which public LinkedIn results carry a phone number.
LinkedIn Phone Number Scraper within the Scrapio data stack
This Actor covers phone-number discovery via Google-indexed LinkedIn results. For tracking LinkedIn posts and hashtag mentions over time instead of contact data, use LinkedIn Post Keyword Monitor. For scoring a LinkedIn profile's credibility and pulling its recommendations rather than a phone number, use LinkedIn Profile Credibility Scraper. Together these cover discovery, monitoring, and profile-quality signals across LinkedIn without overlapping in what each one extracts.
Why do developers and data teams scrape LinkedIn for phone numbers?
🏢 Sales and business development teams
Sales teams feed a list of target job titles or company names as keywords, set country to the region they're prospecting in, and run with outputFormat: "unique_phones". The output lands as one row per unique contact number with title (the SERP result title, usually a name and role), url (the LinkedIn profile), and phone_number (E.164-normalized) ready to import straight into a CRM or dialer list — with duplicateHitCount flagging which leads showed up across multiple searches, a useful signal for how discoverable that contact is.
📊 AI training data and RAG indexing
The title and description fields carry unstructured, human-written text pulled straight from Google's rendering of the LinkedIn result — job titles, company names, and bio snippets — which makes them the fields worth indexing for RAG retrieval over a contact database. For training data, phone_number, dial_code, and country return as consistently typed strings across every record, and foundUnderKeywords/sourceUrls give you a ready-made provenance trail for each entry without extra normalization work.
📱 Competitive and market intelligence
Running the same keyword set on a schedule and tracking the dedupeRatio and uniquePhones fields on the summary row over time shows whether a given search term (a competitor's brand name, a job title tied to a hiring wave) is surfacing more or fewer discoverable contacts on Google over time — a rough proxy for how a company's LinkedIn footprint or hiring activity is changing.
🔬 Research and academic use
Because every record here comes from content Google has already publicly indexed, this Actor is suited to research into how much personal contact information is discoverable through public search — without needing a LinkedIn account, an internal API, or the platform's own search feature. It surfaces only what a search engine already shows any anonymous visitor.
🎥 Product and directory building
Teams building a lead-directory product, a contact-enrichment API, or a monitoring dashboard on top of LinkedIn data can call this Actor as a discovery layer: feed a list of target roles or company names, take the unique_phones output directly as the enrichment payload, and let the built-in dedup keep the downstream directory free of repeat contacts without writing a merge step of your own.
🍚 Input Parameters
All seven parameters below are read directly from the Actor's input schema, in schema order, with the same names, types, and defaults.
| Parameter | Required | Type | Description | Example value |
|---|---|---|---|---|
keywords | Yes | array of strings | A list of keywords, LinkedIn usernames, or profile URLs to search for. | ["founder", "ceo", "marketing director"] |
platform | No | string (enum: Linkedin) | Select platform. For now this Actor targets Linkedin via google.com SERP. Default: "Linkedin". | "Linkedin" |
country | Yes | string (enum, 194 country/dial-code entries) | Select a country to scrape related phone numbers. The dial code is used to normalize and filter phone numbers. Default: "United Kingdom (+44)". | "United Kingdom (+44)" |
maxPhoneNumbers | No | integer (min 1, max 10000) | Maximum number of phone numbers to collect per keyword. The scraper stops once this limit is reached for that keyword. Default: 20. | 25 |
engine | No | string (enum: legacy) | Choose scraping engine. Default: "legacy". | "legacy" |
proxyConfiguration | No | object (proxy editor) | Configure proxies for this Actor (Apify Proxy). The GOOGLE_SERP proxy group is enforced for Google search requests regardless of this setting. | {"useApifyProxy": true} |
outputFormat | No | string (enum: unique_phones, rows) | unique_phones (default) collapses duplicate phone numbers found across different keywords/URLs into one enriched row each. rows emits one row per raw SERP hit. Either way a final summary row reports totalRawHits, uniquePhones, and dedupeRatio. Default: "unique_phones". | "unique_phones" |
The country dropdown covers 194 territories, each stored as "Name (+dial code)" — for example "United States (+1)", "India (+91)", "Germany (+49)", "South Africa (+27)". The full list is visible in the Actor's input editor on the Apify Console.
⚠️ Two parameters don't behave quite as their description text implies. The engine field's description mentions a "cost-effective" option that uses residential proxies, but the schema currently only exposes the "legacy" enum value — every run uses the GOOGLE_SERP proxy group regardless of what engine is set to. Likewise, if you pass a custom apifyProxyGroups array inside proxyConfiguration, it is not read — only the useApifyProxy boolean is honored, and the GOOGLE_SERP group is always enforced for the search requests.
Example input
{"keywords": ["founder", "ceo", "marketing director"],"platform": "Linkedin","country": "United Kingdom (+44)","maxPhoneNumbers": 25,"engine": "legacy","proxyConfiguration": { "useApifyProxy": true },"outputFormat": "unique_phones"}
Supported input formats
Every entry in keywords — whether it reads as a plain search term, a LinkedIn username, or a full profile URL — is treated identically by the Actor: it's inserted verbatim, in quotes, into the Google query site:linkedin.com "<dial code>" "<keyword>". There is no separate URL-parsing path, so a username like "johnsmith" and a phrase like "marketing director" both work the same way — as a quoted search term Google matches against indexed LinkedIn pages.
Three real examples:
- Job-title discovery:
["founder", "co-founder", "managing director"]withcountry: "United States (+1)"— finds LinkedIn results mentioning a U.S. phone number alongside any of those titles. - Brand or company search:
["Acme Ltd", "Acme Corporation"]withcountry: "United Kingdom (+44)"— surfaces UK-numbered contacts tied to that company name. - Username lookup:
["johnsmith92"]withoutputFormat: "rows"— returns every raw SERP hit for that exact string without collapsing duplicates.
📦 Output Format
Every record is pushed to the Actor's default dataset as typed JSON. The dataset's default view surfaces 12 columns (recordType, platform, keyword, title, description, url, phone_number, country, dial_code, foundUnderKeywords, sourceUrls, duplicateHitCount) — but the rows pushed in unique_phones mode actually carry a 13th key, e164, that isn't part of that default view. All keys below are copied from the row-building code, not just the visible columns.
Output for unique phone leads (recordType: "unique_phone")
Pushed when outputFormat is "unique_phones" (the default). One row per unique E.164-normalized phone number, carrying every base field from the first raw hit that number was found on, plus dedup metadata:
{"recordType": "unique_phone","platform": "Linkedin.com","keyword": "founder","title": "John Smith - Founder & CEO - Acme Ltd | LinkedIn","description": "Founder and CEO of Acme Ltd, London. Reach me on +44 7911 123456 for partnership enquiries.","url": "https://www.linkedin.com/in/johnsmith/","phone_number": "+447911123456","country": "United Kingdom","dial_code": "+44","e164": "+447911123456","foundUnderKeywords": ["founder", "ceo"],"sourceUrls": ["https://www.linkedin.com/in/johnsmith/"],"duplicateHitCount": 2}
e164 is the exact dedup key described below, kept on the row for traceability even though it duplicates phone_number's normalized value. foundUnderKeywords and sourceUrls only grow past one entry when the same phone number surfaces under more than one keyword or URL in the same run; keyword, title, description, and url always reflect the first raw hit, not a merged value.
Output for raw SERP hits (recordType: "hit")
Pushed when outputFormat is "rows". One row per raw search hit, with no cross-hit merging:
{"recordType": "hit","platform": "Linkedin.com","keyword": "founder","title": "John Smith - Founder & CEO - Acme Ltd | LinkedIn","description": "Founder and CEO of Acme Ltd, London. Reach me on +44 7911 123456 for partnership enquiries.","url": "https://www.linkedin.com/in/johnsmith/","phone_number": "+447911123456","country": "United Kingdom","dial_code": "+44"}
unique_count is still computed honestly in this mode for the summary row below, even though the raw rows themselves aren't deduped.
Output for the run summary (recordType: "summary")
Exactly one summary row is pushed at the end of every run, regardless of outputFormat:
{"recordType": "summary","platform": "Linkedin.com","outputFormat": "unique_phones","totalRawHits": 40,"uniquePhones": 33,"duplicatesCollapsed": 7,"dedupeRatio": 0.825,"keywordsSearched": ["founder", "ceo", "marketing director"],"country": "United Kingdom","dial_code": "+44"}
dedupeRatio is uniquePhones / totalRawHits. This row is pushed without a charged event name, so it is not billed under the row_result pay-per-event — only unique_phone and hit rows are charged. To count billed rows programmatically, filter the dataset for recordType !== "summary".
Schema stability and export options
Field names are stable across runs — they come from the Actor's own row-building code, not from parsing LinkedIn's front end directly, since the actual scrape target is Google's search results page. The dataset supports Apify's standard export formats (CSV, JSON, Excel, XML, RSS) from the Console or via the API, and results can be fetched programmatically through the Apify API or apify-client SDKs in any language.
💡 LinkedIn Phone Number Scraper Strategy Guide
🎯 Strategy 1: Real-time enrichment pipeline
When a new lead lands in your CRM without a phone number, trigger a run with keywords set to the lead's name or company and country set to their region, outputFormat: "unique_phones". Read the resulting phone_number, title, and url fields back from the dataset via the Apify API and write them onto the CRM record. Because dedup runs globally within a single call, batching several leads' names into one keywords array in one run also collapses any contact that happens to surface under more than one of them.
🎯 Strategy 2: Scheduled monitoring and re-verification
Set up an Apify Schedule to re-run the same keywords/country combination on a recurring cadence. Compare the phone_number set in the new run's dataset against the previous run's dataset — a number that disappears may indicate the LinkedIn result was removed or de-indexed by Google; a number that's newly present may be a fresh lead worth acting on. The Actor itself has no built-in diffing, so this comparison happens outside the run, against two dataset exports.
🎯 Strategy 3: Bulk dataset build
For building a large deduped contact list in one pass, supply a long keywords array (role titles, company names, or usernames) in a single run with outputFormat: "unique_phones" and a maxPhoneNumbers value sized to how many hits you expect per keyword. Because dedup is global across the whole keywords list in that run, the exported dataset needs no further cleanup before a CSV export — the Actor has already collapsed cross-keyword duplicates for you. No concurrency limit is documented for this Actor beyond the per-keyword maxPhoneNumbers cap, so size the keywords list to the run duration you're comfortable with.
Strategy comparison at a glance
| Strategy | Best for | Run pattern | Output format |
|---|---|---|---|
| Real-time enrichment | Filling a missing phone number on an inbound lead or company record | One on-demand run per lead or small batch | unique_phones |
| Scheduled monitoring | Tracking whether a contact's number is still discoverable on Google over time | Apify Schedule, recurring run, diffed against the prior dataset | rows or unique_phones |
| Bulk dataset build | Building a large, pre-deduped contact list from many search terms at once | One large run, long keywords list | unique_phones, exported to CSV |
🌴 Related LinkedIn Scrapers & Tools
| Scraper | What it extracts |
|---|---|
| LinkedIn Post Keyword Monitor | Tracks LinkedIn posts matching keywords and hashtags over time — not profile contact data |
| LinkedIn Profile Credibility Scraper | Scores a LinkedIn profile's credibility and extracts recommendations — not phone numbers |
| Instagram Phone Lead Validator | The same per-keyword search-and-dedupe pattern applied to Instagram instead of LinkedIn |
How to integrate this scraper with your stack
LinkedIn Phone Number Scraper works with any language or tool that can call the Apify API — there is no separate signup flow or credential type beyond your Apify account token.
Python
from apify_client import ApifyClientimport csvclient = ApifyClient("<YOUR_APIFY_TOKEN>")run_input = {"keywords": ["founder", "ceo", "marketing director"],"platform": "Linkedin","country": "United Kingdom (+44)","maxPhoneNumbers": 25,"engine": "legacy","outputFormat": "unique_phones",}run = client.actor("<YOUR_USERNAME>/linkedin-profile-phone-deduper-exporter").call(run_input=run_input)with open("leads.csv", "w", newline="", encoding="utf-8") as f:writer = csv.writer(f)writer.writerow(["phone_number", "keyword", "title", "url", "duplicateHitCount"])for item in client.dataset(run["defaultDatasetId"]).iterate_items():if item.get("recordType") != "unique_phone":continuewriter.writerow([item.get("phone_number"), item.get("keyword"),item.get("title"), item.get("url"), item.get("duplicateHitCount"),])
Node.js
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const input = {keywords: ['founder', 'ceo', 'marketing director'],platform: 'Linkedin',country: 'United Kingdom (+44)',maxPhoneNumbers: 25,outputFormat: 'unique_phones',};const run = await client.actor('<YOUR_USERNAME>/linkedin-profile-phone-deduper-exporter').call(input);const { items } = await client.dataset(run.defaultDatasetId).listItems();const leads = items.filter((row) => row.recordType === 'unique_phone');console.log(`Collected ${leads.length} unique phone leads`);leads.forEach((row) => console.log(row.phone_number, row.foundUnderKeywords));
Async and scheduled pipelines
For large keywords lists, start the run asynchronously via the Apify API's run-async endpoint and poll the run status or the dataset item count rather than holding a connection open — this suits large batches where the run may take longer than a typical HTTP timeout. For smaller, latency-sensitive lookups, the run-sync-get-dataset-items endpoint blocks until the run finishes and returns the dataset directly in the response, useful for a single-lead enrichment call. Apify Schedules can trigger this Actor on a recurring cadence for the monitoring pattern in Strategy 2, and Apify Webhooks can notify an external endpoint the moment a run finishes, instead of polling for completion.
Who Needs This LinkedIn Phone Number Scraper? (Use Cases & Industries)
🏢 Sales and business development
A B2B sales team searching ["procurement manager", "head of purchasing"] against country: "Germany (+49)" gets back a deduped list of phone_number and url pairs ready to load into an outbound dialer, with duplicateHitCount flagging the contacts that surfaced repeatedly across job-title variants — often a signal of a more prominent public profile.
📊 AI and RAG engineering teams
Teams building a lead-enrichment agent can feed the title and description text fields straight into a RAG index, and the phone_number/foundUnderKeywords/sourceUrls fields as structured metadata alongside it — every field arrives as a typed JSON primitive with no HTML to strip first.
📱 Recruiters and market researchers
Recruiters running the same company-name keyword across multiple countries can see which regional offices have publicly discoverable contacts indexed by Google, using the country and dial_code fields to segment results by market.
🔬 Researchers
Academic and market researchers studying how much personal contact information is exposed through public search engines can use this Actor's dedupeRatio and duplicateHitCount fields as a rough measure of contact redundancy across keyword variants, working only with data Google already surfaces publicly.
🎥 Directory and enrichment product builders
Teams shipping a lead-enrichment API or a contact directory on top of LinkedIn data can point the unique_phones output straight at their ingestion pipeline — the Actor's own dedup and merge metadata (foundUnderKeywords, sourceUrls, duplicateHitCount) remove the need to build a separate reconciliation step before the data reaches paying users.
Is it legal to scrape LinkedIn for phone numbers?
Scraping publicly accessible web data is generally lawful in the United States — in hiQ Labs, Inc. v. LinkedIn Corp., 938 F.3d 985 (9th Cir. 2019), the Ninth Circuit held that accessing publicly available LinkedIn profile data does not violate the Computer Fraud and Abuse Act. That case addressed unauthorized-access law, not LinkedIn's own Terms of Service — scraping in violation of a platform's ToS can still expose you to civil claims (breach of contract, not criminal liability) independent of that ruling.
Because this Actor's output includes phone numbers and names tied to identifiable individuals, it does return personal data under data protection frameworks like GDPR and CCPA. Collecting it does not itself violate those laws, but storing, processing, or using it for direct marketing generally requires a lawful basis, and unsolicited commercial contact is separately regulated in many jurisdictions (for example under GDPR, PECR in the UK, or TCPA in the US).
LinkedIn Phone Number Scraper returns only publicly accessible data surfaced by Google's own search index. What you do with that data is your responsibility — consult legal counsel before any commercial use involving personal data.
❓ Frequently asked questions
Does this scraper work without a LinkedIn account?
Yes. It never logs into LinkedIn or opens a LinkedIn session — every request goes to Google's search results page over the GOOGLE_SERP proxy group, filtered to results whose URL contains linkedin.com. No LinkedIn credentials of any kind are read from the input schema.
How does this scraper handle Google's anti-scraping measures?
It rotates a randomized user agent and Accept-Language header on every request, waits 1–2 seconds before each request and 3–6 seconds between retries, and retries up to 3 times with a freshly rotated GOOGLE_SERP proxy URL on a detected block or network error. A response is only treated as blocked if it carries a hard status code (429/503/4xx), redirects to a /sorry/ URL, or shows a block phrase and lacks any genuine result container — this last check avoids misreading normal result pages as blocked.
Can I run this at scale without getting blocked?
The Actor is designed to keep going across a long keywords list rather than stop at the first block — if a single keyword hits 3 consecutive empty or failed pages, it stops that keyword and moves to the next one rather than failing the whole run. No uptime or block-rate figure is published for this Actor.
How fresh is the data this scraper returns?
Every run performs a live Google search at run time — there is no caching layer in the source code. Results reflect whatever Google's index shows for that query at the moment the run executes.
Which fields work best for AI training and RAG indexing?
For RAG retrieval, index title and description — the free-text fields carrying a name, role, and bio snippet as rendered by Google. For training data, phone_number, country, and dial_code are the most consistently structured fields across every record; all fields return as typed JSON strings, arrays, or numbers requiring no HTML parsing or normalization before use.
What happens to the personal data this scraper returns?
The Actor returns only publicly indexed data — it doesn't store, contact, or otherwise process the individuals whose numbers appear in the output. Lawful basis for storing, using, or contacting anyone found in the results sits with you as the operator of the run, under whichever data protection law applies in your jurisdiction.
Does this scraper work with Claude, ChatGPT, and other AI agent tools?
It has no dedicated MCP server, so it isn't registered as a tool inside an MCP-based agent client today. Any agent framework that can call the Apify API — including custom tool-use setups built on Claude or GPT models — can trigger a run and read back the resulting dataset as typed JSON, with no HTML parsing step required before passing results into a context window.
What's the difference between the unique_phones and rows output modes?
unique_phones (the default) collapses every raw hit for the same normalized phone number into a single row per number, wherever in the keywords list it turned up, and attaches foundUnderKeywords, sourceUrls, and duplicateHitCount to that row. rows skips the merge step entirely and pushes one row per raw SERP hit — useful if you want to see every individual search result that mentioned a number, including repeats, rather than a cleaned contact list. Both modes push the same final summary row reporting the totals either way.
How does this scraper compare to other LinkedIn phone number scrapers?
As observed on their Apify Store listings on 2026-07-26, both api-empire/linkedin-profile-phone-number-scraper and scraper-engine/linkedin-profile-phone-number-scraper document a flat example input using "country": "Global" and describe dial-code detection as "Auto-detected," without documenting cross-keyword deduplication or a run summary. This Actor documents an explicit 194-entry country dropdown used to filter results, a global E.164 dedup pass with merge metadata, and a summary row reporting the dedupe ratio. Where those competitors may be a better fit is if a simpler flat-rate monthly plan matters more to you than pay-per-result pricing — both list FLAT_PRICE_PER_MONTH pricing, versus this Actor's pay-per-event model.
ℹ️ Disclaimer
LinkedIn Phone Number Scraper extracts only publicly available data surfaced by Google's search index for LinkedIn results. This tool is intended for lawful use cases only. Users are responsible for complying with LinkedIn's and Google's terms of service, and with applicable data protection laws in their jurisdiction, particularly where the output is used for direct marketing or unsolicited contact.