# Upwork Email Scraper (`email_scraper/upwork-email-scraper`) Actor

Upwork Email Scraper finds publicly indexed Upwork contact emails using targeted keywords, locations, and custom email domains. Extract structured lead data with titles, descriptions, URLs, and emails into an Apify Dataset.

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

## Pricing

from $1.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

### 🔍 Upwork Email Scraper – Overview

Upwork Email Scraper is an Apify Actor designed to discover publicly indexed email addresses associated with Upwork search results using targeted keywords, optional locations, and selected email domain suffixes.

It is built for users who need structured contact research around freelancers, developers, designers, agencies, technical professionals, and other Upwork-related search categories. Instead of manually searching for individual results and copying contact information, you can provide multiple search terms and let the Actor organize matching results into an Apify Dataset.

Upwork Email Scraper works especially well when you use specific search terms instead of one broad keyword. For example, `Freelancer` can be combined with terms such as `Developer`, `Web Developer`, `Python Developer`, or another professional category relevant to your research.

The Actor returns structured records containing the search keyword, result title, description, URL, and discovered email address. The underlying dataset also records the source network as `Upwork.com`.

> **📌 Important:** Upwork Email Scraper searches publicly indexed information. It does not guarantee that an email address exists for every Upwork result, keyword, location, or domain.

### 🔎 Upwork Email Scraper – Key Features

Upwork Email Scraper combines keyword-based search, location targeting, email-domain filtering, exclusion rules, duplicate prevention, structured dataset output, and progress persistence.

> **✨ Key Features**
>
> - Search Upwork-related results using multiple keywords or queries
> - Target searches by country, state, city, or other location
> - Select one or multiple email domain suffixes
> - Set an email target for each keyword + domain combination
> - Exclude unwanted words or phrases from result descriptions
> - Avoid duplicate email addresses across the run
> - Push discovered records incrementally into an Apify Dataset
> - Preserve search progress during processing
> - Return structured contact information for further research

The Actor is useful for both broad discovery and highly focused searches. You can start with a small keyword set, inspect the resulting dataset, and then refine your search terms based on the quality and quantity of available results.

### 🎯 Upwork Email Scraper – Why Use It?

Finding relevant freelancer or professional contact information manually can involve repeated search-engine queries, opening results, identifying useful snippets, checking email domains, removing duplicates, and organizing everything into a spreadsheet.

Upwork Email Scraper automates much of that repetitive discovery process. You define the search criteria once, and the Actor processes the selected keyword and email-domain combinations systematically.

> **💡 Why use Upwork Email Scraper?**
>
> - Reduce repetitive manual contact research
> - Search multiple professional keywords in one run
> - Narrow results geographically when needed
> - Search multiple email domains
> - Filter out irrelevant result descriptions
> - Keep discovered contacts in structured dataset records
> - Reduce duplicate email entries
> - Build more focused research datasets from targeted queries

It can be useful for sales research, freelancer discovery, agency research, business development, market research, recruiting, and other legitimate workflows involving publicly available information.

Actual results depend on the information that is publicly indexed and discoverable for your selected search criteria.

### 📊 Upwork Email Scraper – What Data Can You Extract?

Upwork Email Scraper stores structured information for every newly discovered matching email.

The default Apify Dataset view displays five fields: keyword, title, description, URL, and email. The Actor also pushes a `network` field that identifies the source as `Upwork.com`.

| Field         | Description                                             | Default View |
| ------------- | ------------------------------------------------------- | ------------ |
| `network`     | Source identifier returned as `Upwork.com`              | No           |
| `keyword`     | Keyword or query used during discovery                  | Yes          |
| `title`       | Title of the search result                              | Yes          |
| `description` | Search-result description containing the matching email | Yes          |
| `url`         | URL returned by the search result                       | Yes          |
| `email`       | Email address matching a selected domain                | Yes          |

The description field provides useful context around the discovered contact. The URL is the URL returned by the search result and should not automatically be interpreted as a guarantee that every record represents a directly accessible Upwork profile.

> **📦 Output Summary**
>
> - Source network: Upwork.com
> - Search context: Keyword
> - Optional geographic filter: Location
> - Contact information: Email
> - Context: Title and description
> - Structured storage: Apify Dataset
> - Duplicate handling: Previously discovered email addresses are skipped

This structure makes the dataset suitable for reviewing, filtering, and organizing discovered contact records inside the Apify environment.

### ⚙️ Upwork Email Scraper – How to Use It

Using Upwork Email Scraper requires only a few input decisions.

#### 📝 Step 1: Enter Your Keywords

The required `keywords` field accepts a list of search terms or queries.

Specific keywords can be more useful than a single generic term because different professionals may be represented by different titles or specialties.

For example:

- Freelancer
- Developer
- Web Developer
- Python Developer
- Graphic Designer
- WordPress Developer

You can mix job titles, professional categories, skills, and niche terms according to your research goal.

#### 📍 Step 2: Add a Location

The optional `location` field lets you narrow the search geographically.

You can enter a country, state, city, or another geographic term.

Examples include:

- United States
- New York
- California
- London
- Canada

Leave the field empty when you want to search without a geographic filter.

#### 📧 Step 3: Choose Email Domains

The `customDomains` field controls which email suffixes the Actor searches for.

The default is:

```json
["@gmail.com"]
```

You can provide several domains:

```json
[
  "@gmail.com",
  "@yahoo.com",
  "@outlook.com"
]
```

You can also use relevant custom domains when your research requires them.

#### 🔢 Step 4: Set `maxEmails`

The `maxEmails` input accepts values from 1 to 10,000 and defaults to 5.

Importantly, this is a target for each keyword + domain combination rather than one shared run-wide target.

For example, three keywords combined with two domains create six keyword-domain combinations. If `maxEmails` is 20, each combination can target up to 20 addresses, subject to actual result availability and duplicate handling.

> **⚠️ Important:** `maxEmails` is a collection target or cap, not a guarantee that the requested number will be available.

#### 🚫 Step 5: Add Exclude Words

The optional `excludeWords` field lets you skip result descriptions containing unwanted terms.

For example:

```json
[
  "crypto",
  "onlyfans"
]
```

Matching is case-insensitive. Individual words are matched as whole words, while phrases are matched as substrings.

If an exclusion term appears in a result description, the complete snippet is skipped and no email is extracted from it.

### 🔎 How Does Upwork Email Scraper Find Email Addresses?

Upwork Email Scraper uses targeted search queries to discover publicly indexed Upwork-related results.

Each search is based on the selected keyword and email-domain suffix, with the optional location added when provided.

The Actor then processes available search-result information and looks for email addresses matching the selected domain suffix.

This means the workflow is search-based rather than a guarantee of exhaustive access to all information that may exist on Upwork.

> **🔐 Privacy and Implementation Note:** This documentation describes the Actor's public functionality only. Internal request handling, infrastructure, selectors, headers, proxy configuration, and other implementation-specific details are intentionally not exposed.

The quality and quantity of results depend on what is publicly indexed for the chosen query.

### 🧩 How to Scrape Upwork Email Addresses Using Keywords

A strong search strategy starts with relevant keywords.

If you are researching developers, for example, using only `Developer` may be less targeted than combining it with more specific searches.

Possible keyword variations include:

- Developer
- Software Developer
- Web Developer
- Python Developer
- JavaScript Developer
- Full Stack Developer

For freelancer research, you could combine:

- Freelancer
- Freelance Developer
- Freelance Designer
- Freelance Writer

The goal is not simply to increase the number of keywords. The goal is to create useful search variations that match the audience or professional category you are researching.

### 📍 Can You Search Upwork by Country or City?

Yes. The optional `location` field can narrow searches to a geographic area.

For example:

```json
{
  "keywords": [
    "Freelancer",
    "Developer"
  ],
  "location": "New York",
  "customDomains": [
    "@gmail.com",
    "@outlook.com"
  ],
  "maxEmails": 20
}
```

This configuration focuses the search on the specified location.

Location targeting is useful when geographic relevance matters, but it can also reduce the number of available results. If the dataset is too small, try a broader location or remove the location filter.

### 🚫 Can You Exclude Specific Upwork Result Categories?

Yes. The `excludeWords` filter is designed for this purpose.

For example:

```json
{
  "excludeWords": [
    "crypto",
    "onlyfans"
  ]
}
```

The Actor checks the result description before extracting an email. If a matching excluded word or phrase is found, the entire snippet is ignored.

This can help remove categories that are outside your research scope.

Because the filter applies to the description, overly broad exclusion terms should be avoided if they could unintentionally remove relevant results.

### 💼 Upwork Email Scraper – Use Cases

Upwork Email Scraper can support several legitimate professional research workflows.

> **🎯 Common Use Cases**
>
> - Freelancer research
> - Developer discovery
> - Agency research
> - B2B prospecting
> - Sales lead research
> - Business development
> - Recruiting research
> - Professional contact discovery
> - Market research
> - Industry research
> - Location-based professional research
> - Niche skill research

#### 💻 Developer Research

Use technical keywords such as `Python Developer`, `Web Developer`, or `Full Stack Developer` to create focused research datasets.

#### 🎨 Creative Professional Research

Keywords such as `Graphic Designer`, `UI Designer`, or other creative roles can be used when researching relevant professional categories.

#### 🌎 Location-Based Prospect Research

Add a city, state, or country when the research requires contacts associated with a specific geographic market.

#### 🏢 Agency and Business Research

Search terms related to agencies, freelancers, services, or professional specialties can help organize publicly indexed business-research opportunities.

#### 📈 Sales and Business Development Research

Organizations conducting B2B research can use targeted professional keywords and selected email domains to create structured contact datasets for further qualification.

### 📝 Input

The Actor accepts the following inputs.

| Input           | Type             | Required | Default               | Description                                |
| --------------- | ---------------- | -------- | --------------------- | ------------------------------------------ |
| `keywords`      | Array of strings | Yes      | Freelancer, Developer | Search keywords or queries                 |
| `location`      | String           | No       | Empty                 | Country, state, city, or geographic filter |
| `customDomains` | Array of strings | No       | `@gmail.com`          | Email suffixes to search                   |
| `maxEmails`     | Integer          | No       | 5                     | Target per keyword + domain combination    |
| `excludeWords`  | Array of strings | No       | Empty                 | Words or phrases that skip result snippets |

#### 📋 Example Input

```json
{
  "keywords": [
    "Freelancer",
    "Developer",
    "Python Developer"
  ],
  "location": "United States",
  "customDomains": [
    "@gmail.com",
    "@yahoo.com",
    "@outlook.com"
  ],
  "maxEmails": 20,
  "excludeWords": [
    "crypto"
  ]
}
```

The `keywords` field is the only required input. All other fields are optional and can be adjusted according to your search strategy.

### 📤 Output

The Actor stores records in the `Upwork Emails Dataset`.

The configured default dataset view is `Scraped Leads`. It displays the following fields:

- Keyword
- Title
- Description
- URL
- Email

The underlying pushed record also contains the `network` field.

#### 📦 Example Output

```json
{
  "network": "Upwork.com",
  "keyword": "Python Developer",
  "title": "Example Upwork Result",
  "description": "Example search-result description with contact example@gmail.com",
  "url": "https://www.upwork.com/example",
  "email": "example@gmail.com"
}
```

This is an illustrative example. Actual titles, descriptions, URLs, and emails depend on available search results.

> **📊 Data Fields**
>
> - `network` — identifies the source as Upwork.com
> - `keyword` — records the keyword used for discovery
> - `title` — stores the result title
> - `description` — stores the result description
> - `url` — stores the returned result URL
> - `email` — stores the discovered matching email

### 💰 Upwork Email Scraper – Pricing and Limits

The provided Actor configuration does not define a fixed monetary price.

However, the implementation includes a free-tier email limitation. For free users, the requested `maxEmails` value is reduced to 100 when it is missing or greater than 100.

For paid users, this specific 100-email ceiling is not applied by the Actor's plan logic.

> **💰 Limit Summary**
>
> - Input range for `maxEmails`: 1–10,000
> - Default `maxEmails`: 5
> - Target applies independently to each keyword + domain combination
> - Free-tier ceiling: 100 per keyword + domain combination
> - Actual output may be lower than the target
> - Public search availability determines how many matching emails can be found
> - Wide searches can require more processing time

The Actor's configuration also notes a default run timeout of 3600 seconds. Large combinations of keywords, domains, and locations may require additional run time.

### 💡 Tips and Best Practices

The quality of an Upwork Email Scraper run depends heavily on the search terms and filters you provide.

> **⚡ Practical Tips**
>
> - Use multiple specific keywords
> - Combine job titles with skills or specialties
> - Add several relevant email domains
> - Use location targeting only when needed
> - Broaden keywords when results are sparse
> - Remove the location filter if geographic targeting is too restrictive
> - Use exclusion terms to remove clearly irrelevant categories
> - Start with a small `maxEmails` value when testing
> - Increase the target after validating your search strategy

#### 🔍 Use Specific Search Intent

Instead of relying only on `Developer`, try related terms such as `Python Developer`, `Web Developer`, or `Full Stack Developer` when those categories match your goal.

#### 📧 Expand Domain Coverage

Using only one email domain can restrict the search. Adding relevant domains may uncover different publicly indexed results.

#### 📍 Test Geographic Filters

A location can improve relevance but reduce coverage. Compare location-specific and unrestricted searches when results are limited.

#### 🧹 Avoid Excessive Exclusions

Exclusion filters should be specific enough to remove unwanted categories without accidentally excluding useful professional results.

### ❓ Frequently Asked Questions

#### ❓ What is Upwork Email Scraper?

Upwork Email Scraper is an Apify Actor that discovers publicly indexed email addresses associated with Upwork search results using keywords, optional locations, and selected email domains.

#### ❓ How does Upwork Email Scraper find emails?

It searches publicly indexed Upwork-related results using your keyword, email-domain suffix, and optional location, then extracts matching email addresses from available result descriptions.

#### ❓ Does Upwork Email Scraper directly scrape every Upwork profile?

No. Its discovery workflow is based on publicly indexed search results. The returned title, description, and URL come from the search-result information available during processing.

#### ❓ Can I search Upwork using multiple keywords?

Yes. The required `keywords` field accepts multiple search terms or queries.

#### ❓ What keywords can I use with Upwork Email Scraper?

You can use professional roles, skills, service categories, or other relevant search terms, such as `Freelancer`, `Developer`, `Python Developer`, or `Graphic Designer`.

#### ❓ Can I search multiple email domains?

Yes. `customDomains` accepts multiple email suffixes, including common providers and custom domains.

#### ❓ Is `maxEmails` a run-wide total?

No. The Actor processes each keyword + domain combination independently. For example, three keywords and two domains create six combinations, each with its own target.

#### ❓ What is the maximum value for `maxEmails`?

The configured input range is 1 to 10,000. Free-tier processing can reduce the effective value to 100 per keyword + domain combination.

#### ❓ Does `maxEmails` guarantee that many contacts?

No. It is a target or cap. The Actor can only collect matching email addresses that are publicly indexed and discoverable.

#### ❓ Can I target a specific city or country?

Yes. Enter the desired geographic term in `location`. Leave it empty when you want to search without geographic filtering.

#### ❓ How does `excludeWords` work?

The Actor checks the result description before extracting an email. If a configured word or phrase appears there, that complete snippet is skipped.

#### ❓ Does the Actor remove duplicate emails?

Yes. Previously discovered email addresses are tracked so the same email is not repeatedly added to the collected set.

#### ❓ Why did I receive fewer emails than my target?

A lower result count can occur when keywords are too narrow, the location is restrictive, selected domains have limited matches, or insufficient matching information is publicly indexed.

Try broader keywords, additional email domains, or a broader location.

#### ❓ Can Upwork Email Scraper be used for freelancer research?

Yes. Keywords targeting freelancers, developers, designers, agencies, and other professional categories can be used for legitimate research and contact discovery workflows.

#### ❓ What fields are included in the output?

The Actor pushes `network`, `keyword`, `title`, `description`, `url`, and `email`. The default dataset view displays keyword, title, description, URL, and email.

#### ❓ Can an interrupted run retain its progress?

The Actor persists its search position and discovered-email state during processing, allowing progress to be retained when processing is resumed.

### 🛡️ Responsible Data Use

Upwork Email Scraper is intended for legitimate research and data-collection workflows involving publicly available information.

Users are responsible for ensuring that their collection, storage, and use of contact information comply with applicable privacy, data-protection, anti-spam, marketing, employment, and other relevant laws and regulations.

Always use collected contact information responsibly and respect applicable website terms and communication requirements.

### 🤝 Support

For questions, customization requests, or help with configuring keywords, locations, email domains, and exclusion filters, you can contact me by email.

**contact me by email : <alphascraper69@gmail.com>**

# Actor input Schema

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

A list of keywords or queries to search for.

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

Optional country, state or city used to narrow the search. Leave it empty to search without a geographic filter.

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

List of custom email domains

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

How many addresses each search keyword + domain suffix combination may collect before the finder moves on to the next one. This is a per-combination target, not a run-wide total: with 3 keyword and 2 Domains and a limit of 20, the run works through all 6 combinations and aims for up to 20 addresses in each, so up to 120 overall. Lower values finish sooner and cost less; higher values dig deeper but never guarantee a fuller result, since the run can only find what is publicly listed.

## `excludeWords` (type: `array`):

Words or phrases you do not want to see.

## Actor input object example

```json
{
  "keywords": [
    "Freelancer",
    "Developer"
  ],
  "location": "",
  "customDomains": [
    "@gmail.com"
  ],
  "maxEmails": 5,
  "excludeWords": []
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

# 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": [
        "Freelancer",
        "Developer"
    ],
    "location": "",
    "customDomains": [
        "@gmail.com"
    ],
    "excludeWords": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("email_scraper/upwork-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": [
        "Freelancer",
        "Developer",
    ],
    "location": "",
    "customDomains": ["@gmail.com"],
    "excludeWords": [],
}

# Run the Actor and wait for it to finish
run = client.actor("email_scraper/upwork-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": [
    "Freelancer",
    "Developer"
  ],
  "location": "",
  "customDomains": [
    "@gmail.com"
  ],
  "excludeWords": []
}' |
apify call email_scraper/upwork-email-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,email_scraper/upwork-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/5yWgNgHycyuw9o7G0/builds/FMrsGhqkgfiR3fpZl/openapi.json
