# Upwork Freelance Jobs & Projects Scraper (`wyle/upwork-jobs-scraper`) Actor

Fast, high-yield HTTP-only scraper for Upwork job postings and freelance projects. Extracts job titles, full descriptions, budget, hourly rates, client intelligence (country, feedback, total spent, hires count), required skills, duration, and proposal counts with zero browser overhead.

- **URL**: https://apify.com/wyle/upwork-jobs-scraper.md
- **Developed by:** [Willy Lengkong](https://apify.com/wyle) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.90 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## 💼 Upwork Freelance Jobs & Projects Scraper

High-yield, HTTP-only reverse-engineered scraper for **Upwork freelance jobs, projects, and client intelligence**. Extracts job titles, full descriptions, budgets, hourly rate ranges, required skills, proposal counts, and client hiring history with **zero browser overhead** and minimal memory consumption (< 256MB).

***

### ⚡ Key Features

- **Blazing Fast HTTP Extraction**: Direct HTTP extraction powered by `curl_cffi` with Chrome 124 TLS (JA3/JA4) fingerprinting and HTTP/2 framing.
- **Client Intelligence**: Extracts valuable client data including feedback rating, total spend ($ spent), total past hires count, verification status, and country.
- **Dual Pipeline Architecture**:
  - **Pipeline A (GraphQL Engine)**: Optional direct high-speed GraphQL querying when a `masterAccessToken` cookie is provided.
  - **Pipeline B (HTTP Residential Pipeline)**: Automated web search scraping using Apify Residential Proxy (US) to bypass Cloudflare Managed Challenges without requiring a login.
- **Rich Filtering**: Filter by search keywords, contract types (Hourly / Fixed), rate ranges ($/hr and fixed budget), experience levels (Entry, Intermediate, Expert), and payment verification.
- **Pay-Per-Event (PPE) Ready**: Extremely cost-efficient execution with negligible platform usage, perfect for competitive marketplace pricing.

***

### 📥 Input Parameters

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `queries` | Array of Strings | No | `["python"]` | List of keywords or job titles to search on Upwork. |
| `sort` | String (Select) | No | `"recency"` | Result ordering: `"recency"` (Newest first) or `"relevance"`. |
| `jobType` | String (Select) | No | `"all"` | Filter by contract type: `"all"`, `"hourly"`, or `"fixed"`. |
| `hourlyMin` | Integer | No | `None` | Minimum hourly rate in USD (e.g. `25`). |
| `hourlyMax` | Integer | No | `None` | Maximum hourly rate in USD (e.g. `100`). |
| `fixedMin` | Integer | No | `None` | Minimum fixed budget in USD (e.g. `500`). |
| `fixedMax` | Integer | No | `None` | Maximum fixed budget in USD (e.g. `5000`). |
| `experienceLevel` | Array | No | `[]` | Filter by `["entry", "intermediate", "expert"]`. |
| `paymentVerifiedOnly` | Boolean | No | `false` | Only return jobs from clients with verified payment methods. |
| `masterAccessToken` | String | No | `None` | Optional Upwork session token (`master_access_token` cookie) for direct GraphQL querying. |
| `maxItems` | Integer | No | `50` | Maximum number of job postings to scrape. |
| `proxyConfiguration` | Object | No | `{"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "US"}` | Proxy configuration (Apify Residential Proxy US strongly recommended). |

***

### 📤 Output Schema Example

Each dataset item pushed to the default Apify Dataset matches the following JSON structure:

```json
{
  "id": "~01a2b3c4d5e6f7g8",
  "title": "Senior Python & AI Agent Engineer Needed",
  "description": "We are seeking an experienced Python engineer to develop autonomous LangGraph/LlamaIndex agents with tool-calling capabilities...",
  "url": "https://www.upwork.com/jobs/~01a2b3c4d5e6f7g8",
  "jobType": "Hourly",
  "budget": "$45.00 - $80.00 / hr",
  "hourlyBudgetMin": 45.0,
  "hourlyBudgetMax": 80.0,
  "fixedPrice": null,
  "currency": "USD",
  "experienceLevel": "Expert",
  "duration": "1 to 3 months",
  "workload": "Less than 30 hrs/week",
  "skills": [
    "Python",
    "FastAPI",
    "Artificial Intelligence",
    "Web Scraping",
    "API Development"
  ],
  "category": "Software Development",
  "subcategory": "Back-End Development",
  "clientCountry": "United States",
  "clientCity": "San Francisco",
  "clientRating": 4.95,
  "clientReviewsCount": 38,
  "clientTotalSpent": "$40K+",
  "clientTotalHires": 25,
  "clientPaymentVerified": true,
  "proposalsTier": "5 to 10",
  "publishedDate": "2026-09-06T14:30:00Z",
  "scrapedAt": "2026-09-06T15:15:00.000000+00:00"
}
```

***

### 🚀 Use Cases

1. **Freelancer Job Hunting**: Monitor high-ticket freelance gigs within minutes of posting and receive instant alerts.
2. **Talent & Recruitment Intel**: Analyze competitive salary/hourly rate trends and demand for specific technology stacks.
3. **Lead Generation**: Identify high-spending corporate clients hiring for recurring enterprise software projects.

# Actor input Schema

## `queries` (type: `array`):

List of keywords or job titles to search on Upwork (e.g. 'python', 'ai agent', 'web scraping', 'react').

## `sort` (type: `string`):

Order of job results.

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

Filter by hourly contracts, fixed-price contracts, or both.

## `hourlyMin` (type: `integer`):

Minimum hourly rate filter (in USD).

## `hourlyMax` (type: `integer`):

Maximum hourly rate filter (in USD).

## `fixedMin` (type: `integer`):

Minimum fixed budget filter (in USD).

## `fixedMax` (type: `integer`):

Maximum fixed budget filter (in USD).

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

Filter by required experience levels.

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

Only return jobs from clients with verified payment methods.

## `clientCountries` (type: `array`):

Filter jobs by client location (e.g., 'United States', 'United Kingdom', 'Canada').

## `directUrls` (type: `array`):

Direct Upwork search URLs (e.g. 'https://www.upwork.com/nx/search/jobs/?q=python\&sort=recency').

## `masterAccessToken` (type: `string`):

Optional Upwork 'master\_access\_token' cookie or Bearer token for direct high-speed GraphQL querying.

## `maxItems` (type: `integer`):

Maximum number of job postings to scrape and push to the dataset.

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

Proxy settings. For Upwork Cloudflare WAF bypass, Apify Residential Proxy (US) is strongly recommended.

## Actor input object example

```json
{
  "queries": [
    "python",
    "ai developer"
  ],
  "sort": "recency",
  "jobType": "all",
  "paymentVerifiedOnly": false,
  "maxItems": 50,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

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

Dataset containing structured Upwork job postings with budgets, hourly rates, client information, and skills.

# 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 = {
    "queries": [
        "python",
        "ai developer"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("wyle/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 = { "queries": [
        "python",
        "ai developer",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("wyle/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 '{
  "queries": [
    "python",
    "ai developer"
  ]
}' |
apify call wyle/upwork-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,wyle/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/brgwp0amksurCCSCC/builds/64dfMqyDovJZgXra6/openapi.json
