How to Extract Business Emails and Social Profiles at Scale with the Website Scraper API

Data teams and B2B marketers with domain lists can extract direct business emails, phone numbers, LinkedIn, Instagram, Facebook, and WhatsApp links from thousands of websites in a single API call — no headless browser, no proxy infrastructure required.

Why Scraping Contact Pages at Scale is Hard

Modern business websites are a contact extraction nightmare. The same company may protect its email behind Cloudflare's email obfuscation (data-cfemail), render its contact form dynamically via JavaScript, bury phone numbers in image-alt text, and list its LinkedIn company page only on a hidden /about-us subpage.

Cloudflare Email Obfuscation

Millions of sites encode mailto links with Cloudflare's data-cfemail attribute. Raw regex scrapers return garbage characters. Bolt Scraper includes a full CF email decoder and handles all obfuscation variants.

Contact Data on Subpages

Most businesses do not list their direct email on the homepage. It lives on /contact, /about, or /team. A homepage-only scraper misses 60–80% of available contact data.

Noise vs. Signal Emails

Raw scrapers return noreply@, support@, postmaster@, and image filenames masquerading as emails. Manual filtering adds hours to every export.

This is precisely why teams building B2B prospecting data at scale don't write custom scrapers for each site — they use a purpose-built API that handles all of these edge cases automatically. The Bolt Scraper Website Scraper API accepts up to 10,000 URLs per job and returns a structured JSON record for each domain, including filtered emails, phones, and extracted social profile links.

Sending Bulk URLs in a Single POST Request

The core endpoint accepts an array of URLs and immediately queues them for parallel cloud extraction. You do not need to loop through domains one by one — the entire list ships in one call, and the scraper handles concurrency for you.

POST /api/v1/website/jobs — Submit bulk URL list
POST https://boltscraper.com/api/v1/website/jobs
Authorization: Bearer bs_YOUR_API_KEY
Content-Type: application/json

{
  "urls": [
    "https://example-co.com",
    "https://demo-roofing.com",
    "https://sunsetshingles.net",
    // ... up to 10,000 URLs
  ]
}

The API responds immediately with a job_id. Scraping runs asynchronously in the cloud. You can either poll for completion or — far more efficiently — register a webhook that fires as soon as your batch finishes.

201 Created — Immediate response
{
  "success": true,
  "job_id": "job_a3f8c2...",
  "job_name": "Q4 Outreach — Roofing Companies",
  "total_urls": 2847,
  "status": "scraping"
}
URL Normalization

The API automatically normalizes your input: strips trailing slashes, adds https:// to bare domains, and deduplicates identical URLs before queuing. You can pass raw exports from Apollo or Crunchbase without pre-processing.

Deep Subpage Crawling — Finding /contact, /about, and /team

For every URL submitted, the scraper performs a multi-stage crawl. It starts on the root page and then automatically discovers and follows the contact, about, and team subpages for that domain. This is where 60–80% of direct sales contacts live.

Subpage Discovery

The crawler parses every outgoing link from the root page and classifies them using keyword pattern matching:

  • contactPageUrl — /contact, /contact-us, /reach-us
  • aboutPageUrl — /about, /about-us, /our-story
  • teamPageUrl — /team, /people, /leadership, /staff
Multi-Stage Extraction

Once subpages are discovered, a second scrape pass fetches each one and merges the results. Emails found on /contact are ranked higher than emails regex-matched from body text — so the most intentionally-placed contacts always surface first in email_1.

The resulting record for each URL contains up to three deduplicated emails and two phone numbers, plus all discovered social links, already classified and ready to use:

GET /api/v1/website/jobs/:jobId — single result record
{
  "url":             "https://example-co.com",
  "page_title":       "Example Co",
  "meta_description": "Expert roofing services in Phoenix, AZ",

  // Up to 3 deduplicated emails
  "email_1": "[email protected]",
  "email_2": "[email protected]",
  "email_3": "",

  // Up to 2 phone numbers
  "phone_1": "+15550100192",
  "phone_2": "",

  // Social media — direct profile URLs
  "linkedin_url":   "https://linkedin.com/company/acme-roofers",
  "facebook_url":   "https://facebook.com/example-co",
  "instagram_url":  "https://instagram.com/example_co",
  "twitter_url":    "",
  "youtube_url":    "",

  "status":      "success",
  "scraped_at":  "2026-09-19T11:30:00.000Z"
}

Smart Email Filtering — Direct Contacts Only

Raw scrapers return hundreds of junk email addresses per domain: server notification addresses, CMS system addresses, placeholder addresses from contact form plugins. The Bolt Scraper engine applies a multi-layer filtering stack automatically before returning any email.

Email Pattern Action Reason
noreply@, no-reply@, donotreply@ ❌ Filtered Auto-sending addresses that never receive replies
postmaster@, mailer-daemon@ ❌ Filtered Server-level system addresses
Dummy domains: example.com, test.com, yourdomain.com ❌ Filtered Template/CMS placeholder emails
Files mistaken for emails: [email protected] ❌ Filtered CSS/JS filenames that match email regex
[email protected], [email protected] ✅ Kept Real business contacts on company domains
Cloudflare-encoded emails (decoded) ✅ Kept CF obfuscation reversed before filtering

This means every email in your results file is a real, deliverable business address that was deliberately placed on the site. Your cold outreach bounce rate drops to near zero before you even hit a verification service.

What Social Platforms Are Extracted

Beyond emails, the scraper parses every outgoing link in the page HTML and classifies social profile URLs by platform. All 12 major platforms are detected and returned as separate fields in your result:

B2B Social Channels
  • LinkedIn — company/slug or in/slug profiles
  • Facebook — business page URLs
  • Twitter / X — twitter.com and x.com handles
  • YouTube — channel, user, and @handle URLs
  • GitHub — organisation and user profiles
Direct Messaging Channels
  • Instagram — business profile links
  • WhatsApp — wa.me, api.whatsapp.com, wa.link
  • 📱TikTok — tiktok.com/@handle
  • 💬Telegram — t.me and telegram.me links
  • 📌Pinterest — business profile boards

End-to-End Example: Enriching 500 Domains

Here's a complete Python example that submits 500 domains, polls for completion, and then saves the enriched contacts to a CSV:

enrich_domains.py
import requests, time, csv

API_KEY  = "bs_YOUR_API_KEY"
BASE_URL = "https://boltscraper.com/api/v1/website"
HEADERS  = {"Authorization": f"Bearer {API_KEY}"}

# 1 — Submit the batch
domains = ["example-co.com", "demo-roofing.com", ...]  # your domain list

r = requests.post(f"{BASE_URL}/jobs", headers=HEADERS, json={
    "job_name": "Q4 Roofing Enrichment",
    "urls": domains
})
job_id = r.json()["job_id"]
print(f"Job created: {job_id}")

# 2 — Poll until complete
while True:
    status = requests.get(f"{BASE_URL}/jobs/{job_id}", headers=HEADERS).json()
    job = status["job"]
    print(f"  {job['processed_count']}/{job['total_urls']} processed")
    if job["status"] == "COMPLETED":
        break
    time.sleep(15)

# 3 — Fetch results and save to CSV
results_csv = requests.get(
    f"{BASE_URL}/jobs/{job_id}/download",
    headers=HEADERS
)

with open("enriched_contacts.csv", "wb") as f:
    f.write(results_csv.content)

print(f"✅ Results saved to enriched_contacts.csv")
Prefer Webhooks Over Polling

For production workflows, replace the polling loop above with a webhook. Read the Website Scraper Webhooks guide to set up an automated webhook callback that delivers a signed CSV download URL when your job completes — no polling loop, no wasted compute.

Website Scraper API Series

Part of the Website Scraper Playbook

Explore all five guides in this topic cluster to build a complete contact enrichment and monitoring pipeline:

Start Extracting Business Contacts at Scale

Submit 10,000 domains in one API call. Get business emails, phones, LinkedIn, Instagram, and Facebook links — automatically filtered and ready for your outreach tool.

No Credit Card Required Free Credits Included CF Email Decoding Built-In

Instant cloud setup • CSV & JSON export • Test live website scraper for free & view docs

Frequently Asked Questions

The API fetches raw HTML and applies deep pattern extraction including Cloudflare email deobfuscation, data-email attributes, and obfuscated "name [at] domain.com" formats. For pure client-side-rendered SPAs that return empty HTML, results will be limited to what's available in the initial server response and metadata.

Generic catch-all prefixes like info@, admin@, and hello@ are kept — these are legitimate business inboxes. Only non-deliverable system addresses (noreply@, postmaster@, mailer-daemon@) and placeholder domains (example.com, yourdomain.com) are filtered out automatically.

Up to 10,000 URLs per job. For larger lists, split into multiple jobs and listen for the website_job.completed webhook event on each. Credits are deducted per URL processed.

Yes. Hit GET /api/v1/website/jobs/:jobId/download to receive a CSV file with all result columns. Webhook payloads also include a signed download_csv_url that's valid for 24 hours and works from n8n, Make.com, or any automation platform.