Website Contact Scraper: Emails, Phones & Socials, Fixed Price
Pricing
from $10.00 / 1,000 website with results
Website Contact Scraper: Emails, Phones & Socials, Fixed Price
Contact info scraper alternative: a fixed price per website and a hard page cap, so no runaway crawls. For a list of websites, get emails (role inboxes flagged), E.164 phones, LinkedIn, X, Facebook, Instagram, YouTube, TikTok, contact form and address. Export to Google Sheets. Empty sites are free.
Pricing
from $10.00 / 1,000 website with results
Rating
0.0
(0)
Developer
Adrian Voss
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
Website Contact Scraper: Emails, Phones & Socials, Fixed Price per Site
One website in, one row out, one flat price, and no runaway crawls. Give it a list of websites and get back, per site: every public email (with shared inboxes like info@ and sales@ flagged), phone numbers in international E.164 format, the LinkedIn company page, X, Facebook, Instagram, YouTube and TikTok profiles, the contact form page and the postal address. Ready to export to Google Sheets, a CRM or Clay.
It is a contact info scraper alternative built around one complaint about the popular ones: you pay per page crawled, and a crawl that wanders into a blog or a shop can cost fifty times what you expected. Here the price is per site, whatever the site's size, and every site has a hard page cap (8 by default, 20 at most). A site where nothing is found is free.
Who it's for
- Sales and lead-gen teams enriching a list of websites (from a trade-show list, Google Maps export or CRM) with a general inbox, phone number and LinkedIn page before outreach.
- Agencies and freelancers building prospect lists for clients who need a predictable bill: 1,000 sites costs the same whether they are one-pagers or 10,000-page corporate sites.
- Clay, n8n and Make users who want one clean row per domain, flat columns (
primaryEmail,primaryPhone,linkedinUrl) that map straight into a table. - Researchers and data teams who need the legal-notice address of European companies (the German/Austrian/Swiss Impressum, French mentions légales) without reading each site.
Why this one
- Fixed price per website. One charge per site with results, whether it took 1 page or 20. A site that returns nothing, can't be reached or blocks the request costs nothing.
- No runaway crawls. It reads the homepage plus only the links that look like contact
pages: contact, kontakt, about, team, impressum, imprint, legal, mentions légales, support,
privacy. Blog posts, product pages and shops are never opened.
maxPagesPerSiteis a hard cap. - Emails you can use. Deduplicated, lower-cased, each with the page it was found on
(
sourcePage),isRoleAddressfor shared inboxes andonSiteDomainfor addresses on the company's own domain. Cloudflare-protected emails ([email protected]) and simplename [at] company [dot] comforms are decoded. Placeholders likename@company.comare dropped. - Phones in E.164.
+4998315050, not "09831 505-0". Numbers without a country prefix are read using the site's country (from its address, its .de/.fr/.co.uk domain, or its page language). Fax numbers are left out. - Respects robots.txt. robots.txt is read before any page, and disallowed pages are skipped
(and counted in
pagesSkippedByRobots). - Plain HTTP, no browser. Fast and cheap. The trade-off: contact details that only appear after JavaScript runs are not seen (see FAQ).
Price
- Website with results: $20 per 1,000 websites
Plus a $0.00005 start fee per run. Each event above is billed independently, only when it actually returns data — misses (found:false) are never charged.
The price per site does not depend on maxPagesPerSite: raising the cap to 20 reads more pages
for the same charge.
How to use
- In the Apify Console. Open the actor page and click Start — the
websitesfield is already pre-filled with a working example. Results land in the run's dataset as soon as each item is found. - Via the API. Call it directly with a POST request — no Console needed once you have an API token:
curl "https://api.apify.com/v2/acts/accountable_eel~website-contact-extractor/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \-X POST \-H "Content-Type: application/json" \-d '{"websites":["hetzner.com","fastly.com"]}'
- On a schedule. Save this actor as an Apify Task with the input you want, then add a Schedule (hourly, daily, weekly) so it runs on its own — no server of your own required.
For a list of websites in Google Sheets: paste the domain column into Websites (one per
line; acme.com, www.acme.com and full URLs all work), run, then export the dataset as CSV or
connect the Google Sheets integration. Use the flat columns primaryEmail, emailsText,
primaryPhone, phonesText, linkedinUrl and addressText: one cell each, no nested JSON.
Input
{"websites": ["hetzner.com","fastly.com"]}
One website per line: acme.com, www.acme.com or https://acme.com/en/ all work. Each site is read as the homepage plus only its contact-looking pages (contact, impressum, about, team, legal, support, privacy), capped by 'Max pages per site' below. One flat price per site with results; a site where nothing is found is free. Accepted formats: hetzner.com, www.fastly.com, https://earlydesigneducation.gsd.harvard.edu/.
Output
One row per website. A site with results looks like this (trimmed):
{"query": "https://hetzner.com/","found": true,"domain": "hetzner.com","website": "https://www.hetzner.com/","primaryEmail": "info@hetzner.com","emailsText": "info@hetzner.com, tco@hetzner.com, dsa-authorities@hetzner.com","emails": [{ "email": "info@hetzner.com", "isRoleAddress": true, "onSiteDomain": true, "sourcePage": "https://www.hetzner.com/legal/legal-notice/" }],"primaryPhone": "+4998315050","phones": [{ "number": "+49 9831 505-0", "e164": "+4998315050", "country": "DE", "sourcePage": "https://www.hetzner.com/legal/legal-notice/" }],"linkedinUrl": "https://www.linkedin.com/company/hetzner-online","xUrl": "https://x.com/Hetzner_Online","facebookUrl": "https://www.facebook.com/hetzner.de","instagramUrl": "https://www.instagram.com/hetzner.online","youtubeUrl": "https://www.youtube.com/user/HetznerOnline","contactFormUrl": null,"addressText": "Industriestr. 25, 91710 Gunzenhausen, DE","address": { "streetAddress": "Industriestr. 25", "postalCode": "91710", "addressLocality": "Gunzenhausen", "addressCountry": "DE", "source": "impressum" },"pagesFetched": 5,"pageCapReached": true}
| query | found | status | domain | website | primaryEmail | emailsText | emails | emailCount | primaryPhone | phonesText | phones | phoneCount | phoneCountry | linkedinUrl | xUrl | facebookUrl | instagramUrl | youtubeUrl | tiktokUrl | otherSocialUrls | contactFormUrl | addressText | address | pagesFetched | pagesRead | pagesSkippedByRobots | pageCapReached | scrapedAt |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| hetzner.com | true | OK | <all emails (comma-separated)> | <emails (with source page)> | <all phones (comma-separated)> | <phones (with source page)> | <x (twitter)> | <postal address (parts)> | <pages skipped (robots.txt)> | 1970-01-01T00:00:00.000Z |
A site with nothing found, an unreachable site, or one whose robots.txt disallows it comes back as
a row with "found": false, a status (NOT_FOUND, BLOCKED, REQUEST_FAILED, BAD_FORMAT)
and a plain-English message. Those rows are never charged. Turn on "Only return found results"
to hide them.
Use it from Clay, n8n, Make, or an AI agent
This actor runs synchronously over plain HTTP — call it directly from a script, a workflow tool, or an AI agent, no Apify Console needed once you have an API token.
curl "https://api.apify.com/v2/acts/accountable_eel~website-contact-extractor/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \-X POST \-H "Content-Type: application/json" \-d '{"websites":["hetzner.com","fastly.com"]}'
n8n. Add an HTTP Request node: Method POST, URL https://api.apify.com/v2/acts/accountable_eel~website-contact-extractor/run-sync-get-dataset-items?token=<YOUR_TOKEN>, Body Content Type JSON, JSON Body {"websites":["hetzner.com","fastly.com"]} (swap in an expression from an earlier node for a real value).
Clay. Add an "HTTP API" column: Method POST, URL https://api.apify.com/v2/acts/accountable_eel~website-contact-extractor/run-sync-get-dataset-items?token=<YOUR_TOKEN>, Body {"websites":["{{website}}"]}, mapping the row's website into the websites array.
MCP. In Claude, Cursor, or any MCP client with the Apify MCP server, ask for "Website Contact Scraper: Emails & Phones, Fixed Price" — the agent will find and run this actor.
vs. alternatives
| What it costs | What you get | Trade-off | |
|---|---|---|---|
| This actor | $20 per 1,000 websites with results (less on paid plans), nothing for sites with no results | Emails with source page and role flag, E.164 phones, 6 social networks, contact form, postal address, up to 20 contact pages per site | Plain HTTP: details that only render with JavaScript are missed |
| Popular contact detail scrapers on the Apify Store | Per page crawled: about $2 per 1,000 pages on the free plan, so an 8-page site is ~$0.016 and a deep crawl much more | Crawls to a chosen depth, optional browser rendering, paid lead enrichment add-ons | The bill depends on how big each site is; a missing depth limit is the classic surprise |
| Email finder tools (Hunter-style) | Monthly subscription or credits | Guessed and verified personal work emails | Guesses rather than what the site publishes; no phones, socials or address |
| Doing it by hand | Your time | Exactly what you look for | Minutes per site |
Store figures as of September 2026.
Data & privacy
This actor reads only public pages a visitor can open without logging in, and it honours each site's robots.txt. It returns the contact details the website itself publishes. It does not guess email addresses, look anyone up in third-party databases or enrich people with other sources. Some sites publish named staff emails and phone numbers; those are personal data under the GDPR and similar laws, so make sure you have a lawful basis (for example legitimate interest for B2B outreach, with an opt-out) before you use them, and follow the anti-spam rules where you send.
FAQ
How is "fixed price per site" different from per-result pricing? You pay one site event per website that returned at least one email, phone, social profile, contact form or address, however many pages were read and however many emails it had. Sites with nothing, unreachable sites and blocked sites are free.
What does maxPagesPerSite do, and does it change the price?
It is the most pages that will ever be fetched for one site, homepage included (1 to 20, default
8). It does not change the price. Most sites have 2 to 6 contact-looking pages, so the default
rarely bites. If pageCapReached is true, there were more such pages than your cap.
Which pages does it read?
The homepage (or the URL you gave), then links on it whose address or text looks like a contact
page, in this order: contact, legal notice / impressum, about / team, support, privacy. Only the
same host (www and the bare domain count as one); turn on "Follow links to subdomains" to include
e.g. support.acme.com. If the homepage has no such links (a site whose menu is built by
JavaScript), it tries /contact and /about (or /impressum on .de/.at/.ch domains).
Why is an email or phone I can see in my browser missing? Either it is on a page the crawler didn't open (raise the cap), or the site draws it with JavaScript, which a plain HTTP reader never sees. Emails shown only as an image are also missed.
Does it guess emails like firstname.lastname@? No. It returns only what the site publishes. To guess and check a person's work email from their name and the company domain, use Email Finder by Name and Domain.
What is isRoleAddress?
true for shared inboxes (info@, sales@, support@, contact@, hello@, kontakt@, press@ and
similar), false for addresses that look like a person's. Good for sorting a general inbox from
a named contact.
Why is e164 empty for some phone numbers?
The number was written without a country code and the site's country couldn't be told from its
address, domain or page language. number keeps it exactly as written.
Does it respect robots.txt?
Yes. robots.txt is read first; a site that disallows its homepage is not crawled at all (a free
BLOCKED row), and disallowed contact pages are skipped.
Can an AI agent call this? Yes, through the Apify MCP server or the API call shown above. Ask for "Website Contact Scraper: Emails, Phones & Socials".
Related actors
- Email Finder by Name and Domain: the company's email format and a ranked guess for a named person.
- Company Domain Enrichment: DNS, email provider, tech stack, registration and hiring signals for the same list of domains.
- Email Deliverability Check: check the emails this actor found for a mail route, disposable domains and catch-all.
- JSON-LD Structured Data Lookup: all schema.org data a page publishes.