Verified Website Contact Finder πŸ“§ No Placeholder Emails avatar

Verified Website Contact Finder πŸ“§ No Placeholder Emails

Pricing

from $10.00 / 1,000 domain enricheds

Go to Apify Store
Verified Website Contact Finder πŸ“§ No Placeholder Emails

Verified Website Contact Finder πŸ“§ No Placeholder Emails

Find real company emails, phone numbers and social profiles from any website. Pass domains or URLs; role and personal emails are returned separately, and placeholder addresses other scrapers return are filtered out. Bulk domains per run, export as JSON or CSV.

Pricing

from $10.00 / 1,000 domain enricheds

Rating

0.0

(0)

Developer

Yaniv van der Stigchel

Yaniv van der Stigchel

Maintained by Community

Actor stats

1

Bookmarked

2

Total users

1

Monthly active users

6 hours ago

Last modified

Share

Website Contact Finder β€” real contacts, not placeholders

Extract company emails, phone numbers and social profiles from any website. Every address is labelled and filtered, so you get contacts you can actually use.

What it does

  • Extract emails from a list of websites
  • Find company contact details in bulk
  • Get emails and phone numbers from domains
  • Enrich a domain list with contact info
  • Scrape contact pages and Impressum details

The problem it solves

Most contact scrapers return whatever looks like an email address. Tested against real company homepages, that includes:

AddressWhere it came from
damian.michelfelder@example.comStripe's documentation samples
billing@example.comStripe's docs
sara.baker@acme.comMollie's marketing mockup
zoya@lumos.comMollie's mockup, invented brand
logo@2x.pngan image filename

None of those are contacts. A scraper that returns them hands you a list that looks like data and is not. This one filters them out.

Every address is labelled

FieldMeaning
type: "role"info@, sales@, support@ β€” a company contact point
type: "personal"an individual's address
confidence: "high"role address on the company's own domain
confidence: "medium"personal address on the company's own domain
confidence: "low"address on a different domain
sourcethe exact page it was found on

Personal addresses are off by default. Role addresses are company contact points; personal ones are individuals' data and carry GDPR obligations for you as the data controller.

Honest reporting

reasonMeaningCharged
β€” (ok: true)Contacts foundYes
no-contacts-publishedSite reachable, publishes nothingNo
domain-not-resolvingThe domain does not resolve β€” expired or mistypedNo
site-blockedSite is up and refuses automated clientsNo
site-timeoutNo answer in the time budget β€” worth one retryNo
site-tls-errorCertificate or handshake failure, often expiredNo
site-errorServer error on their side, may be temporaryNo
site-unreachableAnything elseNo

Many companies use contact forms and publish no address at all. You get told that, and you are not charged for it.

The failure codes are split on purpose. Measured on a 400-domain sample (3 September 2026): of the rows a single site-unreachable code used to cover, 35% did not resolve, 28% answered with a 4xx, 15% answered normally on retry, 11% failed on TLS and 7% timed out. Each of those wants a different response β€” drop the dead domain, reach the blocked one another way, retry the flaky one β€” and one code could not tell you which you had.

Input

FieldRequiredDescription
domainsyesDomains or URLs
includePersonalnoDefault false
maxConcurrencyno1–20, default 5
proxynoOptional

Output

Every row has the same fields whether it succeeded or failed, so you can select columns without branching. Failed rows are never charged.

FieldTypeDescription
successbooleanTrue when this row carries data. Failed rows are never charged.
domainstringThe website this row is about.
roleEmailsarrayOn-domain role addresses (info@, sales@, support@) β€” the company's own contact points.
personalEmailsarrayOn-domain addresses belonging to named individuals. Different reliability, and different legal handling under GDPR.
otherDomainEmailsarrayAddresses on a different domain to the site β€” usually the agency that built it. Kept separate rather than presented as the company's contact.
phonesarrayPhone numbers published on the site.
socialsarrayLinks to the company's social profiles.
emailCountintegerTotal addresses found, including off-domain ones.
pagesFetchedintegerHow many pages of the site were crawled to produce this row.
errorCodestringMachine-readable failure reason. Null on success.
errorMessagestringHuman-readable explanation of the failure. Null on success.

Example β€” success

{
"success": true,
"domain": "stripe.com",
"roleEmails": [
"info@stripe.com",
"sales@stripe.com"
],
"personalEmails": [
"dana.olsen@stripe.com"
],
"otherDomainEmails": [
"hello@buildagency.example"
],
"phones": [
"+1 888 963 8955"
],
"socials": [
"https://twitter.com/stripe",
"https://www.linkedin.com/company/stripe"
],
"emailCount": 4,
"pagesFetched": 6,
"errorCode": null,
"errorMessage": null
}

Example β€” failure

A failure carries the same fields, so nothing downstream has to branch.

{
"success": false,
"domain": "contact-form-only.example",
"roleEmails": null,
"personalEmails": null,
"otherDomainEmails": null,
"phones": null,
"socials": null,
"emailCount": null,
"pagesFetched": 5,
"errorCode": "no-contacts-published",
"errorMessage": "The site was reachable but publishes no email, phone, or social profile. Many companies only offer a contact form."
}

Error codes

  • domain-not-resolving
  • site-blocked
  • site-error
  • site-tls-error
  • site-timeout
  • site-unreachable
  • no-contacts-published
  • unparseable-domain
  • error

Use it for

  • Role emails from a website β€” info@, sales@, support@, separated from personal
  • Company contact details β€” emails, phones and social profiles per domain
  • Lead lists and CRM enrichment from a domain list
  • Sales prospecting without placeholder junk
  • Partner and vendor research

Use it from an AI agent (MCP)

This Actor is callable as a tool through the Apify MCP server, so Claude, ChatGPT, Cursor and VS Code can run it directly.

Add the server to your MCP client:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com",
"headers": {
"Authorization": "Bearer <YOUR_APIFY_TOKEN>"
}
}
}
}

Then ask for what you want in plain language β€” for example β€œfind the contact details published on this company website” β€” and the agent calls cleanfeed/verified-website-contacts with the right input. Every output field is described in the dataset schema, so the agent knows what it is getting back before it runs anything.

Call it from code

Python

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("cleanfeed/verified-website-contacts").call(run_input={
"domains": ["https://stripe.com"],
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
if item["success"]:
print(item)

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('cleanfeed/verified-website-contacts').call({
domains: ["https://stripe.com"],
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.filter((i) => i.success));

cURL

curl -X POST "https://api.apify.com/v2/acts/cleanfeed~verified-website-contacts/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
-H 'Content-Type: application/json' \
-d '{"domains": ["https://stripe.com"]}'
If you needUse
Company data from YouTube channels insteadYouTube Channel Transcript Scraper

Limitations

  • Many companies publish no contact details at all, using a form instead. Those return errorCode: no-contacts-published, which is an honest answer rather than a failure.
  • Off-domain addresses are separated, not discarded. An address on another domain is usually the agency that built the site, so it lands in otherDomainEmails rather than being presented as the company's contact.
  • Placeholder addresses are filtered β€” example.com, acme.com, yourdomain.com and asset filenames such as logo@2x.png that match an email pattern.
  • Personal addresses are returned separately from role addresses and are off by default; under GDPR they carry different handling obligations.

FAQ

How is this different from a regex over the page?

A regex also returns fake data. Placeholder domains (example.com, acme.com), asset filenames like logo@2x.png, and the web agency's own address all match an email pattern. Those are filtered or separated here.

What is the difference between role and personal emails?

Role addresses (info@, sales@, support@) are company contact points. Named addresses belong to individuals β€” different reliability, and different handling under GDPR. They are returned in separate fields, and personal ones are off by default.

Why did a domain return nothing?

Plenty of companies publish no address and use a contact form instead. That returns errorCode: no-contacts-published, which is a real answer β€” a guessed address that bounces costs you sender reputation.

What are otherDomainEmails?

Addresses found on the site but hosted elsewhere, typically the agency that built it. They are kept rather than dropped, but not presented as the company's own contact.

Can I process a list of domains?

Yes. Pass the whole list and tune maxConcurrency; one row is returned per domain, including the ones with nothing published.

Notes

Only publicly published company contact details are collected, from pages the company itself serves (homepage, contact, about, Impressum, legal). No login, no purchased databases, no guessed addresses.