Upwork Jobs Scraper
Pricing
Pay per usage
Upwork Jobs Scraper
Extract freelance jobs from Upwork with job titles, descriptions, budgets, hourly rates, skills, categories, client details, posting dates, and job URLs. Ideal for freelance job scraping, lead generation, market research, competitor analysis, and remote job monitoring.
Pricing
Pay per usage
Rating
0.0
(0)
Developer
Shahid Irfan
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
2
Monthly active users
6 days ago
Last modified
Categories
Security
Limited permissionsShare
What does Upwork Jobs Scraper do?
Upwork Jobs Scraper collects job postings from Upwork search results and returns them as a structured dataset. Give it a keyword or any Upwork jobs search URL, and it saves each posting with its budget, contract type, experience level, duration, skills, client signals, and publication time. Every run writes to an Apify dataset that you can download as JSON, CSV, or Excel.
Use it to find new freelance work, watch a niche for new postings, compare budgets across skills, or feed job data into a spreadsheet, database, or AI workflow.
Why use Upwork Jobs Scraper?
Upwork search pages are built for browsing, not for collecting. Sorting through results by hand does not scale, and copying postings into a sheet loses the numbers you need for comparison.
This Actor handles the repeated work:
- One row per posting with consistent field names, so a spreadsheet stays usable across runs.
- Filters that carry over from the URL you build on Upwork, including experience level, contract type, budget range, and hourly rate.
- Client signals such as country, payment verification, total spend, and review count when Upwork publishes them.
- Duplicate protection within a run, so paging through results does not repeat the same posting.
- Scheduling in Apify Console for daily or hourly monitoring.
- Exports and integrations through Apify datasets, webhooks, Make, Zapier, and Google Sheets.
What data can you extract from Upwork?
| Field | Description |
|---|---|
title | Job posting title |
description | Posting text as published by the client |
budget | Fixed budget or hourly range, for example $500.00 or $30.00 - $155.00/hr |
contractType | Fixed-price, Hourly, or Not specified |
experienceLevel | Entry level, Intermediate, Expert, or Not specified |
projectLength | Expected duration and work load when Upwork lists them |
skills | Skill tags attached to the posting |
postedDate | Relative age such as 3 hours ago |
publishedAt | Publication time as an ISO timestamp |
clientInfo | Combined client signals in one readable string |
url | Direct link to the posting |
jobId | Upwork job identifier, useful for deduplication across runs |
fixedBudget, hourlyRateMin, hourlyRateMax, clientCountry, clientPaymentVerified, clientTotalSpent, and clientReviewCount keep the same values in numeric or boolean form, so you can sort and filter without parsing text.
Upwork shows fewer client signals to signed-out visitors. When a value is unavailable, the field is empty or null and clientInfo contains only the signals that were published.
How to use Upwork Jobs Scraper
- Open the Actor on Apify Store.
- Paste an Upwork jobs search URL, or type a keyword.
- Set the maximum number of jobs and pages.
- Start the run.
- Download the dataset or connect it to your workflow.
The simplest input is a keyword. The most precise input is a search URL built on Upwork itself, because every filter you set on the site travels with the URL.
Input Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
searchUrl | String | No | https://www.upwork.com/nx/search/jobs/?q=web%20scraping&sort=recency | Upwork jobs search URL. Filters in the URL are preserved |
keyword | String | No | - | Searches by keyword and takes precedence over searchUrl. Results are sorted by recency |
maxJobs | Integer | No | 20 | Maximum jobs to save. 0 means no limit, bounded by maxPages |
maxPages | Integer | No | 20 | Maximum result pages to request. Each page holds up to 50 jobs |
proxyConfiguration | Object | No | Apify Proxy | Proxy settings. Apify Proxy is on by default to give each run a stable cloud connection |
Usage Examples
Keyword search
Collect the twenty newest postings for a skill:
{"keyword": "rust developer","maxJobs": 20}
Filtered search by URL
Build the search on Upwork, copy the URL, and keep the filters: expert level, fixed price, and a budget between $500 and $1,000.
{"searchUrl": "https://www.upwork.com/nx/search/jobs/?q=python&contractor_tier=3&t=1&amount=500-1000&sort=recency","maxJobs": 100,"maxPages": 4}
Large monitoring run
Collect up to 500 postings for a category, then schedule the run to repeat daily:
{"searchUrl": "https://www.upwork.com/nx/search/jobs/?q=data%20entry&sort=recency","maxJobs": 500,"maxPages": 20}
Category page URL
A category page such as https://www.upwork.com/freelance-jobs/web-scraping/ is accepted. Upwork lists only ten static postings there, so the Actor converts the category to its equivalent keyword search to return the full result set.
{"searchUrl": "https://www.upwork.com/freelance-jobs/web-scraping/","maxJobs": 100}
Sample Output
{"title": "Web scraping for contact details","description": "Hi. I'm looking for a list of contact email addresses for Scout groups, guide groups and woodcraft groups in the UK.","budget": "$50.00","experienceLevel": "Intermediate","contractType": "Fixed-price","projectLength": "Less than 1 month","skills": ["Data Scraping", "Data Entry", "Prospect List"],"postedDate": "3 hours ago","clientInfo": "","url": "https://www.upwork.com/jobs/~022116455622075806435","scrapedAt": "2026-10-31T12:16:04.124Z","jobId": "2116455622075806435","publishedAt": "2026-10-31T09:05:08.494Z","fixedBudget": 50,"hourlyRateMin": null,"hourlyRateMax": null,"clientCountry": "","clientPaymentVerified": false,"clientTotalSpent": null,"clientReviewCount": null}
Tips for Best Results
- Start with a small
maxJobsvalue to confirm the search returns what you expect before running a large collection. - Build filters on Upwork first, then copy the URL. The Actor does not need to reinterpret your filters because they travel in the URL.
- Use
sort=recencyfor monitoring. The default relevance order is better for research on a fixed topic. - Set
maxPagesto match your result budget. One page returns up to 50 jobs in a single request. - Schedule daily or hourly runs and use Apify's dataset comparison or webhooks to act on new postings.
- If a field is empty, check another posting before assuming a problem. Signed-out visitors see fewer client details, and not every posting lists a budget or duration.
- Result counts can differ from what you see in your browser. Upwork varies search results by visitor location, so a run through a different proxy exit may return fewer or more postings for the same query.
Output and Exports
Every run writes to the default dataset. Open the Output tab to preview the table, or download the data as JSON, CSV, Excel, XML, or HTML. The statistics key in the run's key-value store records the saved count, pages requested, extraction path, stop reason, and duration.
Integrations
- Google Sheets - Send each run to a spreadsheet for review.
- Webhooks - Trigger your own service when a run finishes.
- Make or Zapier - Route new postings into alerts, databases, or messaging.
- API - Read the dataset from your own application using the Apify API.
- Schedules - Run the Actor hourly, daily, or weekly without manual work.
Frequently Asked Questions
How many jobs can I collect in one run?
maxJobs accepts up to 10,000 and maxPages accepts up to 200. A page returns up to 50 jobs, so 200 pages can cover roughly 10,000 postings when the search has that many results. Set maxJobs to 0 to remove the job cap and rely on maxPages.
What happens if I supply both searchUrl and keyword?
The keyword wins. The Actor ignores the URL entirely so a keyword run is never mixed with a prefilled URL. Clear the unused field if you switch modes in Apify Console.
Why is clientInfo empty on some rows?
Upwork hides several client signals from signed-out visitors. Payment verification, country, spend, and review count appear when Upwork publishes them for the visitor; otherwise those fields stay empty. This is source behaviour, not a scraping failure.
Why do some postings show "Not specified" for budget?
Not every client publishes a budget or an hourly range. When Upwork has no value, the Actor returns Not specified and leaves fixedBudget, hourlyRateMin, and hourlyRateMax as null.
Can I export the data to CSV or Excel?
Yes. Apify datasets can be downloaded as CSV, Excel, JSON, XML, and HTML from the Output tab or through the API.
Can I run this on a schedule?
Yes. Create a schedule in Apify Console and reuse the same input. For monitoring, keep sort=recency and compare each dataset with the previous run.
Does the Actor need my Upwork account?
No. It reads public search results. You do not need to sign in, and the Actor does not ask for Upwork credentials.
What should I do if a run returns no jobs?
Check the run log and the statistics key. The stop reason tells you whether the search had no matches, the page limit was reached, or Upwork rejected the request. For request-level problems, see the troubleshooting notes in the repository's API_DISCOVERY.md.
Is it legal to collect Upwork job data?
The Actor reads publicly visible job postings. You are responsible for complying with Upwork's terms, applicable privacy law, and the rules that apply to your use of the data. Do not use it to collect personal data or to contact people who did not publish contact details.
Related Actors
- Fast LinkedIn Job Scraper for LinkedIn job postings.
- Wellfound Jobs Scraper for startup roles.
- ZipRecruiter Job Scraper for US job listings.
Support
For issues, feature requests, or a custom Actor, use the Issues tab on the Actor page or contact the developer through Apify.
Legal Notice
This Actor is designed for legitimate collection of publicly available Upwork job postings. Users are responsible for complying with applicable laws, Upwork's terms of service, and any privacy obligations that apply to their use of the data.