Website Email Phone Contacts Scraper
Pricing
from $0.36 / 1,000 page returneds
Website Email Phone Contacts Scraper
Website email phone contacts scraper reads your list of URLs and returns each site's emails, phones, socials, forms, contact_page_url, field_provenance and status on every row.
Pricing
from $0.36 / 1,000 page returneds
Rating
0.0
(0)
Developer
Pradio Actors
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
What does Website Email Phone Contacts Scraper do?
Website Email Phone Contacts Scraper reads the contact pages on your list of URLs and returns one row per site. Each row carries the emails, phone numbers, social profiles and contact forms the site publishes. Per-field provenance names the page behind every value. Paste the list and press Start. Each site lands in your dataset as it is read. A site that yields nothing costs nothing. Its row says why.
In a measured run over 116 sites the Actor had never visited, 49% returned contact details over plain HTTP. No login and no browser are needed. Each data row carries 33 fields. An empty cell is an answer rather than a shrug. status names the verdict. field_provenance names where each value came from. A returned page costs $0.0016.
Who uses Website Email Phone Contacts Scraper
| Who | What they run it for |
|---|---|
| Lead-list builders | Turn a list of prospect domains into email and phone columns for a campaign. |
| Lead-gen agencies | Hand clients a contact sheet where every miss carries its reason. |
| Sales-ops teams | Add direct contact points to account lists before an outreach push. |
| Solo founders | Get a niche contact list without maintaining a personal script. |
Features
- Contact page discovery. Reads the page you give it. It then follows the contact, about, imprint, team and support links the site itself offers. When no link is offered it tries the common paths.
/contactand/aboutare among them. - Deobfuscation built in. It decodes masked
data-cfemailaddresses andname [at] site [dot] comsubstitutions. It also decodes emails assembled inside JavaScript or base64 strings. - Phones split by confidence.
tel:links, structured phone keys and phone-named attributes land inphones. Digit strings that pass the shape check join them. The rest go tophonesUncertainfor review instead of being silently trusted. - Thirteen social networks. Links are lifted from each page: LinkedIn, X (Twitter), Instagram, Facebook, YouTube, TikTok and Pinterest. Also Discord, Snapchat, Threads, Telegram, Reddit and WhatsApp.
- Provenance on every value.
field_provenancenames the page behind each email, phone and profile on the row, and the reading method that read it. - Contact forms captured. When a site offers a form instead of an address,
form_action_urlcarries where that form posts. The site is still reachable. - One row per site, or one per page.
mergeContactsfolds every page a site answers into a single row. Switched off, each fetched page is its own row with its own verdict. - Robots.txt honoured per host. A path the site disallows is never requested. A refused read ends that site as
blockedrather than being pushed past. - A second arm for a dead address. A site that fails at the network level gets one retry. The other form of the host is tried: apex to
wwwor the reverse. Only then is it called a miss. - Proxy support. Runs through Apify Proxy by default and accepts your own proxy URLs.
- Crawl controls.
maxDepth,maxRequestsPerStartUrl,maxRequests,sameDomainandconsiderChildFramesbound how deep each site is read and how its rows are shaped.
What you can count on
- You pay only for rows whose status is
found. A site the run cannot answer comes back as an unchargedITEM_STATUSrow. It names the entry and the verdict. - Every row is charged only after it is written to your dataset. A row you cannot see is never billed.
- A run that finds nothing returns one
NO_CONTACTS_FOUNDrow that says so. It is never an empty dataset. - A spending limit stops the run cleanly. A
STOPPED_EARLYrow says how many rows came back and how many were left out. - Every run writes a
RUN_SUMMARYentry to the key-value store:rowsFetched,rowsPushed,rowsChargedandduplicatesDropped, so a short run and a broken one are told apart. - If the run's own machinery changes what it answers, the run fails with the error in the log. A fault past the per-site boundary is not one site's miss, and a partial set is never returned as though it were whole.
- No value is invented. A field the page does not show stays empty. This page says which fields fill rarely.
Why this one
The most-used alternative on this platform was run on one of the three sites on the prefilled list, the carbonvisuals.com contact page, on 2026-09-20. Each Actor returned one row for it. What the two rows showed:
- Its
phonescolumn was empty. The number sat inphonesUncertainbeside four strings that are not phones. This Actor filed+44 (0)7973 641131underphones, where a dialable number belongs. - Its row names no page per value. The pages it read sit in one
scrapedUrlslist, and it carries nourlorreferrerUrl. Every value here names its page and carrier infield_provenance. - It reported a Twitter profile the site never publishes, assembled from an unrelated Flickr account's screen name. Its
youtubescounted embedded video players as channel links. This Actor does not infer handles. A field the page does not publish stays empty. - The links it did file sat under the bare-plural names. Its canonical
Profilescolumns are its paid enrichment, off by default and empty. This Actor fills the bare plurals and the canonical forms beside them. - Its price is $0.002 a row. It adds a $0.001 start fee on every run. This Actor charges $0.0016 for a returned page and nothing for a miss. It adds no start fee beyond Apify's platform charge. Start fees billed on this shelf run from $0.00005 to $0.001 a run.
On 116 sites the Actor had never visited, 49% returned contact details. The measurement ran without a browser, so the figure is conservative. Every miss came back a named verdict. 23 blocked, 16 fetch_failed, 10 js_required, 6 none_published and 4 form_only.
What data does Website Email Phone Contacts Scraper return?
One row per site on your list. With mergeContacts off, one row per fetched page instead. This is a real row, abbreviated, from the prefilled example:
{"originalStartUrl": "https://www.cas.org/contact","domain": "cas.org","url": "https://www.cas.org/pt-br/contact","referrerUrl": "https://www.cas.org/contact","emails": ["help@cas.org", "apachelp@acs-i.org", "china@acs-i.org", "jsingh@acs-i.org", "cisobe@acs-i.org", "EMEAhelp@cas.org", "cas-pr@cas.org"],"phones": ["+18007534227", "+16144473731", "+65-3125-2705", "+61-2-8550-2646", "+82-70-4732-6766", "+86-10-62508026/7", "+81-3-5456-5696", "+49-721-95-883-155", "+86-10-62508026"],"phonesUncertain": ["117260204", "100-6162"],"linkedIns": ["https://www.linkedin.com/company/cas"],"facebooks": ["https://www.facebook.com/CAS"],"facebookProfiles": ["https://facebook.com/CAS"],"twitters": ["https://www.twitter.com/CASChemistry"],"twitterProfiles": ["https://twitter.com/CASChemistry"],"youtubes": ["https://www.youtube.com/user/ChemAbstractsService"],"youtubeProfiles": ["https://youtube.com/user/ChemAbstractsService"],"contact_page_url": "https://www.cas.org/pt-br/contact","extraction_method": "mailto+tel+json-ld+js-data+text+href","field_provenance": {"emails": [{ "value": "help@cas.org", "page": "https://www.cas.org/contact", "method": "mailto" },{ "value": "apachelp@acs-i.org", "page": "https://www.cas.org/contact", "method": "mailto" },{ "value": "china@acs-i.org", "page": "https://www.cas.org/contact", "method": "mailto" },{ "value": "jsingh@acs-i.org", "page": "https://www.cas.org/contact", "method": "mailto" },{ "value": "cisobe@acs-i.org", "page": "https://www.cas.org/contact", "method": "mailto" },{ "value": "EMEAhelp@cas.org", "page": "https://www.cas.org/contact", "method": "mailto" },{ "value": "cas-pr@cas.org", "page": "https://www.cas.org/contact", "method": "mailto" }],"phones": [{ "value": "+18007534227", "page": "https://www.cas.org/contact", "method": "tel" },{ "value": "+16144473731", "page": "https://www.cas.org/contact", "method": "tel" },{ "value": "+65-3125-2705", "page": "https://www.cas.org/contact", "method": "tel" },{ "value": "+61-2-8550-2646", "page": "https://www.cas.org/contact", "method": "tel" },{ "value": "+82-70-4732-6766", "page": "https://www.cas.org/contact", "method": "tel" },{ "value": "+86-10-62508026/7", "page": "https://www.cas.org/contact", "method": "tel" },{ "value": "+81-3-5456-5696", "page": "https://www.cas.org/contact", "method": "tel" },{ "value": "+49-721-95-883-155", "page": "https://www.cas.org/contact", "method": "tel" },{ "value": "+86-10-62508026", "page": "https://www.cas.org/contact", "method": "json-ld" }],"phonesUncertain": [{ "value": "117260204", "page": "https://www.cas.org/contact", "method": "js-data" },{ "value": "100-6162", "page": "https://www.cas.org/contact", "method": "text" }],"linkedIns": [{ "value": "https://www.linkedin.com/company/cas", "page": "https://www.cas.org/contact", "method": "href" }],"twitters": [{ "value": "https://www.twitter.com/CASChemistry", "page": "https://www.cas.org/contact", "method": "href" }],"instagrams": [],"facebooks": [{ "value": "https://www.facebook.com/CAS", "page": "https://www.cas.org/contact", "method": "href" }],"youtubes": [{ "value": "https://www.youtube.com/user/ChemAbstractsService", "page": "https://www.cas.org/contact", "method": "href" }],"tiktoks": [],"pinterests": [],"discords": [],"snapchats": [],"threads": [],"telegrams": [],"reddits": [],"whatsapps": []},"form_action_url": "https://www.cas.org/contact","obfuscated": false,"depth": 1,"status": "found","row_type": "ROW"}
Contact columns
| Field | Type | What it carries and where it is read |
|---|---|---|
emails | array | Email addresses read from the site: page text, mailto: links and decoded obfuscated forms. |
phones | array | Phone numbers carried by tel: links, structured data or canonical phone-shaped text. |
phonesUncertain | array | Digit strings that could be phone numbers but carry no phone marker; glance before dialling. |
form_action_url | string | The action URL of the contact form the site publishes, when there is one. |
Social columns
Each page's outbound profile links land in two spellings. The bare plural keeps the link as the site published it. The five Profiles fields carry the canonical form. Scheme- and www-normalised, x.com folded to twitter.com, duplicates collapsed.
| Field | What it carries |
|---|---|
linkedIns | LinkedIn company or profile links the site publishes, as published. |
twitters | X (Twitter) links the site publishes, as published; twitterProfiles carries the canonical form. |
instagrams | Instagram links the site publishes, as published; instagramProfiles carries the canonical form. |
facebooks | Facebook page links the site publishes, as published; facebookProfiles carries the canonical form. |
youtubes | YouTube channel links the site publishes, as published; youtubeProfiles carries the canonical form. |
tiktoks | TikTok profile links the site publishes, as published; tiktokProfiles carries the canonical form. |
pinterests | Pinterest profile links the site publishes, as published. |
discords | Discord server invite links the site publishes. |
snapchats | Snapchat profile links the site publishes. |
threads | Threads profile links the site publishes. |
telegrams | Telegram channel or user links the site publishes. |
reddits | Reddit community or profile links the site publishes. |
whatsapps | WhatsApp contact links (wa.me) the site publishes. |
facebookProfiles | Canonical Facebook page URLs: scheme- and www-normalised, duplicates collapsed. |
instagramProfiles | Canonical Instagram profile URLs: scheme- and www-normalised, duplicates collapsed. |
youtubeProfiles | Canonical YouTube channel URLs: scheme- and www-normalised, duplicates collapsed. |
tiktokProfiles | Canonical TikTok profile URLs: scheme- and www-normalised, duplicates collapsed. |
twitterProfiles | Canonical X (Twitter) profile URLs: scheme- and www-normalised, x.com folded to twitter.com, duplicates collapsed. |
Where the row came from
| Field | Type | What it carries |
|---|---|---|
originalStartUrl | string | The start URL this row came from: your input entry. Exact duplicates on it are dropped before charging. |
domain | string | The site you named in the input; a row keys back to your list through this even when the site redirects elsewhere. |
url | string | The page this row was read from. |
referrerUrl | string | The page that linked to this row. |
depth | number | The link depth this row was reached at: a URL you gave is depth zero, a page it links to is one. |
contact_page_url | string | The contact page the site itself publishes, when one was found. |
Evidence columns
| Field | Type | What it carries |
|---|---|---|
extraction_method | string | Which readers produced this row: text, mailto:/tel: links, JSON-LD, data attributes, same-host frames, decoded obfuscation. |
field_provenance | object | Per field, where each value was read: the page and the carrier (link, text, structured data). |
obfuscated | boolean | True when the page hides its contacts behind obfuscation: masked emails, [at]/[dot] spellings or JavaScript-assembled addresses. |
Status columns
| Field | Type | What it carries |
|---|---|---|
status | string | found on a data row; on an ITEM_STATUS row it is the miss verdict. |
row_type | string | ROW, ITEM_STATUS, NO_CONTACTS_FOUND or STOPPED_EARLY. See Output below. |
reason | string | Status rows only: why the run returned no rows, or why it stopped early. |
rowsFetched | integer | Status rows only: how many rows the source handed over before de-duplication and the cap. |
rowsReturned | integer | Status rows only: how many data rows are in the dataset (0 on an empty result; the count before the charge limit on STOPPED_EARLY). |
rowsRemaining | integer | Status rows only: how many fetched rows were not returned (0 on an empty result). |
How often fields fill, measured on the 57 sites that resolved out of the 116-site run. The row-level columns fill on every resolved row. That is url, domain, originalStartUrl, status, extraction_method, field_provenance, obfuscated and depth. contact_page_url and referrerUrl filled on 91.2%, form_action_url on 75.4%. In the contact columns, phonesUncertain filled on 91.2%, phones on 80.7% and emails on 64.9%. In the social columns, facebooks and facebookProfiles filled on 78.9%, instagrams and instagramProfiles on 63.2%, twitters and twitterProfiles on 59.6%, youtubes and youtubeProfiles on 61.4%, and linkedIns on 57.9%. tiktoks and tiktokProfiles and pinterests filled on 14%, discords and threads on 3.5%. snapchats, telegrams, reddits and whatsapps filled on no resolved row. An empty array means the fetched pages carried no such link. It does not mean the read failed. Outside the four niche networks above and the status-only fields, every declared field filled on at least one captured row. The dataset's Overview view shows the headline contact columns. Switch to the All fields view for every column above.
How much does it cost?
Pricing for this Actor is pay per event: $0.0016 per returned page, the page-returned event on your invoice. One charge for each row of contact details written to your dataset. The charge lands only after the row exists. Status rows, dropped duplicates and rows past your spending limit are never charged. With mergeContacts on, a site folds into one row. It costs one charge no matter how many of its pages were read.
Apify also bills its own start charge on every run, the apify-actor-start event at $0.00005 per gigabyte of memory allocated, a fraction of a cent. This Actor adds no start fee of its own.
What a list costs at the measured 49% fill:
| Sites you paste | Sites expected to answer | You pay | If every site answers |
|---|---|---|---|
| 100 | about 49 | about $0.08 + the start charge | $0.16 + the start charge |
| 1,000 | about 491 | about $0.79 + the start charge | $1.6 + the start charge |
| 10,000 | about 4,914 | about $7.86 + the start charge | $16 + the start charge |
In list terms: paste 100 URLs and roughly 49 sites answer. The run costs about $0.08 plus the start charge. Every miss is a free status row. Paste 1,000 URLs and roughly 491 answer, about $0.79 plus the start charge. A run where nothing answers produces one NO_CONTACTS_FOUND row. It costs the start charge alone.
To spend less, keep maxItems low while testing. Split a big list into smaller runs. Set a spending limit in the Console before a long run. A limit ends the run with a STOPPED_EARLY row, not a surprise bill.
How do I use Website Email Phone Contacts Scraper?
- Open this Actor's Store page and press Start (or Try for free).
- Paste your websites into Start URLs, one entry per site. The three prefilled entries are a working example.
- Press Start. Rows appear in the Dataset tab as each site is read.
- Export the dataset as JSON, CSV or Excel, or read it through the API.
A minimal input looks like this:
{"startUrls": [{ "url": "https://www.carbonvisuals.com/contact" },{ "url": "https://www.cas.org/contact" },{ "url": "https://www.acxiom.com/contact-us/" }],"proxyConfig": { "useApifyProxy": true },"maxItems": 100}
The same run through the Apify API:
curl -X POST "https://api.apify.com/v2/acts/Pradio~website-email-phone/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"startUrls":[{"url":"https://www.cas.org/contact"}],"proxyConfig":{"useApifyProxy":true}}'
Input
| Input | Type | Default | What it does |
|---|---|---|---|
startUrls | array | three example sites | The websites to read, one entry per site. Required. |
proxyConfig | object | { "useApifyProxy": true } | Where requests come from. Required; Apify Proxy by default. |
maxItems | integer | 100 | The most rows one run returns. The run stops there and says so. |
maxDepth | integer | 1 | How far to follow the site's own links looking for contact pages. 1 reads the start page plus pages it links to. |
maxRequestsPerStartUrl | integer | 8 | The most pages fetched for one site, counting the start page and the contact pages it leads to. |
maxRequests | integer | no cap | A fetch budget shared across the whole run; leave unset for no cap. |
sameDomain | boolean | on | Only follow links on the site's own host. Off lets contact links pointing elsewhere be followed too. |
mergeContacts | boolean | on | Fold every fetched page of a site into one row. Off gives one row per fetched page. |
considerChildFrames | boolean | off | Also read same-host embedded frames, contacts living inside an iframe on the page, up to three per page. |
scrapeSocialMediaProfiles | object | all networks on | Per-network switches. A network set to false is not extracted; unset reads them all. |
startUrls
Every distinct entry produces a row. A bare domain, a full URL or a contact page deep-link all work. A missing scheme is assumed to be https. An entry that cannot be parsed comes back as a bad_url status row naming it. It is never silently dropped. If a site's address fails at the network level, the other form of the host is tried once. Apex becomes www, or www becomes apex. Only then is the site called a miss.
mergeContacts
On by default. Every page fetched for a site folds into one row. A site is one line in your export and one charge. Set it off and each fetched page becomes its own row with its own verdict. That is useful when you want to see which page of a site carries the contacts.
scrapeSocialMediaProfiles
All thirteen networks are collected by default. Set any single network to false to skip it, for example { "tiktoks": false }. Or pass { "enabled": false } to skip social links entirely.
proxyConfig
Requests go through Apify Proxy by default. Residential proxies help where a site quietly drops or throttles datacenter traffic without an explicit refusal. Supply your own proxyUrls to send requests through your own addresses. Or set useApifyProxy to false for direct fetching. The proxy spreads load. It is never used to push past a refusal. A 401, 403 or 429 ends the site as blocked either way.
Output
Every row carries row_type, which kind of line it is:
row_type | What it means |
|---|---|
ROW | A data row, billed after it is written to the dataset. |
ITEM_STATUS | A per-site miss: the full row shape with status naming the verdict, pushed so you see it, never charged. |
NO_CONTACTS_FOUND | One row for a run where nothing answered; reason says so. Never charged. |
STOPPED_EARLY | One row when the charge limit ended the run, carrying rowsReturned and rowsRemaining. Never charged. |
The status verdicts a row can carry:
status | What it means |
|---|---|
found | The row carries contact details: an email or a phone. This is the billed verdict. |
armored | The page hides its contacts behind obfuscation that did not decode. |
form_only | The site offers a contact form and nothing else; form_action_url says where it posts. |
none_published | The pages answered but publish no email, phone or contact form. A none_published row can still carry social links it found, since found asks for an email or a phone. |
fetch_failed | The site did not answer: a network-level miss on both host arms, an HTTP error that is not a refusal, or a page that gave no answer in 20 seconds. |
blocked | The site refused the read: a 401, 403 or 429, or a robots.txt disallow. Never retried past. |
bad_url | The entry could not be parsed as a URL. |
js_required | Every fetched page answered a thin JavaScript shell with no visible rendered text. A shell's markup can still carry links and embedded strings, and those land on the row. |
The declared vocabulary also covers not_found, bad_input, timeout, aborted, error and failed for misses of those shapes. This Actor's misses land on the verdicts above. Anything other than found is an uncharged ITEM_STATUS row.
Here is a real miss mix from the measured run over 116 sites the Actor had never visited. 57 sites returned contact details. 23 came back blocked, 16 fetch_failed, 10 js_required, 6 none_published and 4 form_only. That is the shape a first run on a fresh list usually takes. Just under half answer, and the rest name their reason.
Every run also writes RUN_SUMMARY in the default key-value store. Its fields are rowsFetched, rowsPushed, rowsCharged, rowsUncharged, duplicatesDropped and stoppedEarly. As a worked example, paste 50 URLs and suppose 47 sites answer with contacts. The dataset holds 47 billed data rows and 3 uncharged status rows. RUN_SUMMARY shows 50 fetched. A zero result means the source answered and had nothing. It is one status row, not an empty dataset and not an error.
What can you do with the data?
A lead-list builder pastes a list of 100 prospect domains. She exports the dataset to CSV and loads emails and phones straight into the campaign sheet. The ITEM_STATUS rows tell her which misses were blocked and which simply publish nothing. She stops re-checking the dead ends by hand.
An agency researcher runs a client's prospect list before a pitch. field_provenance lets him cite the exact page behind every email and phone number. That answers the client who asks where the data came from.
A sales-ops person enriches an account list before an outreach push. phones feeds the dialer. phonesUncertain is flagged for a human glance. obfuscated marks the sites that hide their contacts, worth a manual look.
A founder building a partner list filters status for found. She then opens form_action_url on the form_only sites and uses their contact forms directly. Nothing on the list is a mystery. Every site either produced a value or named why it did not.
Use Website Email Phone Contacts Scraper with AI agents
claude mcp add --transport http apify "https://mcp.apify.com?tools=Pradio/website-email-phone"
One line registers this Actor with the Apify MCP server. Your agent can then run it and read the rows it returns.
Personal data
Each row is the email addresses, phone numbers and social profile links that one page you named displays. Those details can identify private individuals, not only businesses. Data protection law can apply to what your run collects.
You are the controller of the data your run collects. That means informing data subjects who you are and which page their details came from. It means telling them what you will use the data for and what their rights are. It also means honouring objection and deletion requests.
Anyone can ask for the exclusion of their page and the deletion of their rows. Open an issue on this Actor's Issues tab and the request will be honoured.
The Actor's own conduct stays narrow. Logged-out reads only, one page per request until the cap. A robots.txt disallow or a 403 ends the read of that page as blocked. No retry past a refusal. No login or credential. No wall defeated. No proxy used to bypass one. Only the contact points a page itself displays are collected. There is no enrichment, inference or aggregation across pages beyond the list you named. maxItems defaults to 100 rows per run.
Release notes
- 0.1.9 (2026-09-20): first public version.
Limits
- Server-rendered HTML only. Pages that render their content only under a browser answer a thin script shell. They come back
js_required. The Actor does not bundle a renderer. - Refusals are respected. A
401,403or429, or a robots.txt disallow, ends that site asblocked. It is not retried past and not routed around. - The per-site crawl is shallow. At most
maxDepthhops off the start page (default one) andmaxRequestsPerStartUrlpages per site. Fetches on one site are paced. A site that buries its contacts deeper is a miss, not an exception. - Niche networks stay empty on most rows.
tiktoksandpinterestsfilled on 14% of resolved rows,discordsandthreadson 3.5%.snapchats,telegrams,redditsandwhatsappsfilled on no resolved row. An empty array is the honest answer when the pages carry no such link. phonesUncertainis a review pile, not a dial list. It holds digit strings with no phone marker. Dates or IDs can land in it. Look before you load it anywhere.- Very large pages are read in part. Only the first portion of a fetched page is read. A heavier page's tail is not seen.
- One request waits twenty seconds. A page that does not answer in time ends the site as
fetch_failed. - Errors run toward visible misses. A site that fails becomes a status row. A value that is not there stays empty.
maxItemscaps a run at 100 rows by default. Raise it for bigger lists. Or set a spending limit and readSTOPPED_EARLYwhen it binds.
Troubleshooting
I pasted a list of URLs but got back fewer data rows. Every distinct entry produces a row. Misses come back as ITEM_STATUS rows naming the entry and the verdict. blocked, js_required, fetch_failed and the rest. They are never billed. Exact duplicate entries are dropped before charging and counted as duplicatesDropped in RUN_SUMMARY.
My run returned a single NO_CONTACTS_FOUND row. Every site missed. The reason field says the source answered and had nothing. Nothing was billed beyond the start charge. Check that the URLs load for you in a browser first.
A site came back js_required. Its pages answered a JavaScript shell with no visible text. The Actor reads server-rendered HTML over plain HTTP and does not bundle a browser.
My phonesUncertain column contains dates and ID-shaped numbers. That column is the review pile by design. Anything a tel: link or a structured field did not vouch for lands there instead of in phones. Confident numbers are not diluted, and the maybes are not lost.
The run ended with a STOPPED_EARLY row. Your spending limit was reached. rowsReturned and rowsRemaining on that row say how much came back and how much was left. Raise the limit and re-run to see the rest.
Something else off? Open an issue on this Actor's Issues tab.
FAQ
Can I use integrations with Website Email Phone Contacts Scraper? Yes. It is an Apify Actor. Schedules, webhooks and Apify's integrations for tools like Zapier, Make and Google Sheets all work with it. The dataset exports as JSON, CSV, Excel or XML.
Can I use Website Email Phone Contacts Scraper with the Apify API?
Yes. The curl example above starts a run and returns the dataset items. Runs, datasets and key-value store entries are all reachable through the API.
Can I use Website Email Phone Contacts Scraper through an MCP server? Yes. Register the Apify MCP server with the line in the AI-agents section. This Actor becomes a tool your agent can call.
Is it legal to scrape websites for contact details? This Actor reads only pages the sites themselves publish. It honours each host's robots.txt, stops on a refusal, and never logs in or works around a block. Whether collecting the data fits your purpose depends on your jurisdiction and use. The rows can identify private individuals. Read the Personal data section first.
See also
- Imprint Contact Scraper: reads the legal and imprint pages on company websites. It returns the contact details the law requires them to publish. The regulated counterpart of this Actor, same row shape.
- Broken Link Checker: scans the same sites for dead links and broken pages. A site-health complement that reads a URL list the same way.
Not affiliated
Website Email Phone Contacts Scraper is an unofficial tool. It is not affiliated with, sponsored or endorsed by any of the websites it is pointed at. Each site belongs to its owner. You choose which pages it reads.