Contact Details Scraper: Emails, Phones & Socials avatar

Contact Details Scraper: Emails, Phones & Socials

Pricing

from $16.00 / 1,000 websites

Go to Apify Store
Contact Details Scraper: Emails, Phones & Socials

Contact Details Scraper: Emails, Phones & Socials

Email extractor and contact details scraper for leads: give company websites, get emails, phone numbers (E.164) and social media links (LinkedIn, X, Facebook, Instagram, YouTube, TikTok) from contact, about and legal pages, with source pages. Pay only for websites with contacts.

Pricing

from $16.00 / 1,000 websites

Rating

0.0

(0)

Developer

Zaiq

Zaiq

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

6 days ago

Last modified

Share

Give it a list of company websites and get their contact details back: email addresses, phone numbers, social media links (LinkedIn, X/Twitter, Facebook, Instagram, YouTube, TikTok and more), contact pages and the company's own schema.org data. One row per website, deduplicated, with the page each detail was found on. A contact details scraper and email extractor for lead lists, priced per website, and only for websites where an email or phone number was found.

What it does

For each website it reads the home page and then the pages most likely to list contacts: Contact, Legal notice (Impressum, Imprint, Mentions légales, Aviso legal), About, Team, Support, Locations, Terms, Privacy and Careers. It finds these pages from link text and addresses in about 25 languages, reads the best page of each kind first, and stops at 8 pages per website by default.

  • Emails from mailto: links, page text, Cloudflare-protected addresses, common disguises (
    name [at] company [dot] com
    , name(at)company.de, an @ hidden in a separate element) and schema.org. Image names such as logo@2x.png, error-tracker keys, placeholder and example addresses, and addresses inside elements marked hidden (a common spam trap) are dropped. Each address says whether it is on the website's own domain and whether it is a generic mailbox (info@, sales@, kontakt@) or looks like one person's.
  • Phone numbers from tel: links, WhatsApp links, schema.org and page text, checked with Google's phone number library and returned in E.164 (+442079460958), local and international format, with country and type (fixed line, mobile, toll-free ...). Numbers in text count only when they are labelled (Tel, Phone, Telefon, 電話, 대표번호 ...), written with a country code, or toll-free, so dates, VAT and registration numbers are not mistaken for phone numbers. Faxes are flagged.
  • The phone country comes from the website itself: its domain ending, its schema.org address, its own +xx numbers, its language and the countries it names. A number listed under a country's name in an office list ("Mexico 800 681 6929") is read for that country. You can also set one country for all websites.
  • Social profiles: LinkedIn company pages (and staff profiles, kept apart), X/Twitter, Facebook, Instagram, YouTube, TikTok, GitHub, Pinterest, WhatsApp and Telegram, normalised and deduplicated. Share buttons, single posts, videos and profiles that only appear in embedded customer posts are left out.
  • Contact pages and contact forms, the company name, and the schema.org Organization / LocalBusiness record (legal name, address, phones, emails, sameAs profiles, contact points).
  • JavaScript when needed: a page is loaded in a real browser only when its HTML is built by scripts, its menu is drawn by a script, or its addresses are written in by a script, and once more as a last try when nothing was found. At most two pages per website, at no extra cost.

Who uses it

  • Lead generation and sales prospecting: turn a list of company domains (from a CRM export, a directory or a Google Maps search) into emails, phone numbers and LinkedIn pages.
  • CRM enrichment and data cleaning: fill missing contact fields, check which websites still publish a contact.
  • Partnerships, outreach and PR: find the right mailbox (sales@, press@, partners@) rather than a generic form.
  • Market research: build lists of companies with their legal names, addresses and social presence.

Example

A test run on 4 October 2026 read 70 public websites of software, hosting and online-service companies in 22 countries, ten at a time, with the default settings:

ResultWebsites
At least one email or phone number (charged)61 of 70
Email address found56
Phone number found53
Social media profiles found63 (LinkedIn company page: 56)
schema.org organisation data52
No email or phone on the pages read (free)5
Bot wall on every try (free)4

Of the 66 websites that did not block the run, 61 (92%) returned an email or phone number. The run found 231 email addresses and 206 phone numbers; each was checked again against the page it was credited to, and all 437 were there. In a manual review, 227 of the 231 addresses were the company's own (or its group's or legal representative's); the other four came from a product demo picture and an AI assistant's address. A typical website took 5 seconds and 7 pages, with about 0.4 MB of traffic; 15 of the 70 needed a browser for at least one page. The 70 websites took just over a minute in all.

Input

{
"startUrls": [{ "url": "https://www.example.com" }],
"domains": ["example.org", "example.co.uk"],
"maxPagesPerSite": 8,
"renderMode": "auto",
"includeSocials": true,
"proxyConfiguration": { "useApifyProxy": true }
}
  • startUrls: website URLs. Paste a list, upload a text or CSV file, or link a Google Sheet.
  • domains: bare domains, one per line (example.org). Use either field, or both.
  • A deep address (https://example.com/contact) is read first, then the home page. Duplicates of the same website are read once; inputs that are not websites (an email address, localhost, a private IP) get a free row saying why.
  • maxPagesPerSite: pages per website including the home page (1 to 30, default 8). The price per website does not change.
  • pageTypes: which kinds of linked pages to read (contact, legal notice, about, team, support, locations, terms, privacy, careers). All by default.
  • renderMode: auto (default) uses a browser only where needed; never reads plain HTML only; always loads every page in a browser, which is slower and charged at the browser price.
  • defaultCountry: a two-letter country code for numbers written without a country code. Leave it empty to work it out per website.
  • includePeopleProfiles (off by default): also return staff LinkedIn profiles linked from team pages. These are personal data; turn it on only with a lawful basis.
  • onlyGenericEmails: keep only role mailboxes (info@, sales@, support@). sameDomainEmailsOnly: drop addresses at other domains. keepNoReplyEmails: keep noreply@ addresses (dropped by default).
  • proxyConfiguration: Apify's automatic (datacenter) proxy by default. Choose residential proxies for websites that block datacenter addresses (charged at the residential price).
  • respectRobotsTxt (default on), maxConcurrency (websites at once, default 10), maxTriesPerPage (default 3; a blocked or failed page is tried again from a new proxy address, free).

Output

One row per website. This row is from the test run, with the company's name, domain, numbers and profiles replaced and some list entries removed; the structure and the other values are as returned.

{
"domain": "example-hosting.co.uk",
"url": "https://example-hosting.co.uk/",
"status": "found",
"companyName": "Example Hosting Ltd",
"primaryEmail": "sales@example-hosting.co.uk",
"primaryPhone": "+442079460958",
"emails": [
{ "email": "sales@example-hosting.co.uk", "sameDomain": true, "generic": true, "noReply": false,
"source": "mailto", "sourceUrl": "https://www.example-hosting.co.uk/" },
{ "email": "help@example-hosting.co.uk", "sameDomain": true, "generic": true, "noReply": false,
"source": "mailto", "sourceUrl": "https://www.example-hosting.co.uk/" },
{ "email": "billing@example-hosting.co.uk", "sameDomain": true, "generic": true, "noReply": false,
"source": "mailto", "sourceUrl": "https://www.example-hosting.co.uk/" }
],
"phones": [
{ "e164": "+442079460958", "national": "020 7946 0958", "international": "+44 20 7946 0958", "country": "GB",
"type": "fixed_line", "extension": null, "fax": false, "source": "tel-link",
"sourceUrl": "https://www.example-hosting.co.uk/" },
{ "e164": "+448081570123", "national": "0808 157 0123", "international": "+44 808 157 0123", "country": "GB",
"type": "toll_free", "extension": null, "fax": false, "source": "tel-link",
"sourceUrl": "https://www.example-hosting.co.uk/" },
{ "e164": "+442079460959", "national": "020 7946 0959", "international": "+44 20 7946 0959", "country": "GB",
"type": "fixed_line", "extension": null, "fax": true, "source": "text",
"sourceUrl": "https://www.example-hosting.co.uk/contact/" }
],
"socials": {
"linkedin": ["https://www.linkedin.com/company/example-hosting"],
"linkedinPeople": [],
"x": ["https://x.com/examplehosting"],
"facebook": ["https://www.facebook.com/examplehosting"],
"instagram": ["https://www.instagram.com/examplehosting"],
"youtube": ["https://www.youtube.com/user/examplehosting"],
"tiktok": [], "github": [],
"pinterest": ["https://www.pinterest.com/examplehosting"],
"whatsapp": [], "telegram": []
},
"contactPages": ["https://www.example-hosting.co.uk/contact/"],
"contactFormPages": ["https://www.example-hosting.co.uk/contact/"],
"schemaOrg": {
"type": "Organization",
"name": "Example Hosting Ltd",
"url": "https://www.example-hosting.co.uk/",
"sameAs": ["https://www.facebook.com/examplehosting", "https://x.com/examplehosting"]
},
"finalUrl": "https://www.example-hosting.co.uk/",
"phoneRegion": "GB",
"phoneRegionSource": "international numbers on the site",
"pagesVisited": [
{ "url": "https://www.example-hosting.co.uk/", "kind": "home", "status": 200, "rendered": false },
{ "url": "https://www.example-hosting.co.uk/contact/", "kind": "contact", "status": 200, "rendered": false }
],
"errors": [],
"error": null,
"input": "example-hosting.co.uk",
"crawl": { "pages": 8, "renderedPages": 0, "seconds": 3.5, "kilobytes": 160 },
"crawledAt": "2026-10-04T14:43:48Z",
"charged": true
}
  • status: found (at least one email or phone, charged), no-email-or-phone, blocked, unreachable, robots-disallowed, invalid-input or error. Only found is charged; charged says whether the row was.
  • primaryEmail and primaryPhone: the best single contact for a CSV column (own domain and info@/contact@/sales@ first; faxes never).
  • error explains rows without contacts; errors lists pages that failed.
  • The Emails and Phones views of the dataset (and the output tab) give one row per address or number, ready for a spreadsheet.

Use it from code, automations and AI agents

  • API: run it and get the results in one call: POST https://api.apify.com/v2/acts/zaiq~contact-details-extractor/run-sync-get-dataset-items?token=YOUR_TOKEN with the input as JSON. The API tab on this page has ready-made Python, JavaScript and cURL examples.
  • Python (pip install apify-client):
from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("zaiq/contact-details-extractor").call(run_input={'startUrls': [{'url': 'https://www.hetzner.com'}, {'url': 'https://www.blacknight.com'}]})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)
  • No code: connect it to Google Sheets, Zapier, Make or n8n from the Integrations tab, schedule runs in Apify Console, and get a webhook when a run finishes.
  • AI agents (MCP): add it as a tool to Claude, Cursor or any MCP client through Apify's MCP server: https://mcp.apify.com?tools=zaiq/contact-details-extractor.

Pricing

Pay per event: you pay only for websites where at least one email address or phone number was found. Apify's platform usage is included.

EventPrice
Website with contacts$0.02 ($20 per 1,000 websites)
Website with contacts, read through residential proxies$0.04
Website with contacts, every page loaded in a browser (renderMode: always)$0.05

Plus Apify's standard run start fee. The price is per website however many pages are read. Free: websites with no email or phone number on the pages read (even if social profiles were found), unreachable websites, websites that block every try, pages not allowed by robots.txt, invalid inputs and every retry. Your spending limit for the run is respected: the run stops cleanly when it is reached, and websites still in progress are not charged.

Limits

  • It reads the home page and up to 30 linked pages per website (8 by default), not the whole website. Addresses that appear only deep in a blog or a help centre may be missed.
  • Some websites show a bot wall (a Cloudflare challenge, for example) to automated visitors. Those rows come back as blocked and cost nothing; residential proxies get through some of them. The Actor does not solve CAPTCHAs.
  • Addresses shown only as images, only after a click, or only through a contact form cannot be read. Numbers written in running text without a label, a country code or a toll-free prefix are skipped on purpose, to keep dates and registration numbers out.
  • In automatic mode a page is rendered only when it looks built by scripts or nothing was found. A number that a script draws in on a page whose HTML already lists an email address can be missed; renderMode: always reads it.
  • Emails are not verified by sending mail; they are the addresses the website publishes.
  • At most 100 emails, 50 phone numbers and 20 profiles per network are kept per website.
  • Privacy and lawful use: the Actor reads public company pages and is built for business contact details. Some results can still be personal data, for example an employee's name-based address or LinkedIn profile, and data protection laws such as the GDPR (EU and UK), POPIA (South Africa), CCPA (California) and anti-spam rules such as CAN-SPAM and PECR apply to how you store and use them. You are responsible for having a lawful basis and for honouring opt-outs. onlyGenericEmails keeps role mailboxes only, and staff LinkedIn profiles are off unless you turn them on. robots.txt is respected by default. Use it only on websites you may access, and follow their terms.

FAQ

Why is a website free with no contacts? The error field says why: no email or phone on the pages read, a bot wall, a domain that does not resolve, or robots.txt. Rows without contacts are never charged.

How do I get one row per email for my spreadsheet? Open the Emails view in the dataset (or the "Emails, one per row" link in the output tab) and export it as CSV or Excel. The Phones view does the same for numbers.

What does sameDomain mean? The address is at the website's own domain, or at the same name under another ending (acme.com for acme.de). Addresses at agencies, Gmail and other domains are kept but marked false and listed last; sameDomainEmailsOnly removes them.

Does it find personal emails? It returns the addresses a company publishes on its own pages. Addresses on legal and privacy pages that belong to other organisations (regulators, processors) are left out. Use onlyGenericEmails to keep role mailboxes only.

How are phone numbers formatted? Every number is validated and returned in E.164 (+442079460958 style), plus its local and international formats, country and type. Extensions are kept separately.

Which proxy should I use? The default automatic proxy works for most company websites. Switch to residential proxies (optionally with a country) if many rows come back as blocked.

Can I give it a list from a file? Yes: upload a text or CSV file, or link a Google Sheet or any text file in the Websites field. Every cell that looks like a website or a domain is used.