Website Contact & Company Data Scraper with AI Lead Scoring avatar

Website Contact & Company Data Scraper with AI Lead Scoring

Pricing

from $3.00 / 1,000 domain crawleds

Go to Apify Store
Website Contact & Company Data Scraper with AI Lead Scoring

Website Contact & Company Data Scraper with AI Lead Scoring

Crawl company domains for emails, phones, and socials, then add an AI company profile and ICP fit score. Flat price per domain, not per page.

Pricing

from $3.00 / 1,000 domain crawleds

Rating

0.0

(0)

Developer

Crafted in Code

Crafted in Code

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

20 days ago

Last modified

Share

Paste a list of company domains, or pass a dataset from a Google Maps scraper, and get a company profile for each site: emails, phone numbers, social profiles, a few tech hints, and an optional AI lead score against your ideal customer profile.

You pay a flat price per domain, not per page. The crawl is limited to the homepage plus contact, about, team, careers, and legal pages (8 pages max). Dead, parked, and blocked domains are returned with a status and are not charged.

Built for agencies, SDRs, and Clay / n8n / Make workflows that already have a lead list and need qualification without a surprise crawl bill.

What data can you extract?

FieldWhat it is
domain, finalUrl, companyName, titleThe site that was crawled, after redirects, and the name from the page title or structured data
statusok, dead, parked, blocked, or error
emailsRole inboxes such as info@ and sales@ first. Named personal emails are omitted unless you opt in
phonesNumbers from tel: links, structured data, and formatted numbers on the page
socialsLinkedIn, Facebook, Instagram, X, YouTube, TikTok
techHintsSignatures such as Shopify, WordPress, HubSpot, GA4, Stripe, Intercom
contactPageUrl, addressHint, countryHint, hasCareersPageContact page, a short address when the site publishes one, careers link
pagesCrawled, pageUrlsHow many pages were actually fetched
aiSummary, industry, subIndustry, businessModelShort description and category. Industry is one of a fixed list
offerings, targetCustomers, pricingModelHintWhat they sell, who they sell to, and a pricing hint (demo, quote, ecommerce, …)
companySizeSignal, companySizeEvidencesolo, SMB, mid, enterprise, or unknown, plus the phrase that suggested it
icpFitScore, icpFitReasons, personalizationLine0–100 against your ICP text, the reasons, and one outreach opener
aiConfidence, aiMock, aiErrorHow sure the model was, whether the offline mock was used, and why AI was skipped
error, chargedEvents, sourceFailure message, which events were billed, and original columns from a source dataset

icpFitScore is null when you do not provide an ICP. The model is instructed to use only the crawled text. It can still be wrong. Use aiConfidence and companySizeEvidence before you trust a score.

How to use it

  1. Open the Actor and paste domains (acme.com or https://acme.com/pricing) or pick a dataset and the column that holds the website (website for Google Maps).
  2. Set Max domains. This is a hard stop.
  3. Optionally set Max charge (USD). The run also respects the maximum charge you set on the Apify run itself. The lower limit wins.
  4. Leave AI company profile on, and describe your ideal customer in plain English. Example: B2B SaaS, 20–500 employees, sells to HR teams in the US and UK.
  5. Run. Each ok domain is one domain-crawled event. Each AI profile is one ai-profile event. The status message explains when a cap stops the run.

The same domain is crawled once, even if you paste both www.acme.com and https://acme.com/about. Deep links are fetched in addition to the homepage, still inside the page cap.

Free plan: at most 25 AI profiles per run and 100 per UTC month. The crawl can continue without AI after that, until the domain or charge cap. The row's aiError says which cap applied.

How much does it cost to scrape company websites?

Pricing is pay-per-event. You are not billed per page, and you are not billed for a domain that did not resolve, looks parked, or blocked the crawler.

EventFree planPaid plans (Bronze and up)What you pay for
domain-crawled$0.004$0.003One domain with a usable page
ai-profile$0.030$0.010One AI company profile
Start eventplatform defaultplatform defaultA small platform charge when the run starts

Paid-plan examples:

RunPrice
100 domains, contacts only$0.30
100 domains with AI profiles$1.30
1,000 domains, contacts only$3.00
1,000 domains with AI profiles$13.00
1 domain, the prefilled test$0.003 + $0.01 if AI runs

Free-plan example: 25 domains with AI is 25 × $0.004 + 25 × $0.03 = $0.85, and further AI in that UTC month is skipped after 100 profiles.

Set a max charge on the run if you want a hard dollar stop. maxDomains stops the crawl even when money remains. Rows already in flight in the current small batch are finished; new domains are not started.

Flat price vs per-page contact scrapers

This ActorTypical per-page contact scraper
UnitOne domain, up to 8 pagesEvery page fetched
A 5-page site$0.003 on paid plansOften $0.002 × 5 pages, plus browser or proxy add-ons
A site that explodes into hundreds of URLsStopped by the page capCan become a large bill and a huge dataset
Dead or parked domainOutput row, $0Often still billed per request
Lead qualificationOptional AI profile and ICP scoreUsually not included
Google Maps datasetPass the dataset id, keep original columnsUsually a separate copy-paste step

The $13 / 1,000 fully enriched domains figure is the paid-plan list price above. It is not a per-page estimate.

Input example

{
"domains": ["acme.com", "https://example.co.uk/about"],
"datasetId": "yourGoogleMapsDatasetId",
"websiteField": "website",
"maxDomains": 100,
"maxPagesPerDomain": 5,
"maxChargeUsd": 5,
"aiEnrichment": true,
"icpDescription": "B2B SaaS, 20-500 employees, sells to HR teams in the US and UK",
"aiLanguage": "en",
"maxAiDomains": 100,
"includePersonalEmails": false
}

The saved default input is a single fast site (https://crawlee.dev) so the daily Store check finishes in under five minutes.

Output example

One dataset item per domain. A full local sample, produced with the offline mock model against live sites, is in examples/sample-output.json. Real runs set aiMock to false and aiProvider to gemini or openai.

{
"domain": "acme.com",
"finalUrl": "https://acme.com/",
"status": "ok",
"companyName": "Acme Payroll",
"emails": ["sales@acme.com"],
"personalEmailsOmitted": 1,
"phones": ["+1-415-555-0134"],
"socials": { "linkedin": "https://www.linkedin.com/company/acme", "x": null, "facebook": null, "instagram": null, "youtube": null, "tiktok": null },
"techHints": ["HubSpot", "Google Analytics 4"],
"hasCareersPage": true,
"pagesCrawled": 3,
"aiSummary": "Acme sells payroll software to HR teams.",
"industry": "Software",
"businessModel": "B2B",
"companySizeSignal": "SMB",
"icpFitScore": 78,
"icpFitReasons": ["Sells to HR teams", "B2B software"],
"personalizationLine": "Noticed Acme is focused on HR payroll.",
"aiConfidence": 0.7,
"aiMock": false,
"chargedEvents": ["domain-crawled", "ai-profile"],
"error": null,
"aiError": null
}

A blocked site looks like { "status": "blocked", "error": "The site blocked the crawler or returned a bot challenge.", "chargedEvents": [] } and does not add an AI charge.

Run totals, including an estimated LLM cost versus AI-event revenue, are stored as the key-value record RUN_STATS.

FAQ

Is scraping public company websites legal? This Actor fetches pages a browser could open and extracts business contact details the site publishes. It does not log in, bypass paywalls, or solve CAPTCHAs. Laws differ by country. You are responsible for having a lawful basis, especially under GDPR, and for following CAN-SPAM, CASL, and similar rules if you email anyone. This is not legal advice.

Why are some emails missing? By default only role-based addresses are returned (info@, sales@, hello@, and similar). A named inbox such as jane.doe@ is personal data and is counted in personalEmailsOmitted instead. Turn on Include personal emails only when you have a reason to process that data. Addresses that are clearly placeholders, or that belong to vendors such as Sentry, are dropped.

Why is there no phone number? Numbers are taken from tel: links, structured data, and formatted phone patterns. A number that is only drawn as an image, or only rendered by JavaScript, will not be found. This Actor uses HTTP and Cheerio, not a browser, so a site that ships an empty HTML shell may come back thin or blocked.

What does the ICP score mean? It is a 0–100 judgment of the crawled text against the ICP description you typed. It is not a credit score and it is not headcount. If the pages are thin, aiConfidence is low. If you leave the ICP blank, the score is null.

What happens at the free-plan limit? The run does not crash. Further AI calls are skipped, aiError explains the cap, and contact rows that were already allowed are still saved. Raising maxAiDomains does not override the free-plan cap.

Can I connect it to Make, n8n, Zapier, or an AI agent? Yes. Run it from the Apify API, a saved task, or an integration. Map the dataset id of a Google Maps actor into datasetId. The output dataset is a normal Apify dataset, so Make, n8n, Zapier, and the Apify MCP can read the items. The Actor uses limited permissions and pay-per-event pricing, which is what agent checkout flows expect.

Does it charge when the model fails? No. ai-profile is charged only after the response parses as a profile. A timeout or invalid JSON sets aiError and does not bill that event. The crawl event is also skipped unless status is ok.

Integrations

  • Apify API: start a run with the input JSON above and read the default dataset.
  • Google Maps scrapers: pass their dataset id. The website column is picked up automatically.
  • Make, n8n, Zapier: use the Apify integration and map emails, icpFitScore, and personalizationLine.
  • Clay: call the run-sync endpoint and spread the dataset items into rows.
  • MCP / agents: limited permissions, no Standby mode, pay-per-event only.

Limits and honest gaps

  • JavaScript-only sites may return little text. There is no Playwright fallback, on purpose: a browser would make the flat domain price unpredictable.
  • The crawler is polite (robots.txt, a short delay, low concurrency) and will record blocked instead of hammering a site.
  • Industry and company size are model judgments. unknown is a valid size signal.
  • Email and phone coverage will miss obfuscated addresses (info [at] acme.com written as an image, or assembled by JavaScript).

Local development

npm install
npm test
npm run e2e

npm run e2e crawls a few public sites with the mock model and refreshes examples/sample-output.json. Set GEMINI_API_KEY (and optionally OPENAI_API_KEY) to use a real model. See PUBLISHING.md for Store setup, secret env vars, and the exact pay-per-event prices.