# 🔥 Upwork Jobs Scraper (`kobimantzur/upwork-jobs-scraper`) Actor

Scrape Upwork job listings at scale — titles, budgets, hourly rates, skills, and client details. Filter by keyword, client location, experience level, job type, and budget. Bypasses Cloudflare with residential proxies. Export to JSON, CSV, or Excel.

- **URL**: https://apify.com/kobimantzur/upwork-jobs-scraper.md
- **Developed by:** [Pedrock LLC](https://apify.com/kobimantzur) (community)
- **Categories:** Jobs, AI, Agents
- **Stats:** 1,856 total users, 4 monthly users, 100.0% runs succeeded, 74 bookmarks
- **User rating**: 2.17 out of 5 stars

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## 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 Jobs Scraper 🔥

**Scrape Upwork.com job listings at scale — titles, budgets, hourly rates, skills, client details, and more. Bypasses Cloudflare with residential proxies. Filter by keyword, location, experience level, budget, and job type.**

Perfect for freelancers hunting new gigs, agencies tracking demand, and analysts studying the freelance market. Enter a keyword, pick your filters, and get a clean structured dataset (JSON, CSV, Excel) in minutes.

***

### ✨ Why this scraper

- **Actually works** — parses Upwork's current layout and clears the Cloudflare "Just a moment" challenge with residential proxies + Turnstile handling.
- **Powerful filtering** — keyword, client location, experience level, hourly-rate range, job type (hourly/fixed), payment-verified-only, and sort order.
- **Rich data** — title, full description, budget/hourly rate, skills, experience level, estimated time, posting time, and a stable job ID.
- **Bring your own filters** — paste any Upwork search URL directly via Start URLs.
- **Optional logged-in mode** — supply session cookies to unlock client fields (total spent, payment verified, rating, proposals).
- **No duplicates** — results are de-duplicated by job URL automatically.

### 🚀 How to use

1. Enter one or more **Job keywords** (e.g. `React developer`, `logo design`).
2. *(Optional)* Add **Client locations**, **Experience level**, **Job type**, **hourly-rate range**, or **payment-verified only**.
3. Set **Max results** (and optionally **Max results per search** to spread results across locations).
4. Keep the default **Residential** proxy. Click **Start**.
5. Download your data as JSON, CSV, or Excel — or pull it via the API.

> 💡 **Tip:** To scrape a very specific search, run it once on upwork.com, copy the URL from your browser, and paste it into **Start URLs** — every filter you set on Upwork is respected.

### 🔎 Filtering options

| Filter | Input field | Notes |
|---|---|---|
| Keyword | Job keywords | One search per keyword |
| Client location | Client locations | Country or region |
| Experience level | Experience level | Entry / Intermediate / Expert |
| Contract type | Job type | Hourly / Fixed / Any |
| Hourly rate | Min / Max hourly rate | Applies to hourly jobs |
| Payment verified | Payment-verified only | Verified clients only |
| Sort | Sort by | Most recent / Relevance |
| Raw search | Start URLs | Paste any Upwork search URL |

### 📤 Output fields

Each job in the dataset includes:

| Field | Description |
|---|---|
| `jobId` | Stable Upwork job identifier |
| `title` | Job title |
| `url` | Direct link to the job posting |
| `description` | Full job description |
| `postedAt` | When it was posted (e.g. "Posted 13 minutes ago") |
| `contractType` | e.g. "Hourly: $60.00 - $85.00" or "Fixed price" |
| `hourlyRate` | Hourly range (hourly jobs) |
| `fixedPriceBudget` | Budget (fixed-price jobs) |
| `experienceLevel` | Entry / Intermediate / Expert |
| `estimatedTime` | Duration & weekly hours |
| `tags` | Required skills |
| `searchQuery`, `searchLocation` | The search that produced the row |

**Logged-in mode (cookies) additionally populates:** `clientPaymentVerified`, `clientSpent`, `clientLocation`, `clientRating`, `proposals`.

#### Example output

```json
{
  "jobId": "2076800888120589296",
  "title": "Python/FastAPI + React Developer for small feature update",
  "url": "https://www.upwork.com/jobs/...",
  "postedAt": "Posted 13 minutes ago",
  "description": "We're looking for a developer to add 2 small features...",
  "contractType": "Hourly: $60.00 - $85.00",
  "hourlyRate": "$60.00 - $85.00",
  "fixedPriceBudget": "",
  "experienceLevel": "Expert",
  "estimatedTime": "Less than 1 month, Less than 30 hrs/week",
  "tags": ["React", "Python", "FastAPI", "AWS Lambda"],
  "searchQuery": "react developer",
  "searchLocation": "United States"
}
```

### 🔐 Unlocking client data (optional)

Client stats (spend, payment verification, ratings, proposals) are only visible to logged-in Upwork users. To include them:

1. Log in to Upwork in your browser.
2. Export your `upwork.com` cookies with a cookie-export extension (Cookie-Editor, EditThisCookie).
3. Paste the exported JSON array into the **Upwork login cookies** input.

Leave it empty to scrape anonymously (all non-client fields still work).

### 💡 Use cases

- **Freelancers** — monitor fresh, relevant postings without refreshing Upwork all day.
- **Agencies** — track demand and pricing for your services across regions.
- **Market research** — analyze rates, skills in demand, and hiring trends.
- **Lead generation** — build lists of clients actively hiring in your niche.

### 🌍 Supported locations

Any country or region Upwork supports (Americas, Europe, Asia, Africa, Oceania, and individual countries such as United States, United Kingdom, Canada, Germany, Australia, India, etc.).

### 🔌 API & integrations

Run this Actor from the [Apify API](https://docs.apify.com/api/v2), the CLI, or any integration (Make, Zapier, n8n, webhooks). Schedule it to run daily/weekly to keep a live feed of new jobs.

### 🤖 Use with AI agents (MCP)

This Actor is available as a tool for AI agents through the [Apify MCP server](https://mcp.apify.com/). Agents built with Claude, ChatGPT, or any MCP-compatible client can call it directly to fetch live Upwork jobs — no glue code needed.

- **MCP endpoint:** `https://mcp.apify.com`
- **Tool / Actor ID:** `kobimantzur/upwork-jobs-scraper`
- The structured input schema (keywords, filters) and output schema (typed job fields) let agents call it and parse results reliably.

Typical agent uses: "find fresh React jobs paying $50+/hr from verified US clients", monitoring pipelines, or feeding a job-matching assistant.

***

*Not affiliated with Upwork. Scrapes only publicly available job-listing data. Use responsibly and in line with applicable terms and laws.*

# Actor input Schema

## `searchQueries` (type: `array`):

One or more job titles / keywords to search for (e.g. "React developer"). Ignored if Start URLs are provided.

## `startUrls` (type: `array`):

Paste full Upwork job-search URLs (with your own filters). If set, these are scraped directly and Job keywords / filters below are ignored.

## `clientLocations` (type: `array`):

Optional. Country or region where the client is located (e.g. United States, Europe). Leave empty to search everywhere.

## `experienceLevel` (type: `array`):

Filter by required experience level.

## `jobType` (type: `string`):

Filter by contract type.

## `minHourlyRate` (type: `integer`):

Only hourly jobs paying at least this much (applies to hourly jobs).

## `maxHourlyRate` (type: `integer`):

Only hourly jobs paying at most this much.

## `paymentVerifiedOnly` (type: `boolean`):

Only return jobs from clients with a verified payment method.

## `sortBy` (type: `string`):

Sort order of results.

## `maxResults` (type: `integer`):

Maximum number of jobs to scrape across all searches.

## `maxResultsPerLocation` (type: `integer`):

Optional cap per keyword/location combination, so multi-location searches spread evenly instead of one filling the quota.

## `cookies` (type: `array`):

Paste your Upwork session cookies (e.g. exported with the EditThisCookie / Cookie-Editor extension) to run logged-in. This unlocks client fields: total spent, payment verified, rating, proposals. Leave empty for anonymous scraping.

## `proxyConfiguration` (type: `object`):

Residential proxies are strongly recommended — Upwork is behind Cloudflare and will block datacenter IPs.

## Actor input object example

```json
{
  "searchQueries": [
    "full stack developer"
  ],
  "jobType": "any",
  "paymentVerifiedOnly": false,
  "sortBy": "recency",
  "maxResults": 100,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# 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 = {
    "searchQueries": [
        "full stack developer"
    ],
    "maxResults": 100,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("kobimantzur/upwork-jobs-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 = {
    "searchQueries": ["full stack developer"],
    "maxResults": 100,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("kobimantzur/upwork-jobs-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 '{
  "searchQueries": [
    "full stack developer"
  ],
  "maxResults": 100,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call kobimantzur/upwork-jobs-scraper --silent --output-dataset

```

## MCP server setup

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