Local Business Email Finder
Pricing
from $1.13 / 1,000 results
Local Business Email Finder
Find local businesses by niche and city and get name, address, category, website, public emails and phone numbers. Built on OpenStreetMap plus each business's own website, up to 50 businesses per run. Emails are found for some businesses, not all. No login or API key needed.
Pricing
from $1.13 / 1,000 results
Rating
0.0
(0)
Developer
Axiom Works
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
2
Monthly active users
6 days ago
Last modified
Categories
Share
Business Email Scraper
Returns: one row per local business with name, city, category, website, emails, phones and osmUrl.
Input: {"query": "coffee", "location": "Austin, TX", "maxItems": 5}
Best for: local lead lists, agency prospecting, outreach research.
{"name": "Cuppa Austin Coffee", "city": "Austin", "category": "amenity / cafe", "website": "https://www.cuppaaustin.com/", "emails": ["info@cuppaaustin.com"], "phones": ["+15123826729"], "osmUrl": "https://www.openstreetmap.org/node/11111850805"}
What does Business Email Scraper do?
Business Email Scraper finds local businesses for a niche and a city, then collects each business's website, public email addresses and phone numbers. Enter a niche such as "coffee" or "dentist" and a location such as "Austin, TX", and you get one dataset row per business with name, street, postcode, coordinates, category, website, emails and phones. Export the result as JSON, CSV or Excel. The input is a niche and a city; the Actor does not accept a list of website URLs.
Map data © OpenStreetMap contributors (ODbL).
The business list comes from OpenStreetMap (through the Photon geocoder and the Overpass API), not from Google Maps. The Actor reads the website, phone and email tags that OpenStreetMap contributors have added to each place. When a business has no website tag, it tries to find one with a web search, and then reads the homepage and up to two same-host contact pages linked from the homepage (including Kontakt, Contacto and Contato links), falling back to /contact and /contact-us for public emails and phone numbers. No login, cookies or API key are needed. Website checks run in parallel, with each batch capped to the remaining result slots and spending limit. If contact filters reject a business, the Actor checks more candidates until it reaches the requested limit or its existing time budget.
What data can you get?
| Field | Description | Example |
|---|---|---|
id | Stable id: OpenStreetMap element type and id | node/11111850805 |
sourceUrl | Page the row was read from: the business website when found, otherwise its OpenStreetMap page | https://www.cuppaaustin.com/ |
name | Business name from OpenStreetMap (max 150 characters) | Cuppa Austin Coffee |
street | Street name, without house number. Null if unknown | West Parmer Lane |
houseNumber | House number from OpenStreetMap. Null if unknown | 9225 |
city | City, or county as fallback. Null if unknown | Austin |
postcode | Postal code. Null if unknown | 78717 |
country | Country name. Null if unknown | United States |
latitude | Latitude in decimal degrees | 30.4780176 |
longitude | Longitude in decimal degrees | -97.7664202 |
category | OpenStreetMap category as key / value | amenity / cafe |
osmUrl | OpenStreetMap page of the business | https://www.openstreetmap.org/node/11111850805 |
website | Business website from OpenStreetMap or found by web search. Null if none | https://www.cuppaaustin.com/ |
websiteSource | How the website was found: osm or search. Null if no website | osm |
emails | Public contact emails, max 10, from OpenStreetMap tags and the website | ["info@cuppaaustin.com"] |
primaryEmail | First returned email, or null when emails is empty; not a verified or owner address | info@cuppaaustin.com |
emailCount | Number of returned email addresses after optional filtering | 1 |
phones | Public phone numbers, max 5, normalised to E.164 where possible | ["+15123826729"] |
socialLinks | Facebook, Instagram, LinkedIn, Twitter/X, YouTube or TikTok profile links found on the business website (null if none) | {"facebook": "https://www.facebook.com/examplecoffee"} |
phonesRaw | The same phone numbers exactly as found | ["5123826729"] |
query | The niche you searched for | coffee |
location | The location you searched | Austin, TX |
scrapedAt | ISO 8601 UTC timestamp of the run | 2026-09-30T18:09:11.915559+00:00 |
For CRM imports, primaryEmail copies the first address in emails, and emailCount counts that array. These fields do not verify deliverability or identify an owner. Set excludeFreeEmailProviders to true to remove common free mailbox providers such as Gmail, Yahoo and Outlook from the returned email list. It defaults to false, preserving the existing output. The filter runs before requireEmail: combining both options skips businesses whose only published address uses an excluded provider. Phones and social links are unaffected, and skipped businesses do not use a result slot.
Phone discovery reads explicit tel: links and visible page text, ignoring phone-like strings inside scripts and styles. OpenStreetMap phone, contact:phone, mobile and contact:mobile tags also supply public numbers; semicolon-separated numbers are split and deduplicated. Website numbers take precedence over OpenStreetMap phone tags when the five-number limit is reached. phonesRaw preserves the selected link or text spelling, while phones normalises it where possible.
The dataset has three views in the Console: "Businesses" (main columns), "Contacts" (name, website, emails, phones and website source) and "Full data" (every field including coordinates and the OpenStreetMap link).
How to use Business Email Scraper
- Open the Actor in Apify Console and go to the Input tab.
- Type a business niche into "Business type or name, e.g. coffee", for example
coffee,pizza,plumberordentist. One or two words work best. - Type a city or area into "City or area, e.g. Austin, TX", for example
Austin, TX. - Set "Business limit, e.g. 5" (1 to 50). Each returned business counts as one result.
- Decide on the filters: turn on "Require public email, e.g. true" to keep only rows with a public email, or "Keep missing contacts, e.g. true" to also keep rows where nothing was found.
- Click Start. Runtime depends on directory and website responses.
- Open the Output tab, pick a view, and export the dataset as JSON, CSV, Excel, XML or HTML.
Input
Set requirePhone to true to keep only businesses with a public phone number. It defaults to false and combines with requireEmail: enabling both requires both contacts. The Actor skips rows that do not satisfy these filters without counting them toward maxItems. A blocked directory lookup ends successfully with no items and a message suggesting another query, location or proxy configuration. Website contact discovery reads no more than two additional pages per business. It follows same-host contact links before guessing standard paths, which also covers nested and translated contact URLs.
| Field | Type | Default / prefill | Description |
|---|---|---|---|
query | string | prefill coffee | The kind of business to find. The search matches business names and OpenStreetMap categories. One or two words work best. Required for the run to do anything. |
location | string | prefill Austin, TX | City or area to search. Results are filtered to businesses whose address matches this location. |
maxItems | integer, 1 to 50 | optional, falls back to maxResults, then 10; prefill 5 | Maximum number of businesses to return. |
excludeFreeEmailProviders | Optional boolean, default false. Remove common free mailbox provider addresses before applying requireEmail | false | |
requireEmail | boolean | default false, prefill false | Only businesses with an email: return and charge only businesses where at least one public email was found. |
requirePhone | boolean | default false | Return only businesses with a public phone number; combine with requireEmail to require both. |
includeWithoutContact | boolean | default false | By default only businesses with at least a website, an email or a phone number are returned. Turn on to also return businesses where nothing was found. |
maxResults | integer, 1 to 50 | default 10 | Legacy alias; used only when maxItems is absent. |
proxyConfiguration | object | default and prefill Apify Proxy on | Optional. Used for website discovery and to retry blocked business pages with fresh sessions. |
If query or location is empty, the run fails right away with a clear message ("input 'query' is required" or "input 'location' is required").
Complete input example:
{"query": "coffee","location": "Austin, TX","maxItems": 20,"requireEmail": true,"includeWithoutContact": false,"proxyConfiguration": {"useApifyProxy": true}}
Output
This item came from a local run with query: "coffee", location: "Austin, TX", maxItems: 1, requireEmail: true and excludeFreeEmailProviders: true:
{"id": "node/11111850805","sourceUrl": "https://www.cuppaaustin.com/","name": "Cuppa Austin Coffee","street": "West Parmer Lane","houseNumber": "9225","city": "Austin","postcode": "78717","country": "United States","latitude": 30.4780176,"longitude": -97.7664202,"category": "amenity / cafe","osmUrl": "https://www.openstreetmap.org/node/11111850805","website": "https://www.cuppaaustin.com/","websiteSource": "osm","emails": ["info@cuppaaustin.com"],"phones": ["+15123826729"],"socialLinks": {"facebook": "https://www.facebook.com/CuppaAustin","instagram": "https://www.instagram.com/cuppaaustincoffee"},"phonesRaw": ["5123826729"],"primaryEmail": "info@cuppaaustin.com","emailCount": 1,"query": "coffee","location": "Austin, TX","scrapedAt": "2026-10-14T06:00:00.630314+00:00"}
When a business has no website, email or phone that could be verified, those fields are null or empty arrays. That is normal: the Actor never guesses or fabricates contact details. websiteSource is osm when the website came from the OpenStreetMap listing and search when it was discovered by web search.
How much does it cost?
The Actor uses pay-per-event pricing: you are charged for each business that is returned in the dataset, and businesses that are skipped are not charged. Turn on "Require public email, e.g. true" to pay only for rows that have an email. See the Pricing tab of the Actor page for the current per-result price.
Use with AI agents (MCP)
You can call Business Email Scraper from any MCP-capable client through Apify's MCP server at mcp.apify.com. The server exposes the tools search-actors and call-actor, so an agent can find this Actor and run it. To load only this Actor as a tool, use this configuration in Claude Desktop, Cursor, VS Code or another MCP client:
{"mcpServers": {"apify": {"url": "https://mcp.apify.com?tools=axiomworks/business-email-extractor"}}}
Example prompts you could type to an agent:
- "Find 10 coffee shops in Austin, TX and give me their websites and contact emails."
- "Get contact details for plumbers in Denver and list the ones that have a public email address."
- "Search for dentists in Leeds and export their phone numbers and websites to a table."
The Actor has typed input and output schemas, so the agent knows the exact fields (query, location, maxItems, requireEmail, requirePhone, includeWithoutContact, excludeFreeEmailProviders) and the structure of each returned business.
Integrations and API
Python, using the apify-client package:
from apify_client import ApifyClientclient = ApifyClient("YOUR_API_TOKEN")run = client.actor("axiomworks/business-email-extractor").call(run_input={"query": "coffee","location": "Austin, TX","maxItems": 10,})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["name"], item["emails"])
JavaScript, using the apify-client package:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });const run = await client.actor('axiomworks/business-email-extractor').call({query: 'coffee',location: 'Austin, TX',maxItems: 10,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
cURL, running the Actor synchronously and returning the dataset items:
curl -X POST "https://api.apify.com/v2/acts/axiomworks~business-email-extractor/run-sync-get-dataset-items" \-H "Authorization: Bearer YOUR_API_TOKEN" \-H "Content-Type: application/json" \-d '{"query": "coffee", "location": "Austin, TX", "maxItems": 10}'
You can send the results to other tools with Apify integrations: Zapier, Make, n8n, Google Sheets, and webhooks that fire when a run finishes. Schedule the Actor to run for different niches or cities and append the results to a sheet or CRM.
FAQ
Where does the data come from, and how complete is it? The list comes from community-maintained OpenStreetMap plus business websites. Coverage depends on what contributors have mapped and varies by city and niche. This is not a Google Maps scraper; it can miss businesses that are absent from OpenStreetMap.
How many results can I get per search? Up to 50 per run. The data source returns a limited number of matches per query, and the Actor filters out results that do not match your location or niche, so narrow niches in small towns can return fewer. Run several queries or nearby locations to get more.
Why does a chain location list several emails? For multi-location businesses the website often lists every branch's address. The Actor returns the public emails it finds on the linked site, preferring generic mailboxes and addresses that match the branch, so check which one belongs to the branch you need.
Why do some businesses have no email? Many small businesses do not publish an email address, or only use a contact form. The Actor returns only addresses that are publicly visible on OpenStreetMap or on the website's homepage and contact pages. It does not guess or verify addresses. Third-party addresses such as ordering platforms and placeholder emails are dropped.
Do I need a proxy? The proxy is optional. It is used for the web search that finds websites without an OpenStreetMap website tag, and as a fallback when a business website blocks a direct request. Fresh proxy sessions are used for retries. The Actor still runs if the proxy is unavailable.
Are phone numbers international?
Phone numbers are normalised to E.164 where the country code or a North American 10-digit number makes that possible; phonesRaw keeps the original text. Numbers found on websites are matched in US and Canada format only, so businesses outside North America may show OpenStreetMap phone numbers but few website phone numbers.
Why is my run sometimes slow? Photon and Overpass are free shared community services. The Actor sends one community-service request at a time, identifies itself with a descriptive User-Agent, and backs off on HTTP 429 before retrying or using a mirror Overpass server. Optional Overpass lookups have short time limits; if both servers are slow, it fetches the same OpenStreetMap contact tags in small batches from the OpenStreetMap API before website discovery.
How fresh is the data? Contact details from OpenStreetMap are as recent as the last edit by a contributor. Website contacts are read live at run time. Schedule runs if you want to refresh a list.
Is it legal to scrape business contact data?
This Actor is not affiliated with, endorsed by or sponsored by Google, OpenStreetMap, Bing or the businesses whose websites it reads.
The Actor collects publicly available business information from OpenStreetMap and public website pages, and it does not log in to anything. You are responsible for how you use the data. Email marketing and cold outreach are regulated in many places (for example CAN-SPAM, GDPR and the ePrivacy rules), and some business contact details can be personal data. Respect privacy and data protection law, honor opt-outs, follow each website's terms, and comply with the OpenStreetMap data license terms. Seek legal advice if you are unsure about your use case.
This Actor is not affiliated with or endorsed by OpenStreetMap, Google, Bing or any website it collects data from.
Feedback
If a search returns too few results or wrong contacts, open an issue from the Issues tab of this Actor with the niche and location you used. Concrete examples make problems much easier to fix.