Upwork Jobs Scraper avatar

Upwork Jobs Scraper

Pricing

from $1.23 / 1,000 job saveds

Go to Apify Store
Upwork Jobs Scraper

Upwork Jobs Scraper

Export public Upwork jobs with descriptions, budgets, skills and visible client details. Filter and download matching freelance opportunities.

Pricing

from $1.23 / 1,000 job saveds

Rating

0.0

(0)

Developer

Fetch Cat

Fetch Cat

Maintained by Community

Actor stats

0

Bookmarked

14

Total users

2

Monthly active users

2 days ago

Last modified

Features

Limited permissions

Share

Export public Upwork job previews and available public details, including descriptions, skills, publication dates, budgets and visible client facts. Account-restricted details stay marked as restricted, with no invented client object. The Actor does not sign in, accept account cookies, apply for jobs or collect private account information.

Quick start

Start with the existing two-job web-scraping search, then inspect source links and detailStatus before expanding the cap:

{"query":"web scraping","maxItems":2,"includeDetails":true}

The existing broader feed uses python with a fifty-job cap. A client-country filter such as Canada matches the hiring client's exposed country rather than the applicant's location. Narrow filters can scan more candidates than they save.

Prefer a video guide? This short Apify walkthrough shows you how to set up and run an Actor. It uses a different Actor, but the setup steps are the same.

Ready-to-run examples

Open a public example to inspect its input, run it, or reuse it as a task:

What you get

One unique matching job row with its source ID, URL, title, available description, skills and budget values. Public client facts and activity accompany complete details, while restricted previews remain useful labeled records. OUTPUT reports saved and scanned counts, restrictions and early-stop reasons.

Who is it for?

  • Freelancers shortlisting public opportunities against their own skills and budget requirements.
  • Agency research teams inspecting exposed demand and client context without automating outreach.
  • Labor-market analysts comparing bounded skill and budget samples with their publication times.
  • Data developers maintaining source-ID-based job datasets and downstream reports.

How you can use the data

  • Triage a web-scraping opportunity sample. Collect a small query sample and inspect title, description, skills and source URL. Keep detailStatus beside each record so a restricted preview is not presented as a complete brief.
  • Compare observed Python budgets. Use the existing python query and keep fixed-price and hourly values in separate columns with their source currency. Missing rates stay null rather than becoming zero or an estimated market price.
  • Review a client-market subset. Apply the existing Canada client-country example and inspect the exposed client facts. Client location differs from public applicant-country requirements, and a missing or restricted verification, spend or rating value does not satisfy a strict filter.
  • Join recurring exports in your own store. Keep jobId, publication time and collection time to avoid duplicate records across scheduled runs. Use Apify schedules and your own comparison or alert logic, allowing closed or restricted listings to change between observations.

Input settings

SettingJSON keyMeaning
Search queryqueryWords or Upwork search operators. Defaults to web scraping when neither query nor searchUrl is supplied.
Public Upwork search URLsearchUrlOptional https://www.upwork.com/nx/search/jobs/?q=... URL. Supports q and sort. Use dedicated inputs for filters. Leave query blank when using this field.
Maximum saved jobsmaxItemsStop after this many unique matching jobs. Public previews with restricted details count as jobs.
Jobs requested per pagepageSize1–50. Smaller pages can reduce unused search results in small runs.
Maximum search pagesmaxPagesBounds scanning when filters are narrow. Hitting this limit is reported as partial coverage.
Search ordersortNewest publication first or Upwork relevance.
Published on or afterpostedSinceISO date or timezone-qualified timestamp. Compared with the source publication time.
Job typejobTypeKeep fixed-price or hourly jobs.
Experience levelexperienceLevelKeep the requested source experience level.
Category name or slugcategoryMatch an exact public category or category-group name/slug, case-insensitively. Requires details.
Client countryclientCountryExact source country name, case-insensitive, such as Canada. This is the hiring client location, not the proxy or applicant location.
Explicitly remote jobs onlyremoteOnlyRequire the source to explicitly label REMOTE. Unspecified arrangements are excluded. Upwork often leaves this field unspecified. Requires details.
Verified-payment clients onlypaymentVerifiedOnlyRequire a public true payment-verification value. Missing/restricted values do not match.
Include public job and client detailsincludeDetailsDefault true. Retrieve full public description, category, client facts and activity. Account-restricted jobs retain their public preview with detailStatus=restricted.
Fail on incomplete extractionfailOnBlockedFail on source blocks, unexpected errors or scan limits, while preserving saved jobs. False permits an explicitly partial run: if Upwork refuses job details, found jobs are saved as search previews with detailStatus=unavailable (not with client-detail filters). Zero-row blocks always fail.
Request timeout in secondsrequestTimeoutSecsMaximum time for one public request, capped by the shared runtime deadline.
Total runtime budgetmaxRunSecondsIncludes a shutdown reserve of at least 30 seconds and 10 percent. Increase for many jobs or restrictive filters.
Maximum session attempts per operationmaxSessionAttemptsBounded retry count for guest bootstrap, network failures and HTTP blocks. Account restrictions are not retried.
Apify proxy configurationproxyConfigurationAutomatic selection tries up to two Apify datacenter sessions, then residential if needed within the session-attempt limit (US by default). Explicit proxy groups are respected. No external proxy credentials are accepted.
Minimum hourly ratehourlyRateMinLocal filter on the corresponding public source value. Unavailable values do not match.
Maximum hourly ratehourlyRateMaxLocal filter on the corresponding public source value. Unavailable values do not match.
Minimum fixed budgetfixedBudgetMinLocal filter on the corresponding public source value. Unavailable values do not match.
Maximum fixed budgetfixedBudgetMaxLocal filter on the corresponding public source value. Unavailable values do not match.
Minimum public client spendminClientSpendLocal filter on the corresponding public source value. Unavailable values do not match.
Minimum client ratingminClientRatingLocal filter on the corresponding public source value. Unavailable values do not match.
Maximum proposal countmaxProposalsLocal filter on the corresponding public source value. Unavailable values do not match.
Description/title must include allincludeKeywordsCase-insensitive text filters applied to the full public detail when available, otherwise to the public preview.
Description/title must exclude allexcludeKeywordsCase-insensitive text filters applied to the full public detail when available, otherwise to the public preview.

searchUrl accepts public job-search URLs containing q and sort. Other URL filters produce a clear validation error. Use the dedicated Actor inputs instead. If both URL and query are supplied, they must agree.

remoteOnly requires an explicit source REMOTE value. Many jobs leave their work arrangement unspecified. These do not match that strict filter. A client's country is different from applicant-location restrictions. Company size is the source's classification, not an inferred employee count.

Output data

This shortened example comes from an actual public job. Values change as Upwork updates the listing.

{
"jobId": "2094154303070879807",
"url": "https://www.upwork.com/jobs/~022094154303070879807",
"title": "Build a Car Listing Scraper with Instant TG Notifications",
"jobType": "FIXED",
"fixedBudget": 10.0,
"currency": "USD",
"client": {
"country": "United Kingdom",
"totalSpent": 24305.91,
"paymentVerified": true
},
"detailStatus": "complete"
}

Full records include the description, skill identifiers, public client summary, activity and source metadata. Download results from the run's Dataset tab. The OUTPUT key-value record reports status, saved/scanned counts, source restrictions and any reason the run stopped early.

FieldMeaning
jobIdStable source job ID
ciphertextSource public job ciphertext
urlCanonical Upwork job URL
titleSource title
descriptionFull public description when details are complete. Source search preview otherwise
jobTypeFIXED or HOURLY
queryRequested search expression
sourceUrlPublic search URL
scrapedAtUTC collection timestamp
detailStatuscomplete, restricted, unavailable (Upwork refused details; search preview saved) or not_requested
currencySource budget currency. Never inferred from viewer
experienceLevelNormalized source experience level
workloadSource workload
createdAtSource creation timestamp
postedAtSource publication timestamp
statusSource job status
detailSourcePublic detail source
workArrangementremote, on_site or unspecified, from onSiteType
fixedBudgetSource fixedBudget. Null when not applicable or unavailable
hourlyRateMinSource hourlyRateMin. Null when not applicable or unavailable
hourlyRateMaxSource hourlyRateMax. Null when not applicable or unavailable
weeklyRetainerBudgetSource weeklyRetainerBudget. Null when not applicable or unavailable
premiumSource premium flag
skillsSource skill identifiers and labels
warningswarnings
durationduration
categorycategory
categoryGroupcategoryGroup
clientPublic client summary. Omitted for restricted previews
activityactivity
qualificationsPublic applicant/location requirements, distinct from client country

The client object includes country, city, timezone, totalSpent, totalHires, activeHires, hoursBilled, reviewCount, rating, jobsWithHires, openJobs, memberSince, paymentVerified, companyIndustry and companySize. Individual values can be null when Upwork does not disclose them. Zero is kept as zero.

activity includes totalApplicants, totalHired, totalInvitedToInterview, unansweredInvites, invitationsSent, numberOfPositionsToHire and lastBuyerActivity. qualifications preserves public countries, regions, states, timezones, localMarket, onSiteType, prefEnglishSkill, risingTalent and locationCheckRequired. Empty location requirements must not be interpreted as the client's location.

Download your results

Open your run's dataset, choose Export and select JSON, CSV or Excel. JSON keeps nested fields together. CSV and Excel are useful when you want to review the records in a spreadsheet.

See Apify's download and export guide for the available formats and field options.

Pricing

The start event is charged once when the first matching job is ready to save. The item event is charged for each unique saved job. A useful public preview with restricted details counts as a saved job and is clearly marked. Error/status messages are written to the run summary and are not dataset jobs.

See the current pricing and discounts. No additional Upwork account or external data subscription is required.

Tips for best results

  • Keep public details on when needed. Turning them off intentionally exports search previews instead of full descriptions and client facts.
  • Begin with a small query and cap. Tight filters can scan many candidates before finding qualified rows.
  • Review detailStatus and warnings. Restricted previews are saved jobs, while source restrictions must remain visible.
  • Use IDs for repeat exports. Keep jobId and source timestamps in your own destination before producing comparisons.
  • Separate missing facts from measured zero. Source-null spend, ratings and rates must not be replaced with guesses.

Limits and caveats

  • Keep includeDetails enabled for public client fields and complete descriptions. Turning it off intentionally exports only search previews.
  • A genuine empty search can succeed with zero rows. A challenge, malformed response or failed bootstrap cannot.
  • Results reflect a changing marketplace. Closed, removed, private or restricted jobs may become unavailable between search and detail retrieval.
  • Tight filters can scan many jobs. maxPages and the runtime budget bound this work. Inspect the run summary for partial coverage.
  • With failOnBlocked=true, unexpected blocks or incomplete extraction fail the run while preserving jobs already saved. With failOnBlocked=false, jobs whose details Upwork refuses are saved as labeled search previews (detailStatus=unavailable) and OUTPUT reports unavailableDetails.
  • The maximum supported memory allocation is 1024 MiB. Existing lower-memory task settings are unchanged, but browser recovery headroom at 256 MiB has not been verified.
  • Public HTTP and browser-search JSON responses are limited to 8 MiB after decompression. Search pages may contain at most 50 jobs. Oversized responses stop extraction without retries, retain saved jobs and report RESPONSE_TOO_LARGE, not an empty-search success.
  • Source IDs control duplicates. Reuse job IDs in your own database when combining separate runs.
  • Apify proxies are required. Automatic selection starts with a datacenter session and can fall back to residential traffic. Explicit proxy groups are respected. Narrow filters may scan more jobs than they save.
  • If a run reaches its maximum total charge or time limit, it stops starting new work, keeps the jobs already saved and finishes successfully with a status message that says why. A time limit under about two minutes may not leave enough time to search.
  • Upwork's source fields can omit spend, location, rating or rates. This Actor does not fill them with guesses.
  • This Actor is independent of Upwork and does not automate applications or contact job posters.

Automation and integrations

Save your settings for next time

Once you have an input that works for you, save it as an Apify task. This keeps your settings together so you can use them again without filling in the form from scratch.

Run on a schedule

Need fresh results regularly? You can schedule the Actor or a saved task to run at a time that suits you.

Each scheduled run collects the data again. If you want to compare results or highlight changes, add that step in your own workflow.

Send results to your other tools

Use n8n, Make or Zapier to connect this scraper to the rest of your workflow. For example, you could pass its results to an AI assistant or add records to a spreadsheet. Follow the Apify integration guides for your chosen tool.

For a custom connection, an Apify webhook can notify your app when a run finishes or fails. Your app can then fetch the results or handle the failure.

API usage

Want to collect this data from your own app or automation? The examples below send input to the scraper and show how to collect its results.

The existing Node.js and Python examples wait for completion and read dataset results. This cURL example uses the synchronous result endpoint and returns dataset items. For longer searches, start an asynchronous run, wait for completion and read its dataset with pagination.

For setup instructions, see Apify's JavaScript client guide, Python client guide and Actor runs API reference.

cURL

$curl --request POST --header "Authorization: Bearer $APIFY_TOKEN" --header "Content-Type: application/json" --data '{"query":"python","maxItems":20,"includeDetails":true}' "https://api.apify.com/v2/acts/fetch_cat~upwork-jobs-scraper/run-sync-get-dataset-items"

Node.js

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('fetch_cat/upwork-jobs-scraper').call({
query: 'python', maxItems: 20, includeDetails: true
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Python

import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("fetch_cat/upwork-jobs-scraper").call(
run_input={"query": "python", "maxItems": 20, "includeDetails": True}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)

MCP and AI agents

You can ask your AI assistant to collect data with Upwork Jobs Scraper and help you work with the results. The scraper returns the data, and your assistant can then summarize it, compare records or prepare notes.

Connect your assistant through the Apify MCP server. MCP gives your assistant a way to find this scraper, run it and read the results. Follow the official setup and sign-in guide for your app.

Easier setup with an Apify plugin

If you use a supported coding assistant, the official Apify plugin can set up the connection for you. It connects your assistant to Apify and includes instructions for common tasks. Follow the guide for your particular app.

Use Apify AI in Console

Prefer to keep everything in Apify? Open Apify AI in Console and ask it to find Fetch Cat's Upwork Jobs Scraper. You can describe the data you want and ask questions about the results.

Apify AI is currently in beta. It asks for confirmation before starting an Actor, and normal run charges apply.

Choose your assistant

Connect just this scraper

To keep your setup focused on this scraper, add this server configuration to a compatible MCP client:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=fetch_cat/upwork-jobs-scraper"
}
}
}

Sign in to Apify when your client asks. If your client uses a Bearer token instead, follow its setup guide and keep the token in its secure configuration. Configuration formats vary by app, so use the linked guide if your client needs a different format.

Use Apify's general server

Already connected to the general Apify MCP server at https://mcp.apify.com? You can use it to find this scraper without adding another server. Ask your assistant to use Upwork Jobs Scraper by Fetch Cat, or give it the identifier fetch_cat/upwork-jobs-scraper.

Your assistant can check the available settings and retrieve the results from the returned run. If the run is still working, it should follow that run rather than start it again. Both connection options use Apify's hosted service.

Example requests

  • “Use Fetch Cat’s Upwork Jobs Scraper to collect up to 2 public web scraping jobs with public details enabled. Keep titles, links, available budgets and restricted-detail labels without applying or inventing client information.”
  • “Collect up to 5 public Python jobs from clients whose exposed country is Canada, with details enabled. Separate fixed and hourly budgets and preserve missing values without confusing client country with applicant restrictions.”
  • “Retrieve up to 5 public web scraping jobs with details off. Keep IDs, publication times and preview text, and explain which detail fields are unavailable rather than logging in or treating previews as complete briefs.”

Normal Apify charges apply. Check the live Pricing tab before asking your assistant to run a larger batch.

Pay with x402

If your AI agent has a funded wallet, it can pay for Apify usage through x402. This experimental option lets an agent use Apify without a conventional account.

Apify AGI provides a prepaid API token with a spending cap after payment. Your agent can use that token to run this scraper through the Apify API or an authenticated MCP connection.

Some MCP setups also support paying for each request directly. That is a different payment option, so check the official guide for its availability.

Follow the official guide for wallet setup, supported payment options and current terms. Apify handles the payments. Keep wallet keys and payment tokens in your agent's secure configuration.

Other ways for agents to pay

Apify also supports MPP for prepaid access through AGI and Skyfire for eligible Actors. If your agent already uses one of these, see the agentic payment guide to choose the right setup.

FAQ

What data can I export with upwork job scraper?

Export titles, job IDs, URLs, descriptions, skills, publication dates and available budgets. Full public details also include visible client facts and activity. Restricted details are flagged explicitly.

Can I run Upwork Jobs Scraper through an API, schedule, or MCP client?

Yes. Use the API examples or Apify MCP configuration above. Save an input as a task to schedule it, and deduplicate scheduled results using jobId.

How much does it cost to use Upwork Jobs Scraper?

A one-time search event applies when the first matching job is ready, plus one event per saved job. The Pricing tab shows the current rate for your plan. Account-restricted public previews count as saved jobs.

Does this need an Upwork login?

No. It uses public job data and will not ask for your Upwork cookies.

Why does a job have no client object?

Upwork may expose the search preview while requiring registration for details. Check detailStatus and warnings.

Are null spend and zero spend equivalent?

No. Null means the source did not disclose the value. Zero is a source value.

Why did a restrictive filter return fewer jobs?

Only observed matching values qualify. Missing or restricted values do not count as matches, and the scan has page/time limits.

Can I schedule it?

Use an Apify task and schedule after confirming the input. Use job IDs to avoid duplicates across scheduled runs.

Support and feedback

For custom additions or integrations, email hello@fetchcat.dev.

Found an error or have a feature request? Open an issue with the run URL, a non-sensitive input example and what you expected.

Need help sharing it? See Apify’s guide to sharing a run when reporting an issue. Sharing a run can give the developer access to its input, logs and results, so use a run that contains no sensitive data. Please leave out API tokens, passwords, cookies, private documents and personal data. Use a public sample URL or a redacted example instead.

Tried this scraper? We'd love to hear how it worked for you. Leave a review to help others choose the right tool and help us improve it. Your feedback means a lot to us.

Made with care for curious people, AI agents and the possibilities in data. ♥