Upwork Job Finder
Pricing
$10.00 / 1,000 results
Upwork Job Finder
Scrapes job listings from Upwork based on a search query. Returns job title, link, description, type, experience level, and duration. Useful for freelancers to track new opportunities matching their skills.
Pricing
$10.00 / 1,000 results
Rating
4.9
(3)
Developer
Nahom D
Maintained by CommunityActor stats
10
Bookmarked
247
Total users
9
Monthly active users
6 days ago
Last modified
Categories
Share
Overview
Upwork Job Finder is an Apify Actor that scrapes freelance job listings from Upwork's public job search for any keyword you choose. It bypasses Cloudflare's anti-bot challenge using a stealth headless browser, extracts the embedded Nuxt application state, and returns clean, structured job data ready for analysis, alerting, or integration into downstream workflows.
Typical use cases:
- Build a daily feed of new freelance opportunities matching your skills.
- Power a job-alert email or Slack notification system.
- Track market rates, demand, and required skills for a niche over time.
- Feed structured job data into a CRM, Airtable base, or BI dashboard.
Features
- Search any Upwork query (skills, keywords, or phrases).
- Paginate through results one page at a time (available to all users).
-
Multi-page range scraping (paid users only): fetch up to 10 pages in a
single run using
pageStartandpageEnd. Free-tier users are limited to single-page scraping via thepagefield. - Automatic Cloudflare Turnstile solving via a stealthy headless browser.
- Optional Apify Proxy support via
proxyConfiguration. - Returns full job metadata: title, description, budget, skills, client info, posting timestamps, and more.
- Output is written to the Actor's default dataset with a typed schema and a pre-built table view.
Input
The Actor accepts either a plain search query or a
full Upwork searchUrl — not both. Use query for a
quick keyword search, or build a URL on
Upwork's search page (filters for budget,
experience level, duration, client history, etc.) and paste it into searchUrl.
Any Upwork URL filter works automatically.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
query | string | One of query/searchUrl | — | Plain keyword search (3–100 chars), e.g. "Airtable Automation". |
searchUrl | string | One of query/searchUrl | — |
Full Upwork search URL. Must match
https://www.upwork.com/nx/search/jobs/?.... Any other URL is rejected.
|
page | integer | No | 1 | Result page to fetch when pageStart/pageEnd are not provided. |
pageStart (paid only) | integer | No | — | First page in the range to fetch. Must be ≥ 1. Available to paying Apify users only. The run fails immediately if a free-tier user provides this field. |
pageEnd (paid only) | integer | No | — |
Last page in the range to fetch. Must be ≥ pageStart.
Available to paying Apify users only. The run fails immediately
if a free-tier user provides this field.
|
proxyConfiguration | object | No | — | Optional Apify Proxy configuration. Use the proxy editor in the Apify UI. |
Validation: the run fails fast if both query and
searchUrl are set, if neither is set, or if searchUrl is not a valid
Upwork search URL. The page range is capped to 10 pages per run.
Free vs. paid plans. Range-based scraping (pageStart/pageEnd) is restricted to paying Apify users. Free-tier users can still scrape jobs — just one page per run via thepagefield. If a free user passespageStartorpageEndthe run is rejected with a clear error message. Upgrade your Apify plan to unlock multi-page runs.
Example: simple keyword query
{"query": "Airtable Automation","page": 1}
Example: full search URL with filters
{"searchUrl": "https://www.upwork.com/nx/search/jobs/?client_hires=0&contractor_tier=1&duration_v3=semester&nbs=1&q=ai%20automation&sort=relevance%2Bdesc","page": 1}
Example: with Apify Proxy
{"query": "AI engineer","page": 2,"proxyConfiguration": {"useApifyProxy": true,"apifyProxyGroups": ["RESIDENTIAL"]}}
Example: page range (capped to 10 pages, paid users only)
{"query": "Airtable Automation","pageStart": 1,"pageEnd": 5}
Note: this input only works on a paid Apify plan. Free-tier users should use the
single-page page field instead, and loop over runs if multiple pages are needed
(see Paginating through all results).
Output
Each run pushes one record per job to the default dataset. A full JSON Schema is defined in
.actor/dataset_schema.json, and an Overview table view is available
in the Apify console for quick scanning.
Key output fields
| Field | Type | Description |
|---|---|---|
uid | string | Unique job identifier. |
ciphertext | string | URL slug. Build the job URL with https://www.upwork.com/jobs/{ciphertext}. |
title | string | Job title (may include <span class="highlight"> markup around matched terms). |
description | string | Full job description (may include highlight markup). |
type | integer | 1 = Fixed-price, 2 = Hourly. |
durationLabel | string | Expected project duration, e.g. "1 to 3 months". |
engagement | string | Engagement key, e.g. usnuxt_Engagement_421.partTime. |
tierText | string | Required experience tier (entry / intermediate / expert). |
amount.amount | number | Fixed-price budget in USD (0 for hourly jobs). |
hourlyBudget | object | { min, max } hourly rate in USD (both 0 for fixed-price jobs). |
publishedOn | string (ISO 8601) | When the job was published. |
attrs | array | Skill tags attached to the job, each with prefLabel and a highlighted flag. |
client | object | Client info: country, payment verification, total spent, reviews, and feedback rating. |
Sample output (truncated)
{"uid": "2054172332114949360","ciphertext": "~022054172332114949360","title": "Senior AI/ML Engineer for LLM and RAG Systems","description": "We are seeking a highly skilled Senior AI/ML Engineer ...","publishedOn": "2026-05-12T12:11:45.608Z","type": 2,"durationLabel": "More than 6 months","engagement": "usnuxt_Engagement_421.fullTime","tierText": "jsn_Expert_207","hourlyBudget": { "min": 30, "max": 60 },"amount": { "amount": 0 },"attrs": [{ "prefLabel": "Machine Learning", "highlighted": true },{ "prefLabel": "Artificial Intelligence", "highlighted": true },{ "prefLabel": "Python", "highlighted": false }],"client": {"location": { "country": null },"isPaymentVerified": false,"totalSpent": null}}
Usage
Run on the Apify platform
- Open the Actor in the Apify console.
- Set your
queryandpagevalues in the input form. - Click Start. Jobs appear in the Dataset tab when the run finishes.
- Export the dataset as JSON, CSV, Excel, or HTML, or fetch it via the Apify API.
Run via the Apify API
curl -X POST "https://api.apify.com/v2/acts/<ACTOR_ID>/runs?token=<APIFY_TOKEN>" \-H "Content-Type: application/json" \-d '{ "query": "Airtable Automation", "page": 1 }'
Run locally
Requires Python 3.11+ and the Apify CLI.
$apify run
Edit storage/key_value_stores/default/INPUT.json to change the input.
Paginating through all results
Free users: the Actor fetches one page per run via the page
field. To collect multiple pages, schedule or loop the Actor while incrementing
page until an empty dataset is returned:
for page in 1 2 3 4 5; doapify call <ACTOR_ID> --input "{\"query\":\"Airtable Automation\",\"page\":$page}"done
Paid users: use pageStart/pageEnd to fetch up to 10
pages in a single run, which is significantly faster than looping (the Cloudflare challenge
is solved once and reused across all pages):
$apify call <ACTOR_ID> --input "{\"query\":\"Airtable Automation\",\"pageStart\":1,\"pageEnd\":5}"
For ranges larger than 10 pages, paid users can still loop runs, incrementing
pageStart/pageEnd by 10 each iteration.
Limitations
- Only public search results are returned — no login-gated data.
-
Free-tier users are limited to single-page scraping
(
pageonly). ThepageStart/pageEndrange inputs require a paid Apify plan and will cause the run to fail on free accounts. -
Some client fields (
totalSpent,country,isPaymentVerified, review counts) may benullin the search-listing payload. Fetch the individual job page for the full client profile. titleanddescriptioncontain Upwork's search-highlight HTML markup; strip it client-side if you need plain text.- Heavy use of one IP may trigger Cloudflare. Use Apify Proxy for high-volume scraping.
Support & feedback
Found a bug or have a feature request? Open an issue on the Actor's source repository or contact the maintainer through the Apify console.
Wanna hire me? I'm a freelance software developer specializing in web scraping, automation, data engineering, web development, and much more. Check out my Upwork profile