Website Contacts & Decision Makers Scraper avatar

Website Contacts & Decision Makers Scraper

Pricing

from $6.00 / 1,000 website scanneds

Go to Apify Store
Website Contacts & Decision Makers Scraper

Website Contacts & Decision Makers Scraper

Turn a list of company websites into contact rows: emails, phone numbers (validated, typed), social profiles, address, VAT ID, plus the owners and managers named on the site. Works on any country's websites, pairs with Google Maps Scraper output.

Pricing

from $6.00 / 1,000 website scanneds

Rating

0.0

(0)

Developer

Benjamin Zsigri

Benjamin Zsigri

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

Turn a list of company websites into a clean contact sheet. For every website you get one row with:

  • Emails, labelled as role mailbox (info@, sales@), personal (jane.smith@), generic or freemail, with the page each one was found on
  • Phone numbers, validated and formatted in international E.164 (+441614960123), typed as landline, mobile or service number, with fax numbers kept apart
  • Decision makers: owners, founders, managing directors, executives, board members and department heads named on the website, with their role, a role category and, when the site publishes it, their email
  • Social profiles: LinkedIn, Facebook, Instagram, X/Twitter, YouTube, TikTok, Pinterest, XING, GitHub
  • Company name, postal address, VAT ID, website language and description

It works on websites from any country (English, German, French, Spanish, Italian, Dutch, Portuguese, Polish, Nordic, Hungarian and Czech pages are understood) and it is built to take the output of Google Maps Scraper or any other dataset with a website column.

Who it is for

  • Sales and lead generation: you have a list of businesses (from Google Maps, a directory, a trade fair, your CRM) and need a phone number, an email and the name of the person in charge.
  • Agencies building prospect lists for clients.
  • CRM enrichment: fill in missing emails, phones, social profiles and VAT IDs for accounts you already have.
  • Market research: who owns and runs the companies in a niche.

How it works

  1. Each website is visited starting from its homepage.
  2. The crawler picks the pages most likely to hold contact details first: contact, imprint / legal notice (Impressum, mentions légales, aviso legal), team / leadership, about. It never opens login, basket, blog, shop or privacy pages.
  3. Every page is read for emails, phone numbers, social links, structured data (schema.org) and people with a role.
  4. Everything found is merged into one row per website, ranked (the company's own domain first, role mailboxes before personal ones, the main phone number first, the most senior person first).

A typical small or mid-size business website needs 4 to 8 pages. You set the maximum with Max pages per website.

What the Actor does NOT do

  • It does not log in anywhere and it does not solve or bypass CAPTCHAs.
  • It respects robots.txt. A website that disallows crawling is reported as robots_blocked and is not charged.
  • It does not decode email protection scripts (such as Cloudflare's): the row is flagged with email_hidden_by_protection: true instead. Emails written as name [at] company [dot] com are plain text shown to every visitor and are read.
  • It does not guess emails (no firstname.lastname@ invention) and it does not use LinkedIn. Only what the company publishes on its own website is returned.
  • Customer testimonials and reviews are kept apart from the company's people: names right under a quote or in a "what our customers say" section are skipped.

Input

The simplest input is a list of websites:

{
"websites": ["https://www.example-plumbing.co.uk", "example-dental.com"],
"findDecisionMakers": true,
"maxDecisionMakersPerWebsite": 3
}

Or point the Actor at a dataset, for example the output of a Google Maps Scraper run:

{
"datasetId": "YOUR_DATASET_ID",
"maxPagesPerWebsite": 8
}

The website field is detected automatically (website, url, domain, companyWebsite, …) or you can name it in Website field in the dataset. A Google Maps listing link is never taken for the website; items without a website are skipped. Fields such as title, placeId, address, city, countryCode and categoryName are copied into source_item, so you can join the results back to your list.

FieldWhat it does
websitesCompany websites, one per line. Duplicates are scanned once.
datasetIdImport websites from a dataset (e.g. Google Maps Scraper output).
findDecisionMakersRecognise owners, executives and managers named on the site.
maxDecisionMakersPerWebsiteMost senior first. Caps the cost per website.
includeOtherPeopleOther named people with a role (staff, contact persons). Free.
defaultCountryCountry for local phone numbers written without a prefix. Without it, the dataset's countryCode or the website's country domain is used.
maxPagesPerWebsiteRequests per website, homepage included (default 8).
maxConcurrencyWebsites scanned in parallel (default 20).
proxyConfigurationOptional. Most company websites answer direct requests.

Output

One row per website. Overview columns (primary_email, primary_phone, decision_maker_name, decision_maker_role, decision_maker_email, linkedin, …) make the CSV and Excel export usable without unpacking arrays; the full lists are in the JSON.

{
"input_url": "example-plumbing.co.uk",
"domain": "example-plumbing.co.uk",
"website": "https://www.example-plumbing.co.uk/",
"status": "ok",
"company_name": "Example Plumbing Ltd",
"language": "en",
"emails": [
{ "email": "hello@example-plumbing.co.uk", "type": "role", "same_domain": true, "source_url": "https://www.example-plumbing.co.uk/contact/" },
{ "email": "jane.smith@example-plumbing.co.uk", "type": "named", "same_domain": true, "source_url": "https://www.example-plumbing.co.uk/meet-the-team/" }
],
"phones": [
{ "number": "+441614960123", "type": "landline", "country": "GB", "source_url": "https://www.example-plumbing.co.uk/" },
{ "number": "+447911123456", "type": "mobile", "country": "GB", "source_url": "https://www.example-plumbing.co.uk/contact/" }
],
"fax_numbers": [],
"socials": { "facebook": "https://facebook.com/exampleplumbing", "linkedin": "https://linkedin.com/company/example-plumbing" },
"address": { "street": "12 Mill Lane", "postal_code": "M1 2AB", "city": "Manchester", "region": null, "country": "GB" },
"vat_ids": [{ "id": "GB123456789", "country": "GB" }],
"decision_makers": [
{
"name": "Jane Smith",
"first_name": "Jane",
"last_name": "Smith",
"salutation": null,
"role": "Founder & Managing Director",
"role_category": "owner",
"is_decision_maker": true,
"email": "jane.smith@example-plumbing.co.uk",
"source_url": "https://www.example-plumbing.co.uk/meet-the-team/",
"extraction_method": "name_above_role"
}
],
"other_people": [{ "name": "Tom Baker", "role": "Gas Safe Engineer", "role_category": "staff", "is_decision_maker": false }],
"email_hidden_by_protection": false,
"primary_email": "hello@example-plumbing.co.uk",
"primary_phone": "+441614960123",
"decision_maker_name": "Jane Smith",
"decision_maker_role": "Founder & Managing Director",
"decision_maker_email": "jane.smith@example-plumbing.co.uk",
"pages_crawled": 4,
"scraped_at": "2026-10-01T09:00:00.000Z"
}

Role categories

role_categoryExamplesDecision maker
ownerOwner, Founder, Co-founder, Managing Partner, Inhaber, Gründer, Fondateuryes
executiveCEO, Managing Director, General Manager, Geschäftsführer, Directeur généralyes
boardChairman, Board member, Non-Executive Director, Verwaltungsratyes
authorized_representativeLegal representative named in the legal noticeyes
department_headHead of Sales, Sales Director, Director of Marketing, Office Manager, Vertriebsleiteryes
content_responsible, contactResponsible for content, contact personno
staffEngineer, Consultant, Plumber, Account Managerno

Status values

statusMeaningCharged
okThe website answered and was readyes
robots_blockedrobots.txt disallows crawlingno
blockedThe site refuses automated requests (HTTP 401/403/429) or redirects elsewhereno
not_a_company_websiteA social profile, directory or marketplace page, not the company's own siteno
unreachable / http_error / not_html / invalid_url / errorThe website could not be readno

Pricing

This Actor uses pay per event pricing: you pay for results, not for compute time.

  • Website scanned: charged once per website that answered (status: ok), whatever was found on it.
  • Decision maker found: charged per decision maker returned. Set Max decision makers per website to cap it, or switch decision makers off.

Websites that could not be read are listed in the results with the reason, free of charge. Other named people (other_people) are free. The current prices are on the Pricing tab.

The Actor respects your maximum cost per run: when the limit is reached it stops before starting another website, and it never returns a decision maker it could not charge for.

Use it with Google Maps Scraper

  1. Run Google Maps Scraper for your niche and area (e.g. "plumbers in Manchester").
  2. Copy the run's dataset ID.
  3. Start this Actor with datasetId set to it.

Each row keeps the place's title, placeId, address and countryCode in source_item, so you get the place, its website contacts and its owner in one table. You can chain both Actors automatically with an Apify integration (run this Actor when the Maps run succeeds).

Where your list can come from

  • Google Maps Scraper: set datasetId to its run's dataset. This Actor never searches Google Maps itself; it works on the dataset you bring.
  • A CSV file or spreadsheet: paste the website column into websites, one per line.
  • Your CRM: export the accounts and paste the website column, or push the rows into an Apify dataset with the API and set datasetId to it. datasetUrlField names the column when it is not one of the usual names.
  • Make, n8n, Zapier or Clay: start the Actor through the Apify API (Apify also offers ready-made modules for some of these tools), pass websites in the input and read the run's dataset as the output.

Tips

  • Speed and cost: 6 to 8 pages per website find contact details on the vast majority of small business websites. Raise it for large corporate sites with deep team sections.
  • Local phone numbers written without a country prefix are only returned when the country is known (from defaultCountry, the dataset's countryCode or the country domain such as .de or .co.uk). A number is never guessed into the wrong country.
  • Blocked websites: if many of your websites end as blocked, try a proxy in the input.
  • Resuming: if a run is migrated by the platform, it continues where it stopped without scanning or charging the finished websites again.

This Actor reads only pages that the company publishes openly on its own website, respects robots.txt and does not bypass any login, CAPTCHA or email protection. Business contact details of companies are generally public information. However, names and personal work emails of people are personal data under the GDPR (EU/UK) and similar laws. If you store or use them, you need a lawful basis (for B2B outreach usually legitimate interest), you must tell people where you got their data, and you must respect opt-outs and local direct-marketing rules (e.g. PECR in the UK). If you are unsure, ask a lawyer. You are responsible for how you use the data.

Limitations

  • Websites that render all content with JavaScript only (no server-side HTML) may return few results.
  • People are recognised from their name and role as written on the page. A person introduced only in a paragraph of prose, or only in an image, is not found.
  • The postal address comes from schema.org structured data when the site provides it.

Feedback

Found a website where the result is wrong or incomplete? Open an issue on the Issues tab with the URL. Real examples are the fastest way to improve the extraction.

Need it done for you?

Want this connected to your CRM or workflow, or adapted to your market? Tribloc, the team behind this Actor, builds these setups. Get in touch at tribloc.co.uk.