# Touch Local Email Scraper (`leads-scraper/touch-local-email-scraper`) Actor

Touch Local Email Scraper SD - Touch Local Email Scraper is a lead generation tool that extracts leads with public contact emails, account names and profile URLs from Touch Local results by keyword, location and email domain - Touch Local email extractor.

- **URL**: https://apify.com/leads-scraper/touch-local-email-scraper.md
- **Developed by:** [Leads Scraper](https://apify.com/leads-scraper) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.49 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### Touch Local Email Scraper - public business contact emails from touchlocal.com

The Touch Local Email Scraper collects publicly indexed contact emails that appear in Google search results for `touchlocal.com`. Touch Local is a UK business directory where small firms, shops and tradespeople publish a listing so that local customers can find and contact them.

The honest headline comes first, before any of the good news. **Touch Local has a small and ageing indexed footprint, so expect low volume.** That is a property of the platform's presence in Google, not of the extraction pipeline.

What the Touch Local Email Scraper does exceptionally well is convert the pages that do exist. On the listings Google holds, both identity resolution and email extraction perform near the top of this whole Actor family.

The result is a small, unusually clean UK dataset. Local-services agencies, SMB SaaS vendors and franchise development teams working British towns are the people it fits.

#### A measured live result, stated plainly

A live Google run of the Touch Local Email Scraper returned **10 result blocks, 10 rows with account identity, 10 resolvable profile URLs and 9 unique emails**. Those are observed figures.

Nine unique emails from ten blocks, with complete identity coverage, is one of the best per-page conversion rates measured across these directories. Touch Local listings tend to carry a business description alongside the contact line, which is exactly what a snippet-level extractor needs.

The constraint is not the hit rate. It is how many `touchlocal.com` pages Google currently holds, and that number is modest.

### Features of the Touch Local Email Scraper

Every feature below is genuinely implemented. Nothing here is aspirational.

| Feature | What it means in practice |
|---|---|
| Google SERP parsing | Reads Google result pages through the Apify GOOGLE_SERP proxy. No browser, no JavaScript rendering |
| Structural block detection | Locates the `<h3>` title, then the smallest surrounding block. Does not depend on Google's CSS class names |
| Domain filter | Only emails ending in one of your `customDomains` values are kept |
| Query expansion | Base, quoted, `intitle:` and one variant per query modifier. Base queries run first |
| Global deduplication | An email seen once is never pushed twice, across every query and every page |
| Email normalisation | Understands `name [at] domain [dot] com`, `name (at) domain`, `name @ domain.com`, `domain .com`, zero-width characters and the full-width `＠` sign |
| Junk filter | Rejects placeholders such as `email@`, `yourname@`, `test@`, `xxx@` and single-character locals |
| Boundary-correct matching | `@gmail.com` does not match inside `@gmail.company` or `@gmail.com.br` |
| Soft-wrap repair | Drops a hit that is only the tail of another email in the same block |
| Concurrency | An `asyncio` worker pool with a shared stop signal on `maxEmails` |
| Retries | Up to 3 attempts per page, exponential backoff, a fresh proxy session per request |
| Block detection | CAPTCHA, "unusual traffic" and consent pages are detected and retried, not counted as empty |
| Re-queueing | Blocked or failed queries are retried once at the end of the run |
| Resumable run | State is stored in the key-value store, keyed by a hash of the input, and saved on `PERSIST_STATE`, `MIGRATING` and `ABORTING` |
| Fallback parser | If Google's markup changes, the run degrades to "emails without account details" rather than "no emails" |
| Run summary | Logs pages fetched, blocked pages, retries and emails per page |
| Dataset output | Rows push immediately and export to CSV, JSON, Excel or XML from the Apify dataset |

None of those features change the underlying arithmetic. The Touch Local Email Scraper is careful and resilient, but it is still bounded by how much of `touchlocal.com` sits in Google's index.

Query expansion is the feature that matters most on a small index. Running many variants is the only reliable way to reach its edges.

### How the Touch Local Email Scraper works

The pipeline is six steps and there is nothing hidden inside it.

1. It reads your input: keywords, location, email domains and limits.
2. It builds Google search queries with the `site:` operator against `touchlocal.com`, for example `site:touchlocal.com local business "@gmail.com" "Bristol"`.
3. It fetches Google result pages through the Apify GOOGLE_SERP proxy using `aiohttp`, asynchronously.
4. It parses each result block structurally, finding the `<h3>` title and the smallest block around it.
5. It extracts emails from that block's text with a domain-filtered regex.
6. It deduplicates globally and pushes each lead straight into the Apify dataset.

The Touch Local Email Scraper does **not** log into Touch Local, does not use any Touch Local API, and does not open the directory in a browser. Every field comes from publicly indexed Google search results - titles, snippets and site labels, with no authentication and no cookies.

### Who the Touch Local Email Scraper is built for

This is a UK local business Actor, aimed at people who sell services to small British firms rather than at industrial buyers.

Local-services agencies use it to build outreach lists for web design, SEO, print and signage across a town or county. SMB SaaS vendors use it to reach owner-run shops, salons and trades that still work from paper.

Franchise development teams use it to find independent operators in a category worth converting. Payment and POS providers use it to approach retail and hospitality businesses in a chosen high street.

Because the footprint is modest, treat the Touch Local Email Scraper as a supplementary source. It pairs naturally with [Scoot Email Scraper](https://apify.com/neuro-scraper/scoot-email-scraper), which covers a sibling UK directory, and with [Fyple Email Scraper](https://apify.com/neuro-scraper/fyple-email-scraper) for wider multi-country reach.

### Input fields for the Touch Local Email Scraper

| Field | Type | Default | Meaning |
|---|---|---|---|
| `keywords` | array (required) | `["local business", "tradesman"]` | Search terms - niche, job title, industry |
| `location` | string | `""` | Optional location phrase added to every query |
| `customDomains` | array | `["@gmail.com", "@yahoo.com"]` | Only emails on these domains are kept; the `@` is optional |
| `maxEmails` | integer 1-10000 | `20` | Stop after this many unique emails |
| `countryCode` | string | `""` | Two-letter country for the search proxy (US, GB, DE...) |
| `expandQueries` | boolean | `true` | Search each keyword x domain pair in several phrasings |
| `queryModifiers` | array | `["email", "contact", "enquiries", "owner", "get a quote"]` | Extra words combined with each keyword when expansion is on |
| `maxPagesPerQuery` | integer 1-50 | `30` | Page cap per query |
| `maxConcurrency` | integer 1-20 | `5` | Parallel queries |

#### How the Touch Local Email Scraper input fields actually behave

`customDomains` is the highest-leverage field, because the two webmail defaults miss much of how UK small businesses keep their mail. Add `@btinternet.com`, `@sky.com`, `@virginmedia.com`, `@hotmail.co.uk`, `@yahoo.co.uk` and `@live.co.uk`.

`keywords` should name a trade or a shop type. `hairdresser`, `dry cleaners`, `builder`, `cafe`, `letting agent` and `mobile mechanic` all match the Touch Local index far better than the broad defaults.

`location` narrows to a town, borough or county and is worth setting on nearly every run. UK directories are organised around place, so `"Bristol"`, `"Croydon"` or `"Hampshire"` reshapes results considerably.

`queryModifiers` only fire when `expandQueries` is `true`. The defaults `enquiries`, `owner` and `get a quote` are tuned to local listing text, where those exact phrases appear next to a published address.

`maxEmails` is a hard stop shared across the worker pool; set it generously so a run on a small index explores every expanded query. `maxConcurrency` and `maxPagesPerQuery` trade speed against politeness, and 5 and 30 are sensible defaults.

### JSON input example for the Touch Local Email Scraper

```json
{
  "keywords": ["hairdresser", "builder", "letting agent"],
  "location": "Bristol",
  "customDomains": ["@gmail.com", "@yahoo.co.uk", "@btinternet.com", "@sky.com", "@live.co.uk"],
  "maxEmails": 100,
  "countryCode": "GB",
  "expandQueries": true,
  "queryModifiers": ["email", "contact", "enquiries", "owner", "get a quote"],
  "maxPagesPerQuery": 30,
  "maxConcurrency": 5
}
```

The UK webmail domains carry that example. `@btinternet.com`, `@sky.com` and `@live.co.uk` are common in British high-street listings and none of them are in the default filter.

That is a realistic configuration for the Touch Local Email Scraper: three trades, one city, `GB` as the country code, and a domain filter that matches how UK owner-operators actually receive mail.

### Output fields of the Touch Local Email Scraper

Every dataset item carries all fourteen fields.

| Field | Meaning |
|---|---|
| `network` | Platform name |
| `keyword` | The keyword that produced the lead |
| `query` | The exact Google query used |
| `title` | Raw result title |
| `accountName` | Account label Google prints |
| `fullName` | Display name parsed from a profile-style title; empty for non-profile results |
| `username` | URL-safe handle when the platform exposes one; otherwise `null` |
| `profileUrl` | Canonical account URL when a handle is known; otherwise empty |
| `url` | Direct platform link when exposed, else the profile URL |
| `description` | Bio or snippet text, cleaned of labels and counters |
| `email` | Lower-cased email address |
| `emailDomain` | The matched domain, for example `@gmail.com` |
| `possiblyTruncated` | `true` when Google's snippet ellipsis touched the email - verify before sending |
| `foundAt` | ISO 8601 UTC timestamp |

On Touch Local, `username` and `profileUrl` are populated on essentially every row because listing pages carry a stable slug. The Touch Local Email Scraper builds the canonical link as `https://www.touchlocal.com/{username}`.

The `description` field is unusually useful on this platform, since listings often include an owner-written blurb. Check `possiblyTruncated` before sending; when it is `true`, Google's ellipsis may have clipped the address.

### JSON output example from the Touch Local Email Scraper

```json
[
  {
    "network": "Touch Local",
    "keyword": "hairdresser",
    "query": "site:touchlocal.com hairdresser contact \"@btinternet.com\" \"Bristol\"",
    "title": "Clifton Cuts Hair Studio - Bristol - Touch Local",
    "accountName": "Clifton Cuts Hair Studio",
    "fullName": "Clifton Cuts Hair Studio",
    "username": "clifton-cuts-hair-studio-bristol",
    "profileUrl": "https://www.touchlocal.com/clifton-cuts-hair-studio-bristol",
    "url": "https://www.touchlocal.com/clifton-cuts-hair-studio-bristol",
    "description": "Unisex salon in Clifton offering cuts, colour and bridal styling. Bookings by phone or email.",
    "email": "cliftoncuts@btinternet.com",
    "emailDomain": "@btinternet.com",
    "possiblyTruncated": false,
    "foundAt": "2026-08-29T17:20:15Z"
  },
  {
    "network": "Touch Local",
    "keyword": "letting agent",
    "query": "site:touchlocal.com letting agent \"get a quote\" \"@gmail.com\" \"Bristol\"",
    "title": "Harbourside Lettings - Bristol - Touch Local",
    "accountName": "Harbourside Lettings",
    "fullName": "Harbourside Lettings",
    "username": "harbourside-lettings-bristol",
    "profileUrl": "https://www.touchlocal.com/harbourside-lettings-bristol",
    "url": "https://www.touchlocal.com/harbourside-lettings-bristol",
    "description": "Residential lettings and property management across central Bristol. Landlord enquiries welcome.",
    "email": "harboursidelettings@gmail.com",
    "emailDomain": "@gmail.com",
    "possiblyTruncated": true,
    "foundAt": "2026-08-29T17:21:52Z"
  }
]
```

Both rows carry a clean handle and a readable description, which is the normal shape here. Per-record quality is the strength of the Touch Local Email Scraper; record count is not.

### Use cases for the Touch Local Email Scraper

| Audience | What they do with the data |
|---|---|
| UK local-services agencies | Build outreach lists for web design, SEO, print or signage in a town or borough |
| SMB SaaS vendors | Reach owner-run shops, salons and trades still working from paper |
| Franchise development teams | Identify independent operators worth converting to a franchise model |
| Payment and POS providers | Approach retail and hospitality businesses on a chosen high street |
| Field sales teams | Plan territory coverage across a UK region before working a route |
| Insurance and finance brokers | Prospect sole traders by trade and postcode area |
| Trade suppliers and merchants | Reach builders and contractors who buy materials locally |
| Local data researchers | Sample how UK high-street businesses publish contact routes |

Each of those targets a business inbox that an owner published in a directory so customers could get in touch. That is the honest boundary of what the Touch Local Email Scraper does.

### Targeting tips for the Touch Local Email Scraper

`location` and `countryCode` are both real levers, and on a UK-only directory they are close to mandatory.

Set `countryCode` to `GB` so the search proxy uses the UK view. Leaving it blank makes the Touch Local Email Scraper compete against international results that have nothing to do with British high streets.

Set `location` to a town, borough or county rather than "UK". The directory is organised around place, so `"Croydon"`, `"Bristol"` or `"Hampshire"` reaches genuinely different listings.

On a small index, breadth of vocabulary beats depth of paging. Twenty specific trade and shop types will out-produce two generic keywords, and the `owner` and `get a quote` modifiers land on the exact listing text where addresses sit.

For wider coverage, pair it with [Scoot Email Scraper](https://apify.com/neuro-scraper/scoot-email-scraper) from the same UK directory network, then widen further with [Cybo Email Scraper](https://apify.com/neuro-scraper/cybo-email-scraper) or [Lacartes Email Scraper](https://apify.com/neuro-scraper/lacartes-email-scraper).

### Limitations of the Touch Local Email Scraper

Read all of these before your first run.

- **Touch Local has a small and ageing indexed footprint, so expect low volume.** Conversion per page is excellent; the number of pages is the constraint.
- Because listings can be old, some addresses may no longer be monitored. Verify before running a campaign on them.
- The Touch Local Email Scraper only finds addresses that are **publicly visible in Google's index**. Anything Google has not indexed is invisible to it.
- Google caps a single query at roughly 300 results, which is exactly why query expansion exists and defaults to on.
- `possiblyTruncated: true` means Google's snippet ellipsis may have cut the email short. Verify it before sending.
- It requires the Apify GOOGLE_SERP proxy and cannot run without Apify proxy credentials.
- Free Apify plans are capped at 100 emails per run; paid plans are uncapped. Here the platform's footprint usually binds before the plan cap does.
- `username` and `profileUrl` are only populated when Google exposes a handle. Touch Local almost always does, but rows from category or search pages can still arrive with `username: null` and an empty `profileUrl`. That is a Google limitation, not a bug.
- Results vary with keywords, domains and location. No volume is guaranteed by the Touch Local Email Scraper or by any Actor in this family.

### Responsible use of Touch Local Email Scraper output

The addresses the Touch Local Email Scraper surfaces are business contacts that owners published in a UK directory so that customers could reach them. Treat them as exactly that.

UK GDPR and PECR both apply, and a sole trader's address counts as personal data. Record your legitimate interest, identify yourself and your company in the first line, and keep the message clearly relevant to that business.

Honour opt-outs immediately and permanently, keep your list current, and follow UK marketing rules including any preference-service screening that applies to you. Do not use this output for bulk unsolicited mail.

### FAQ about the Touch Local Email Scraper

#### How many results should I expect from the Touch Local Email Scraper?

Fewer than from most Actors in this family, because Touch Local has a small and ageing indexed footprint. A live Google run returned 10 result blocks, 10 identified accounts, 10 profile URLs and 9 unique emails - outstanding per-page conversion, but a limited pool of pages. Run many specific trade keywords and expect a small, clean dataset.

#### Why is the footprint described as ageing?

Touch Local is a long-established UK directory and part of its indexed content is older listings. Some contact details may therefore be out of date, so verification before outreach is sensible.

#### How does it differ from the Scoot Email Scraper?

They cover sibling UK directories in the same network. In the measured runs Touch Local converted slightly better on emails, 9 against 8, with identical identity coverage. Running both is the sensible approach for UK work.

#### Does the Touch Local Email Scraper log into Touch Local or use its API?

No. It builds Google `site:touchlocal.com` queries, fetches result pages through the Apify GOOGLE_SERP proxy and parses them. There is no browser, no login, no API and no cookies.

#### Why do nearly all rows have a working profile URL?

Because Touch Local listing pages carry a stable slug that Google prints. The Touch Local Email Scraper derives `username` from it and builds `profileUrl` as `https://www.touchlocal.com/{username}`.

#### What is the fastest way to increase Touch Local Email Scraper yield?

Add UK webmail domains to `customDomains` and run many specific trade keywords instead of two generic ones. `@btinternet.com`, `@sky.com` and `@yahoo.co.uk` are the most productive additions.

#### Should I set `countryCode`?

Yes, to `GB`. Touch Local is a UK-only directory and the UK proxy view materially improves what the Touch Local Email Scraper finds.

#### Why does the Touch Local Email Scraper turn `expandQueries` on by default?

Google caps one query at roughly 300 results. Expansion runs base, quoted and `intitle:` variants plus one per modifier, which matters even more when the index is small. Base queries always run first.

#### Can I run the Touch Local Email Scraper on a free Apify plan?

Yes. Free plans are capped at 100 emails per run, which on the Touch Local Email Scraper is usually above what the platform's footprint will produce anyway. Paid plans are uncapped.

#### What happens if a Touch Local Email Scraper run is interrupted?

State is saved in the key-value store, keyed by a hash of your input, and written on Apify's `PERSIST_STATE`, `MIGRATING` and `ABORTING` events. Restarting with the same input resumes rather than starting over.

#### Which export formats does the Touch Local Email Scraper support?

Anything the Apify dataset supports - CSV, JSON, Excel and XML - plus the API for pushing rows straight into a CRM.

#### Is the Touch Local Email Scraper affiliated with Touch Local?

No. It is an independent Actor that reads publicly indexed Google results, with no relationship to or endorsement from the platform.

### Related Actors

More email scrapers from the same Business & Professional Directories family, built on the same Google SERP pipeline.

| Actor | What it collects |
|---|---|
| [Angi Email Scraper](https://apify.com/leads-scraper/angi-email-scraper) | Public contact emails from Angi |
| [Bark Email Scraper](https://apify.com/leads-scraper/bark-email-scraper) | Public contact emails from Bark |
| [Better Business Bureau Email Scraper](https://apify.com/leads-scraper/better-business-bureau-email-scraper) | Public contact emails from Better Business Bureau |
| [Bizapedia Email Scraper](https://apify.com/neuro-scraper/bizapedia-email-scraper) | Public contact emails from Bizapedia |
| [Brownbook Email Scraper](https://apify.com/neuro-scraper/brownbook-email-scraper) | Public contact emails from Brownbook |
| [Callupcontact Email Scraper](https://apify.com/neuro-scraper/callupcontact-email-scraper) | Public contact emails from CallUpContact |
| [Capterra Email Scraper](https://apify.com/leads-scraper/capterra-email-scraper) | Public contact emails from Capterra |
| [Clutch Email Scraper](https://apify.com/leads-scraper/clutch-email-scraper) | Public contact emails from Clutch |
| [Crunchbase Email Scraper](https://apify.com/leads-scraper/crunchbase-email-scraper) | Public contact emails from Crunchbase |
| [Cybo Email Scraper](https://apify.com/neuro-scraper/cybo-email-scraper) | Public contact emails from Cybo |
| [Cylex Email Scraper](https://apify.com/neuro-scraper/cylex-email-scraper) | Public contact emails from Cylex |
| [EC21 Email Scraper](https://apify.com/neuro-scraper/ec21-email-scraper) | Public contact emails from EC21 |
| [Europages Email Scraper](https://apify.com/leads-scraper/europages-email-scraper) | Public contact emails from Europages |
| [ExportHub Email Scraper](https://apify.com/neuro-scraper/exporthub-email-scraper) | Public contact emails from ExportHub |
| [FindUsLocal Email Scraper](https://apify.com/neuro-scraper/finduslocal-email-scraper) | Public contact emails from FindUsLocal |
| [Foursquare Email Scraper](https://apify.com/neuro-scraper/foursquare-email-scraper) | Public contact emails from Foursquare |
| [Fyple Email Scraper](https://apify.com/neuro-scraper/fyple-email-scraper) | Public contact emails from Fyple |
| [G2 Email Scraper](https://apify.com/neuro-scraper/g2-email-scraper) | Public contact emails from G2 |
| [Hotfrog Email Scraper](https://apify.com/leads-scraper/hotfrog-email-scraper) | Public contact emails from Hotfrog |
| [Houzz Email Scraper](https://apify.com/leads-scraper/houzz-email-scraper) | Public contact emails from Houzz |
| [Infobel Email Scraper](https://apify.com/neuro-scraper/infobel-email-scraper) | Public contact emails from Infobel |
| [Kompass Email Scraper](https://apify.com/leads-scraper/kompass-email-scraper) | Public contact emails from Kompass |
| [Lacartes Email Scraper](https://apify.com/neuro-scraper/lacartes-email-scraper) | Public contact emails from Lacartes |
| [Manta Email Scraper](https://apify.com/leads-scraper/manta-email-scraper) | Public contact emails from Manta |
| [MapQuest Email Scraper](https://apify.com/neuro-scraper/mapquest-email-scraper) | Public contact emails from MapQuest |
| [N49 Email Scraper](https://apify.com/neuro-scraper/n49-email-scraper) | Public contact emails from N49 |
| [Porch Email Scraper](https://apify.com/neuro-scraper/porch-email-scraper) | Public contact emails from Porch |
| [Scoot Email Scraper](https://apify.com/neuro-scraper/scoot-email-scraper) | Public contact emails from Scoot |
| [Thomasnet Email Scraper](https://apify.com/leads-scraper/thomasnet-email-scraper) | Public contact emails from Thomasnet |
| [Thumbtack Email Scraper](https://apify.com/leads-scraper/thumbtack-email-scraper) | Public contact emails from Thumbtack |
| [TradeIndia Email Scraper](https://apify.com/leads-scraper/tradeindia-email-scraper) | Public contact emails from TradeIndia |
| [Trustpilot Email Scraper](https://apify.com/leads-scraper/trustpilot-email-scraper) | Public contact emails from Trustpilot |
| [Tupalo Email Scraper](https://apify.com/leads-scraper/tupalo-email-scraper) | Public contact emails from Tupalo |
| [Yalwa Email Scraper](https://apify.com/leads-scraper/yalwa-email-scraper) | Public contact emails from Yalwa |
| [Yellow Pages Email Scraper](https://apify.com/leads-scraper/yellow-pages-email-scraper) | Public contact emails from Yellow Pages |
| [Angi Email and Phone Number Scraper](https://apify.com/neuro-scraper/angi-email-and-phone-number-scraper) | Emails and phone numbers from Angi |
| [Bark Email and Phone Number Scraper](https://apify.com/neuro-scraper/bark-email-and-phone-number-scraper) | Emails and phone numbers from Bark |
| [Better Business Bureau Email and Phone Number Scraper](https://apify.com/leads-scraper/better-business-bureau-email-and-phone-number-scraper) | Emails and phone numbers from Better Business Bureau |
| [Bizapedia Email and Phone Number Scraper](https://apify.com/neuro-scraper/bizapedia-email-and-phone-number-scraper) | Emails and phone numbers from Bizapedia |
| [Brownbook Email and Phone Number Scraper](https://apify.com/neuro-scraper/brownbook-email-and-phone-number-scraper) | Emails and phone numbers from Brownbook |
| [CallUpContact Email and Phone Number Scraper](https://apify.com/neuro-scraper/callupcontact-email-and-phone-number-scraper) | Emails and phone numbers from CallUpContact |
| [Capterra Email and Phone Number Scraper](https://apify.com/leads-scraper/capterra-email-and-phone-number-scraper) | Emails and phone numbers from Capterra |

### Leave a review

If the Touch Local Email Scraper saved you time, please leave a star rating and a short review
on the Actor page.

Reviews are how other buyers judge whether a tool works, and they tell us which features to
build next.

If something did not work, email <neurodata.apify@gmail.com>
instead - bugs get fixed faster than they get complained about.

# Actor input Schema

## `keywords` (type: `array`):

Search terms describing the Touch Local accounts you want (niche, job title, industry).

## `location` (type: `string`):

Optional location phrase added to every query (e.g. "New York").

## `customDomains` (type: `array`):

Only emails ending with one of these domains are collected. With or without the leading @. Each domain is searched separately, so more domains means more results but a longer run - remove some for a faster, narrower search, or add your own (e.g. @company.com).

## `maxEmails` (type: `integer`):

Stop once this many unique emails have been collected.

## `countryCode` (type: `string`):

Two-letter country code for the search proxy (e.g. US, GB, DE). Empty for any.

## `expandQueries` (type: `boolean`):

Search each keyword x domain pair with several phrasings. Recommended - Google caps a single query at ~300 results.

## `queryModifiers` (type: `array`):

Extra words combined with each keyword when Expand queries is on. Tuned for Touch Local.

## `maxPagesPerQuery` (type: `integer`):

Google rarely returns more than ~30 pages for one query.

## `maxConcurrency` (type: `integer`):

How many queries run in parallel.

## Actor input object example

```json
{
  "keywords": [
    "local business",
    "tradesman"
  ],
  "location": "",
  "customDomains": [
    "@gmail.com",
    "@yahoo.com"
  ],
  "maxEmails": 20,
  "countryCode": "",
  "expandQueries": true,
  "queryModifiers": [
    "email",
    "contact",
    "enquiries",
    "owner",
    "get a quote"
  ],
  "maxPagesPerQuery": 30,
  "maxConcurrency": 5
}
```

# Actor output Schema

## `results` (type: `string`):

Records produced by Touch Local Email Scraper, stored in the run's default dataset.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "keywords": [
        "local business",
        "tradesman"
    ],
    "location": "",
    "customDomains": [
        "@gmail.com",
        "@yahoo.com"
    ],
    "countryCode": "",
    "queryModifiers": [
        "email",
        "contact",
        "enquiries",
        "owner",
        "get a quote"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("leads-scraper/touch-local-email-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "keywords": [
        "local business",
        "tradesman",
    ],
    "location": "",
    "customDomains": [
        "@gmail.com",
        "@yahoo.com",
    ],
    "countryCode": "",
    "queryModifiers": [
        "email",
        "contact",
        "enquiries",
        "owner",
        "get a quote",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("leads-scraper/touch-local-email-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "keywords": [
    "local business",
    "tradesman"
  ],
  "location": "",
  "customDomains": [
    "@gmail.com",
    "@yahoo.com"
  ],
  "countryCode": "",
  "queryModifiers": [
    "email",
    "contact",
    "enquiries",
    "owner",
    "get a quote"
  ]
}' |
apify call leads-scraper/touch-local-email-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,leads-scraper/touch-local-email-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/h5AIHfWUF3VqZUqHa/builds/NcZxyXISvj3K3REOV/openapi.json
