Upwork Jobs Scraper: Multipage Job Search & Client Data avatar

Upwork Jobs Scraper: Multipage Job Search & Client Data

Deprecated

Pricing

from $1.60 / 1,000 jobs

Go to Apify Store
Upwork Jobs Scraper: Multipage Job Search & Client Data

Upwork Jobs Scraper: Multipage Job Search & Client Data

Deprecated

Scrape Upwork freelance jobs across multiple search pages. Collect descriptions, skills, budgets and client details. Filter and export JSON, CSV or Excel.

Pricing

from $1.60 / 1,000 jobs

Rating

0.0

(0)

Developer

Stan Van Rooy

Stan Van Rooy

Maintained by Community

Actor stats

7

Bookmarked

73

Total users

1

Monthly active users

13 days ago

Last modified

Share

Upwork Jobs Scraper: Job Search, Budgets & Client Data

Search Upwork freelance jobs across multiple result pages and export structured data to JSON, CSV or Excel. Collect job titles, full descriptions, skills, hourly rates, fixed-price budgets, experience levels and posting dates. Add public client information and proposal activity when you need richer qualification data.

Use keywords such as python developer, Shopify, AI automation or virtual assistant. The Actor follows Upwork's public guest-search pagination, removes duplicate job IDs and keeps collecting until it reaches your result limit, the available results or your page budget. No Upwork login, cookies or personal API key is required.

Quick start: search beyond the first page

{
"search": "python developer",
"limit": 150,
"include_details": false,
"sort": "newest"
}

On a paid Apify plan, this requests up to 150 unique jobs across successive search pages. Free-plan accounts stop at 100 rows per run. Actual output depends on the query, filters and Upwork availability.

Fast listing mode: include_details: false reads full descriptions, skills and budgets directly from search results. It avoids a separate page request for each job. At a page size of 50, 150 unfiltered results require three search-page requests plus guest-session setup.

Enriched mode: include_details: true (the default) also visits each selected job's public page to collect available client and application information. These extra requests take longer.

Search several topics in one run

{
"searches": ["python automation", "Shopify developer", "AI integration"],
"limit": 300,
"include_details": false
}

Queries run in input order and share one output limit. Duplicate jobs are saved once. An earlier query can fill the limit before later queries are reached. newest applies within each query; the combined dataset is not globally sorted across queries.

Filter freelance opportunities

{
"search": "python",
"keywords": "automation",
"job_type": "hourly",
"min_hourly_rate": 25,
"contractor_tier": ["2", "3"],
"limit": 50,
"include_details": true
}

Keyword search, contract type, experience level and category are sent to Upwork's guest search. Additional keywords and budget checks are applied to the returned jobs. The Actor continues through later pages when local filters remove results.

Upwork may broaden an unquoted search to related results, even for an unfamiliar term. To request an exact phrase, include quotes inside the search value, for example "search": "\"python developer\"". Use keywords when every supplied word must appear in the returned title, description or skills.

What you get

DataFast listing modeWith job details
Complete job ID, URL, title and descriptionYesYes
Skills, experience level and contract typeYesYes
Fixed budget or hourly range, when publishedYesYes
Posting date, publish date and project durationYesYes
Client country, city, verification and rating—When public
Client spending, hours and hiring history—When public
Proposal range, applicants, interviews and invitations—When public
Category and category group in the output—When public

Missing fields remain absent or null. Decimal budgets, client spending and billed hours retain their precision. detail_status distinguishes not_requested, complete and failed enrichment.

Input reference

Provide at least one of search, searches or start_urls.

ParameterDefaultDescription
search—Upwork job-search keywords.
searches[]Up to 20 additional keyword queries, combined with search.
limit10Maximum unique output jobs across all inputs, from 1 to 1,000.
include_detailstrueAdd public client and job activity details. Disable for faster listing-only collection.
sortnewestnewest or relevance, applied by Upwork within each query.
job_typebothboth, hourly or fixed.
contractor_tier[]Experience levels: "1" entry level, "2" intermediate, "3" expert.
category—Optional category or subcategory selected in the input form.
keywords""Additional local filter across title, description and skills. All supplied words must match.
min_fixed_price, max_fixed_price—USD budget range, applied to fixed-price jobs.
min_hourly_rate, max_hourly_rate—USD hourly range. A job qualifies when its published range overlaps yours.
page_size50Jobs requested per search page: 10, 20 or 50.
max_pages100Maximum search pages per query, from 1 to 200. Bounds work when filters are restrictive.
max_concurrency4Concurrent detail requests, from 1 to 8. Search pages are fetched sequentially so limits and pagination can be checked.
start_urls[]Up to 100 supplemental public Upwork skill or job URLs, processed after search queries if output capacity remains.

A limit is a ceiling, not a promised result count. Budget filters exclude jobs whose required budget is unknown. Set job_type explicitly if you want only one contract type. Restrictive filters may require more pages; RUN_SUMMARY indicates when max_pages stopped the run.

Direct job and skill URLs

Use public /jobs/~ID/ or /freelance-jobs/apply/TITLE_~ID/ links to revisit known jobs. Direct job URLs always load the job details.

{
"start_urls": ["https://www.upwork.com/freelance-jobs/shopify/"],
"limit": 20,
"include_details": false
}

Skill URLs are a different source: /freelance-jobs/<skill>/ pages expose a limited public sample, currently up to 30 jobs. They do not paginate. Use search: "shopify" for paginated retrieval. Category filtering of explicit URLs requires detail requests, even in listing mode.

Output example

Illustrative listing-mode row:

{
"id": "022000000000000000001",
"url": "https://www.upwork.com/jobs/~022000000000000000001/",
"title": "Python developer for workflow automation",
"description": "Build a Python workflow that connects our reporting tools.",
"job_type": "hourly",
"skills": ["Python", "API Integration"],
"experience_level": "Intermediate",
"contractor_tier": "2",
"fixed_budget": null,
"hourly_min": 25.5,
"hourly_max": 50,
"duration": "1 to 3 months",
"posted_at": "2026-10-01T08:00:00Z",
"scraped_at": "2026-10-01T09:00:00+00:00",
"search_query": "python developer",
"search_offset": 50,
"detail_status": "not_requested"
}

Enrichment adds flat fields such as client_location_country, client_payment_verified, client_stats_total_spent, client_stats_total_hours_hired, job_activity_proposals_min and job_activity_interviewing.

Export, monitor and integrate

Download results as JSON, CSV or Excel from the run's Output tab. Use the Apify API or schedules for recurring opportunity tracking, agency research, budget analysis and freelance-market reporting. To identify newly discovered jobs across runs, compare the complete id field; deduplication within a run does not create a persistent history.

The Run summary output links to RUN_SUMMARY, which records page offsets, unique IDs discovered per page, total jobs reported by Upwork, saved rows, request counts and errors. This makes it possible to verify that the Actor progressed beyond page one.

Reliability and limitations

  • Search uses the jobs available to anonymous Upwork visitors. Private or account-restricted listings are not included.
  • Search results change while a run is in progress. Deduplication prevents repeated output, but a live search is not a historical snapshot or a guarantee of complete coverage.
  • A repeated page with no new IDs, an unexpected offset, a rejected request or an invalid response is treated as a failure—not a successful empty search.
  • A valid search with no matches completes with zero rows and an explicit result message.
  • If enrichment or a later search page fails, already-saved rows remain available and the run is marked failed. Check detail_status and RUN_SUMMARY before retrying.
  • Reaching the result limit or max_pages ends the run gracefully with an explicit status message.
  • Upwork can change its guest interfaces, restrict access or remove jobs. No fixed success rate is promised.

Pricing and Free-plan sample

Apify Free accounts can collect up to 100 result rows total per run, shared across all queries and URLs. The Actor stops requesting further pages once that output cap is reached and applies it before detail enrichment. Upgrade your Apify plan for larger runs. Normal Actor charges apply, including any applicable start charge on runs with no results. See the Store pricing panel for current charges.

The sample resets each run; it is not a daily or monthly quota. Paid accounts can request up to 1,000 unique jobs per run, subject to source availability and the configured page budget.

October 2026 update

This release replaces the former HTML search path, which began returning a login page, with paginated guest search. It adds multiple queries, optional faster listing mode, direct URLs, full-ID deduplication, structured job and client data, and explicit failure reporting. Existing budget, experience and category inputs remain available.

For support, open the Actor's Issues tab with the run URL and a non-sensitive input example.