Bulk Website Contact Extractor – Emails, Phones & Socials
Pricing
from $5.00 / 1,000 result founds
Bulk Website Contact Extractor – Emails, Phones & Socials
Bulk-crawl any list of websites and extract emails, phone numbers, WhatsApp links, and social profiles $5.00/1K. MCP/API-ready.
Pricing
from $5.00 / 1,000 result founds
Rating
0.0
(0)
Developer
Khadin Akbar
Maintained by CommunityActor stats
2
Bookmarked
170
Total users
16
Monthly active users
9 days ago
Last modified
Categories
Share
Bulk Website Contact Extractor is an Apify Actor for users who already have a list of direct website URLs and want one structured contact record per URL. It accepts startUrls, crawls each URL independently, and returns fields such as emails, phones, whatsapp_links, social_links, company_name, lead_score, contact_page_url, and pages_crawled. The output is a CRM-ready dataset for lead enrichment, outreach preparation, and contact list review. This Actor is also usable through Apify MCP.
Best fit and connected workflows
This Actor fits workflows that begin with known websites rather than search queries. It routes naturally from spreadsheet exports, CRM domain lists, prospect lists, and other URL collections into one record per site.
It is a strong match when you want to:
- enrich company websites with public contact details,
- separate role inboxes and personal inboxes,
- collect phone numbers, WhatsApp links, and social profile URLs in one pass,
- sort records by
lead_score, - move structured records into Apify platform automations or Apify MCP workflows.
If your starting point is a direct website URL list, this Actor provides a focused crawl and one output record for each processed URL.
Practical scenario
Maya, a sales operations specialist, has a spreadsheet of company websites from a conference list. She sends those URLs in startUrls and keeps followContactPages enabled. The Actor returns records with emails, phones, social_links.linkedin, whatsapp_links, lead_score, and contact_page_url.
Maya uses lead_score to sort the list. Records with A include both email and phone, while B and C show partial contact coverage. She then imports the dataset into her CRM and starts with the records that already include a public email address and a phone number.
Input fields
| Field | Type | Required | Purpose |
|---|---|---|---|
startUrls | array | Yes | Direct website URLs to crawl. Accepts plain URL strings or objects with a url key. |
maxPagesPerDomain | integer | No | Maximum pages to visit per input URL. The crawler prioritizes /contact, /about, /team, and /imprint before general pages. Default: 6. |
maxResults | integer | No | Maximum number of input URLs to process. Set to 0 to process all input URLs. Default: 1000. |
followContactPages | boolean | No | When enabled, the crawler follows contact, about, team, imprint, support, and equivalent multilingual pages before extracting. Default: true. |
proxyConfiguration | object | No | HTTP proxy settings. Use the default Apify datacenter proxies for most sites. |
Focused JSON input example
{"startUrls": [{ "url": "https://apify.com" },{ "url": "https://crawlee.dev" }],"maxPagesPerDomain": 3,"maxResults": 2,"followContactPages": true}
Output fields
One record is produced per input URL. The dataset schema includes the following fields.
| Field | Type | Purpose |
|---|---|---|
source_url | string | Original input URL that was crawled. |
domain | string | Cleaned hostname with www. removed. |
company_name | string or null | Business name extracted from site metadata, schema, footer copyright, or page title. |
page_title | string or null | Title of the first crawled page. |
emails | array | All unique email addresses found on the crawled pages. |
emails_personal | array | Individually owned email addresses. |
emails_generic | array | Role or team inboxes such as info@, hello@, or sales@. |
phones | array | All unique phone numbers found on the crawled pages. |
address | string or null | First physical address found on the site. |
social_links | object | Social profile URLs for supported platforms such as LinkedIn, Twitter/X, Facebook, Instagram, YouTube, TikTok, GitHub, Pinterest, Snapchat, Threads, and Telegram. |
whatsapp_links | array | Direct WhatsApp contact links found on the site. |
lead_score | string | A, B, C, or D based on the contact data found. |
contact_page_url | string or null | First crawled page that yielded contact data. |
pages_crawled | integer | Number of pages visited for the domain. |
scraped_at | string | ISO 8601 timestamp for the record. |
Illustrative output record
{"source_url": "https://acme.com","domain": "acme.com","company_name": "ACME Corp","page_title": "ACME Corp - Contact Us","emails": ["hello@acme.com", "sales@acme.com"],"emails_personal": ["john.doe@acme.com"],"emails_generic": ["hello@acme.com", "sales@acme.com"],"phones": ["+1-800-555-0100"],"address": "123 Main St, Springfield, IL 62701","social_links": {"linkedin": "https://linkedin.com/company/acme-corp","twitter": "https://x.com/acmecorp","facebook": null,"instagram": null,"youtube": null,"tiktok": null,"github": null,"pinterest": null,"snapchat": null,"threads": null,"telegram": null},"whatsapp_links": ["https://wa.me/15551234567"],"lead_score": "A","contact_page_url": "https://acme.com/contact","pages_crawled": 4,"scraped_at": "2026-03-30T12:00:00.000Z"}
How it works
The Actor processes each input URL as an independent crawl. It prioritizes contact-focused pages such as /contact, /about, /team, and /imprint, and can also follow equivalent multilingual pages when followContactPages is enabled.
It extracts public emails, phone numbers, WhatsApp links, social profile URLs, and physical address data from the crawled pages. The output schema is aligned with the dataset record structure, and the run also writes terminal data to the key-value store through runOutput and runSummary for automation and agent workflows.
The primary charged event is Result found, which is charged per domain where contact info was extracted. There is also an Actor Start event charged when the Actor begins running.
Evergreen pricing
This Actor uses pay per event pricing plus Apify platform usage. The primary event is Result found, charged per domain where contact info is extracted. The Actor Start event is also charged when the Actor begins, based on Actor memory.
For example, if a execution produces ten extracted-domain events, the pricing is driven by those ten Result found events together with the Actor Start charge and any Apify platform usage that applies to the run. For the current pricing details, open the live Pricing tab in Apify Console.
Use with AI agents (MCP)
This Actor is an Apify Actor usable through Apify MCP. It accepts a list of website URLs, crawls each URL independently, and returns structured contact records that AI agents can parse for outreach, enrichment, or routing tasks.
The exact Actor identity is khadinakbar/bulk-website-contact-extractor.
Extract contact details from this list of company websites. Return emails, phone numbers, WhatsApp links, social profiles, lead scores, and the source URL for each record. Keep the output grouped one record per input URL.
The output can be interpreted record by record. source_url identifies the website that was processed, contact_page_url shows the page that yielded contact data when available, and pages_crawled shows how much of the site was visited for that record. The output is scoped to the submitted URLs, so an AI agent can map each record back to the original input list. Pagination is reflected in the dataset output when the input list is large enough to span multiple result pages. Cost guidance is event-based: each extracted domain contributes a Result found event, and the Actor Start event also applies.
Apify API example
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({token: process.env.APIFY_TOKEN,});const run = await client.actor('khadinakbar/bulk-website-contact-extractor').call({startUrls: [{ url: 'https://apify.com' },{ url: 'https://crawlee.dev' }],maxPagesPerDomain: 3,maxResults: 2,followContactPages: true});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
Python
from apify_client import ApifyClientimport osclient = ApifyClient(os.environ["APIFY_TOKEN"])run = client.actor("khadinakbar/bulk-website-contact-extractor").call(run_input={"startUrls": [{"url": "https://apify.com"},{"url": "https://crawlee.dev"},],"maxPagesPerDomain": 3,"maxResults": 2,"followContactPages": True,})items = list(client.dataset(run["defaultDatasetId"]).iterate_items())for item in items:print(item["domain"], item["lead_score"], item["emails"])
Best results and outcome guidance
Use direct website URLs in startUrls. This Actor is designed for lists of domains and website URLs, not search queries.
Keep followContactPages enabled when the goal is email and phone discovery. The crawl order prioritizes contact-oriented pages before broader site pages, which fits most enrichment workflows.
Use maxPagesPerDomain to shape coverage. A value of 1 focuses on the homepage, while higher values let the Actor visit more pages per domain.
Use maxResults when you want to process only part of a larger URL list. Set it to 0 when the full list should be processed.
Review lead_score alongside emails, phones, and contact_page_url to decide which records move first into outreach or CRM import.
Continue the workflow
- Then use Clutch Agencies Scraper — Ratings, Services & Pricing to extend Bulk Website Contact Extractor – Emails, Phones & Socials with a neighboring local-business research source when the brief calls for Clutch data.
- Then use BizBuySell Scraper — Business Listings & Financials to extend Bulk Website Contact Extractor – Emails, Phones & Socials with a neighboring local-business research source when the brief calls for Bizbuysell data.
Design note
I found that the live dataset schema includes company_name, emails_personal, emails_generic, address, and contact_page_url, which makes the output more specific than the earlier record shape shown in the current README.
FAQ
What kind of input fits this workflow?
A list of direct website URLs in startUrls. Each URL is crawled independently and becomes one output record.
How many records does one input URL produce?
One record per input URL.
Which pages does the crawl prioritize?
The crawler prioritizes /contact, /about, /team, and /imprint, and it can also follow equivalent contact-oriented pages when followContactPages is enabled.
How should I read the lead score?
A means email and phone were found, B means email only, C means phone only, and D means no public contact info was found in the crawled pages.
Can this Actor be used from Apify MCP?
Yes. It is an Apify Actor usable through Apify MCP, and the output is structured for agent-driven workflows.
What should I use if I need only part of a large URL list?
Use maxResults to cap the number of input URLs processed in the run.
Responsible use
Use this Actor on publicly accessible websites and follow applicable site terms, privacy requirements, and internal data handling policies. Review the extracted contact data before sending outreach, and store or route it according to your organization’s compliance rules.