Company Website Contact Info Scraper
Pricing
from $1.00 / 1,000 successfully parsed html pages
Company Website Contact Info Scraper
Extract emails, phone numbers and social links from company websites or domain lists. Respects robots.txt, CRM-ready output, MX check, $1 per 1,000 pages, failed pages free.
Pricing
from $1.00 / 1,000 successfully parsed html pages
Rating
0.0
(0)
Developer
Ye Qiangwei
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Company Website Contact Scraper — Emails, Phone Numbers & CRM Export
Turn a list of company websites into source-linked public email addresses, phone numbers and social profile links. Each company is summarized in one dataset row, ready for review or CRM enrichment. Choose perContact for a flat contact export.
What you get
- Public email addresses, phone numbers and social profile links found on the company pages you supply.
- Contact, About, Legal, Team and Support page discovery within each company’s registered domain.
- Source URLs for each contact, plus page results and company status for review.
- Company rows with ready-to-export CRM fields, or one row per contact with
perContact. - Configurable page and spending limits, with fees based on successfully parsed HTML pages.
Who is it for?
Sales operations teams enriching company lists, agencies reviewing client contact details, and researchers organizing public business directories. Export primaryEmail, primaryPhone, contactPageUrl, emailsFlat and phonesFlat directly to CSV for CRM review.
The Actor reads static HTML. It does not render JavaScript or verify that an email address exists. Coverage depends on what each website publishes and allows the Actor to access.
Pricing
| Event | Price (USD) | When charged |
|---|---|---|
run-start | $0.00005 per run (nominal startup fee) | Once for a validated new run, including runs with failed websites or no contacts |
page-fetched | $0.001 per page ($1.00 / 1,000 pages) | Once for each successfully fetched and parsed HTML page, including pages without contacts |
There is no per-contact or dataset-row event fee. Finding ten contacts on one page still costs one page event. The homepage counts toward both the page budget and the price.
Robots requests, redirect hops, duplicate final pages, HTTP failures, non-HTML responses, login pages, protection challenges, timeouts and parsing failures do not incur page events.
For 100 companies × about 8 successful pages each = 800 pages, one run costs $0.00005 + 800 × $0.001 = $0.80005 (about $0.80). Actual successful page counts determine the price.
| Other single-run examples | Actor event fees |
|---|---|
| 8 successful pages | $0.00805 |
| 1,000 successful pages | $1.00005 |
| All websites fail, with enough budget to start | $0.00005 |
These examples cover Actor event fees. See the Store pricing panel for the effective price and any other platform charges.
Spending limits and billing status
Set the run’s maximum total charge to control spending. The Actor uses the lower of that limit and ACTOR_MAX_TOTAL_CHARGE_USD, after subtracting charges already known to the SDK, including any automatic platform startup event. It reserves capacity before fetching each page and stops scheduling pages when the remaining budget cannot cover the next event.
Before any automatic platform charges, the minimum Actor event budget is $0.00005 to start, or $0.00105 for startup plus one successful page. A budget between those amounts permits only the startup event, with no page requests. Zero budget permits no events; fractions smaller than one microdollar are rounded down.
All companies remain in the output when billing stops:
- Companies with pending pages, or not yet started, receive
CHARGE_LIMITfor budget exhaustion orBILLING_STOPPEDfor a billing/storage failure. Their status ispartialif a page was fetched, otherwiseskipped. limits.chargeLimitReachedis true only when budget exhaustion affects that company. Completed companies keep their original status and flags. Independently blocked companies keepblocked.- The key-value store record
SUMMARYcontains the global stop reason. Check page-levelbillingfor uncertain charges: a company can retain its extraction status if its last page’s charge is uncertain and no pages remain.
An uncertain charge or receipt-storage failure stops further charging; uncertain events are never retried. Receipts are saved in batches to CHARGE-CHECKPOINT. Forced termination can leave the latest receipts or company output unsaved, so checkpoints do not replace platform billing records. Automatic migration/restart using existing run storage is refused to prevent duplicate charging.
Input
Provide exactly one of startUrls or domains, containing 1–1,000 entries. URLs may include a path: https://example.org/contact starts at that exact page; the homepage is not automatically added. URLs sharing a registered domain are combined into one company and share one page budget. The public suffix list, including private suffixes, keeps independent tenants such as a.github.io and b.github.io separate.
{"startUrls": [{ "url": "https://example.com/" },{ "url": "https://example.org/contact" }],"maxPagesPerDomain": 8,"maxConcurrency": 5,"includeSubdomains": true,"requestIntervalMs": 1000,"globalIntervalMs": 100,"timeoutMs": 15000,"outputMode": "perCompany","checkMx": false,"defaultCountry": "GB"}
Alternatively:
{"domains": ["example.com", "example.org"],"outputMode": "perContact"}
Bare domains use HTTPS, with no automatic HTTP or www fallback. JSON/API input also accepts URL strings in startUrls; the Store URL editor uses { "url": "..." } objects.
Only the URL is used. Standard request-list fields such as uniqueKey, userData and headers are accepted but ignored; method, if supplied, must be GET. Request-list files, credentials, login paths, cookies and proxy options are unsupported.
| Option | Default | Limits / behavior |
|---|---|---|
maxPagesPerDomain | 8 | 1–30 page candidates examined, including failed or robots-disallowed candidates; includes supplied seed pages |
maxConcurrency | 5 | 1–20 concurrent company workers; one HTTP request at a time per registered domain |
includeSubdomains | true | Follow relevant links and redirects within the registered domain. If false, allow only hostnames explicitly provided in the input, including for robots redirects; company grouping stays by registered domain |
requestIntervalMs | 1,000 | 100–60,000 ms between request starts for a company; robots Crawl-delay takes precedence |
globalIntervalMs | 100 | 20–10,000 ms between global request starts, including robots and redirect hops |
timeoutMs | 15,000 | 1,000–60,000 ms per DNS lookup and per HTTP hop, including body transfer; separate from scheduling delays |
outputMode | perCompany | perCompany or perContact |
checkMx | false | DNS MX lookup only, cached per email domain, with a 3-second lookup timeout |
defaultCountry | unset | Optional uppercase country code such as GB or US for national phone numbers; no country is guessed |
After the supplied pages, the Actor follows only linked pages with relevant anchor text or paths. It does not guess contact paths or open arbitrary news/product pages. It queues at most 3,000 relevant links per company and examines no more than the configured page budget.
Matching covers common English phrases such as “get in touch”, “reach us” and “enquiries”, plus selected French, Spanish, Italian, Portuguese, Dutch, German, Chinese and Japanese terms. This is a limited keyword list, not full language coverage or translation. Uncommon labels may be missed; broad words such as “connect” and “feedback” alone do not qualify.
Output example
One illustrative company row for a fictional business (not collected from a live website):
{"domain":"northstar-studio.co.uk","companyName":"Northstar Studio Ltd","primaryEmail":"hello@northstar-studio.co.uk","primaryPhone":"+442079460958","contactPageUrl":"https://northstar-studio.co.uk/contact","emailsFlat":"hello@northstar-studio.co.uk;sales@northstar-studio.co.uk","phonesFlat":"+442079460958","pagesFetched":8,"pagesFailed":0,"status":"succeeded"}
The compact example selects CRM columns. Full company rows also contain nested contacts, page evidence and billing details as shown below.
| CSV column | Meaning |
|---|---|
domain, companyName | Registered company domain and published organization name; name may be empty |
primaryEmail | First general business/role email by source priority, falling back to a suspected personal address; empty if none |
primaryPhone | First observed phone by source priority; may be a national number when no country was provided |
contactPageUrl | Best fetched contact-path page, falling back to a prioritized page with observed contacts; empty if none |
emailsFlat, phonesFlat | Deduplicated values joined with semicolons, ordered with the primary value first; empty strings if none |
status, pagesFetched, pagesFailed | Company outcome and examined-page results; check limitations before treating missing data as absent |
Export the default perCompany Dataset as CSV to use these columns. primaryEmail, primaryPhone and contactPageUrl are JSON null when unavailable. Phone extensions stay in the phone value.
Source priority is Contact > Impressum/Legal/Privacy > About/Company > Team > Support > homepage > other paths, with the contact value breaking ties. Role emails always precede suspected personal addresses. This ranking does not establish who is best to contact. Flat fields include suspected personal addresses too; review them before import.
Full illustrative row:
{"domain": "acme-company.com","companyName": "Acme Company","primaryEmail": "info@acme-company.com","primaryPhone": "+442079460958","contactPageUrl": "https://acme-company.com/contact","emailsFlat": "info@acme-company.com","phonesFlat": "+442079460958","emails": {"general": [{"value": "info@acme-company.com","sourcePages": ["https://acme-company.com/contact"]}],"personal": []},"phones": [{"value": "+442079460958","e164": "+442079460958","extension": null,"raw": "+44 20 7946 0958","sourcePages": ["https://acme-company.com/contact"]}],"socialLinks": [{"value": "https://www.linkedin.com/company/acme-company","sourcePages": ["https://acme-company.com/contact"]}],"sourcePages": [{"requestedUrl": "https://acme-company.com/contact","url": "https://acme-company.com/contact","status": "fetched","billing": "confirmed","httpStatus": 200,"redirectCount": 0,"contacts": [{ "type": "email", "value": "info@acme-company.com" },{ "type": "phone", "value": "+442079460958" },{ "type": "social", "value": "https://www.linkedin.com/company/acme-company" }]}],"pagesFetched": 1,"pagesFailed": 0,"status": "succeeded","failureReasons": [],"scrapedAt": "2026-10-23T00:00:00.000Z","billing": { "mode": "platform", "pagesConfirmed": 1, "pagesUnknown": 0 },"limits": { "maxPagesPerDomain": 8, "pageLimitReached": false, "chargeLimitReached": false },"mxDisclaimer": null}
Each contact has its own sourcePages URL list. The company’s top-level sourcePages holds page outcomes, contact references and billing confirmations. Fetched pages also include parsedAt, chargeReceiptId and chargeCheckpointKey to link them to billing receipts.
companyName comes from explicit organization JSON-LD or og:site_name when available; it may be null.
General role addresses such as info@, sales@, support@ and contact@ are separated from suspected personal addresses. This is a local-part heuristic, not identity verification. The Actor only extracts addresses actually published on the supplied company's pages; it never guesses employee addresses. Contacts are deduplicated within a company and retain all observed source pages. The same contact can appear for different companies.
Phone numbers are validated and normalized using numbering-plan metadata. National numbers require defaultCountry; otherwise plausible numbers found in explicit tel: links are retained with e164: null. Extensions are preserved. A valid format does not establish ownership or whether a phone is active.
Common [at], (at), [dot] and Cloudflare email-protection XOR encodings are decoded locally. Scripts, styles, image filenames, placeholder/test domains, no-reply addresses and common telemetry addresses are filtered. This does not solve CAPTCHAs or bypass access controls.
With checkMx: true, each email includes mx.status (present, no_mx, null_mx or unknown), exchanges and deliverability: "not_verified". MX presence does not mean an address exists or is deliverable. No SMTP connection, message sending or mailbox probing occurs. A missing MX may still permit SMTP fallback; this is an observation, not a deliverability verdict.
perContact produces rows such as:
{"domain": "acme-company.com","companyName": "Acme Company","contactType": "email","category": "general","value": "info@acme-company.com","sourcePages": ["https://acme-company.com/contact"],"status": "succeeded","pagesFetched": 1,"pagesFailed": 0}
Flat rows also include the five CRM fields, company metadata, failureReasons, billing, limits and scrapedAt.
sourcePagesalways contains that contact’s source URL list.pageResultscontains the company’s page outcomes (the top-levelsourcePagesinperCompanyoutput).- Company counters repeat on each contact row: do not sum them across contacts.
- Companies with no contacts retain a row with
contactType: null,value: null,sourcePages: []and the company’s page evidence inpageResults. If no pages were attempted,pageResultsis also empty.
Understanding results
| Status | Meaning |
|---|---|
succeeded | Contacts were found within the examined pages, without a reported incomplete condition |
empty | Examined pages produced no contacts, without a reported incomplete condition |
partial | Failed/skipped candidates, the page budget or a charge stop left the company incomplete |
failed | No page was successfully fetched and a page failure was reported |
blocked | Access was refused; may retain contacts collected before the refusal |
skipped | The company was not fetched, for example because the spending limit was reached before it started |
No status guarantees that every website contact was found. pagesFetched counts parsed HTML pages, including empty pages. pagesFailed counts failed examined candidates, including robots exclusions. Robots requests and redirect hops are excluded from both counters. Check page-level billing for uncertain charge outcomes.
Access rules and limitations
Website access
The Actor reads each origin’s robots.txt as CompanyContactsBot. Disallowed paths and unavailable or ambiguous rules are skipped conservatively. A 404/410 allows normal evaluation. Transient network failures and HTTP 5xx receive at most one robots retry per origin per run, through the same rate limits; deterministic refusals are cached without retry. Crawl-delay above 60 seconds results in a skip.
HTTP 401/403/429, detected login walls and protection challenges stop that company without retries or IP changes. Other page failures are reported without retrying. The Actor sends no target cookies or credentials, uses no proxies, submits no forms, and does not execute JavaScript, load images or follow social profiles.
Pages and robots fetches allow up to five redirect hops, within the original registered domain. Every destination is checked for private/reserved addresses, mixed public/private DNS answers are rejected, and connections are pinned to the validated address. Off-domain redirects are reported as incomplete.
Coverage and resource limits
- Contacts must appear in returned HTML. JS-only data, images of contact details, advanced obfuscation and details requiring interaction may be missed.
- Social links come from a known host list; unrecognized hosts may be omitted. Language matching, filtering, phone parsing, company names and challenge detection are heuristic and may miss data or produce false positives.
- Compressed and decoded HTML are each limited to 5 MiB; robots.txt is limited to 512 KiB. gzip, deflate and Brotli are supported. Unsupported/binary/invalid character encodings fail without page fees; ordinary imperfect HTML is accepted.
- Default memory is 1,024 MiB (minimum 512 MiB). Large pages and higher concurrency increase memory use; these settings do not guarantee against out-of-memory failures.
- Cross-run change and deletion tracking are not supported.
Responsible use
Supply only public company pages you are authorized to collect. Review suspected personal addresses before use and apply appropriate retention and deletion rules. Public availability and robots.txt access do not establish permission to republish information or contact people; comply with website terms and applicable privacy and marketing rules.
FAQ
Does it support JavaScript websites? No JavaScript is executed. Static HTML returned by a JavaScript-based site can be parsed, but contacts rendered only by scripts or interaction are unsupported.
Does it respect robots.txt? Yes. Each origin is checked with CompanyContactsBot; disallowed paths and unavailable or ambiguous robots responses are skipped conservatively. HTTP 401/403/429 and detected access challenges stop the company without retries.
Are emails verified using SMTP? No. The optional MX check uses DNS only, never connects to SMTP, sends messages or probes a mailbox. MX presence does not verify an address or deliverability.
Who is responsible for personal data and outreach compliance? You are responsible for your lawful basis, permissions, privacy notices, retention and deletion, and compliance with applicable rules such as GDPR and CAN-SPAM. Public contact details can still be personal data. Review the source and intended use before exporting, storing or contacting anyone; this Actor does not establish legal permission.