How to find the contact email, phone and socials for a list of company domains
Short answer
Companies publish role addresses on their own site: footer, contact, about and imprint pages. Hollerdex on Apify checks up to 6 such pages per domain and returns the best email (labelled sales, support, press or info), phones, social profiles and the contact form, at $0.004 per domain with contacts.
- Start from bare domains (example.com). If you only have company names, resolve them to domains first.
- Decide whether you want only role addresses (info@, sales@, support@): set includePersonalEmails to false.
- Run the list; each domain comes back with primaryEmail, all emails with the page they were found on, phones and socials.
- Use contactFormUrl for companies that publish a form instead of an address.
- Re-run monthly in monitor mode to catch changed addresses.
Copy-paste code
Python (pip install apify-client): role addresses only, to CSV
import csv, os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("cybermax/website-contacts").call(run_input={
"domains": ["apify.com", "basecamp.com", "katzsdelicatessen.com"],
"maxPagesPerDomain": 6,
"includePersonalEmails": False, # company role addresses only
})
with open("contacts.csv", "w", newline="") as f:
w = csv.writer(f)
w.writerow(["domain", "email", "phone", "linkedin", "contact_page"])
for r in client.dataset(run["defaultDatasetId"]).iterate_items():
s = r.get("socials") or {}
w.writerow([r["domain"], r.get("primaryEmail"), r.get("primaryPhone"), s.get("linkedin"), r.get("contactPageUrl")])JavaScript / Node (npm i apify-client)
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('cybermax/website-contacts').call({ domains: ['apify.com', 'basecamp.com'] });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const r of items) console.log(r.domain, r.primaryEmail, r.emails?.map((e) => e.role || e.type));No code: n8n, Make or Zapier
n8n: HTTP Request node (or the Apify node, action "Run an Actor and get dataset")
Method: POST
URL: https://api.apify.com/v2/acts/cybermax~website-contacts/run-sync-get-dataset-items
Auth: Header Auth -> Authorization: Bearer <your Apify token>
Body: JSON {"domains": ["apify.com", "basecamp.com"], "includePersonalEmails": false}
Output: one n8n item per result row, ready for Google Sheets / Airtable / a Slack message
Make: Apify app -> "Run an Actor" (Actor: cybermax/website-contacts, wait for finish = yes)
-> Apify "Get Dataset Items" (dataset = the run's defaultDatasetId) -> Google Sheets "Add a Row"
Zapier: Apify app -> action "Run Actor" (cybermax/website-contacts, input JSON as above)
-> trigger "Finished Actor Run" -> "Fetch Dataset Items" -> your app
Runs longer than 5 minutes: start with POST /v2/acts/cybermax~website-contacts/runs and read the dataset when the run finishes.From an AI agent (MCP)
# Any MCP client (Claude Desktop, Claude Code, Cursor, VS Code): Apify's hosted MCP server
{
"mcpServers": {
"website-contacts": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.apify.com/?tools=cybermax/website-contacts",
"--header", "Authorization: Bearer ${APIFY_TOKEN}"],
"env": { "APIFY_TOKEN": "<your Apify token>" }
}
}
}
# The agent sees one tool, cybermax--website-contacts, with the Actor's input schema.| domain | primaryEmail | email type | socials | contact page / form | pages checked |
|---|---|---|---|---|---|
| apify.com | hello@apify.com | role | linkedin, x, tiktok, github, discord | apify.com/contact | 5 |
| basecamp.com | jason@basecamp.com | personal | - | basecamp.com/support (form) | 4 |
Source: Hollerdex (Apify Actor cybermax/website-contacts) README, real run on 24 Sep 2026
Where companies publish contact details
Footers, /contact, /about, /impressum (required in Germany and Austria), /press and /support pages, plus mailto: and tel: links and the JSON-LD Organization block. A scraper that only reads the homepage misses most of them; one that checks a handful of likely pages per domain finds far more.
Use company addresses responsibly
Business role addresses that a company publishes on its own site are meant to be contacted. Laws such as GDPR and CAN-SPAM still apply to what you send: say who you are, give a real reason and an easy opt-out.
Good to know
Price on Apify: $0.004 per domain where contacts are found ($4 per 1,000); domains with no contacts, blocked sites and errors are free. Apify's free plan includes $5 of usage each month.
Hollerdex reads only the company's own public pages; it does not guess addresses or look people up elsewhere.
Hollerdex: Any company's best email, phone and socials
$0.004 per domain with contacts, misses and blocked sites freeHollerdex returns each domain's best email, phone, socials and contact page from the company's own site. $0.004 per domain with contacts; misses and blocked sites are free.
Runs on your own Apify account, pay per result; failed results are not charged.Questions
Can I find an email address from just a domain?
Yes, when the company publishes one on its site. Hollerdex returns it with the page it was found on; it never invents pattern guesses like firstname@.
What about companies with only a contact form?
You get contactFormUrl, so you can use the form.
Is scraping contact details legal?
Reading publicly published business contact pages is generally allowed; how you use the data is governed by privacy and anti-spam law. This is not legal advice.
Can an AI agent use it?
Yes. Apify's MCP server exposes it as cybermax--website-contacts.
Free: the Free API Starter Kit
Copy-paste calls for 4 APIs with free daily tiers (CVE priority, VIN recalls, US duty rates, email checks), then 5 short emails on KEV/EPSS, MCP and free data.