Job boards & ATS · Live on Apify

Upwork Jobs Scraper: Pay, Clients and Job Alerts

Get public Upwork job posts without an account or cookies. Use a search phrase, a search link, a job link or a job ID. Each row has pay, skills, applicants and public client data.

About $0.90 for 1,000 results$0.0009 per result + $0.001 per run. Apify bills you, not us.Free to try: the Apify free plan gives you $5 of usage every month, no credit card needed.

Run it on Apify Opens apify.com, the website where our tools run. Sign up free with Google or email, no card needed.

Apify links on this page are affiliate links. We may earn a commission. You pay the same price. Affiliate disclosure

What you get, for example

jobId2117702916010329632
titleSocial Media automated data collection (API) and Website Data…
jobTypehourly

How to use it: 3 steps

  1. Make a free Apify accountApify is the cloud platform where our tools run. The free plan gives you $5 of usage every month, no credit card needed. You pay Apify, not us.
  2. Paste your input and press StartNo code needed: you fill in a form (the input). It already has a working example. For example: web scraping in Search phrases. Each start is one run.
  3. Download the resultsWhen the run ends, the results are in a table (the dataset). Open Output, press Export and pick Excel or CSV. JSON and the API are there too.

This tool is an Apify Actor: a small program that runs on Apify. You can also run it on a schedule, for example every Monday. New to it? Read how it works, step by step and the 8 words you need first.

What it does

Use this Upwork jobs scraper to get public Upwork job posts by search phrase, search link, job link or job ID. Find clients, track freelance demand or get new job alerts. Each row has pay, skills, applicants and public client data such as country, spend and rating. No Upwork account or cookies needed.

Good for

  • Find new clients and leads for a freelance team or agency.
  • Track demand, pay and skills in a job category.
  • Get an alert when a new job matches your search.
  • Feed job rows to a sheet, database, Slack, Notion or an AI agent.

Who uses it

Freelancers

Get an alert when a new job matches your search.

Agencies

Find new clients and leads.

Market analysts

Track demand, pay and skills in a job category.

Price

Pay per event: you pay for each result the tool saves, plus a small start fee for each run. The price includes Apify platform costs. Apify bills you, not us. Prices below are for the Apify free plan.

What you pay forPriceWhen
Start fee$0.001Charged once per run. This tool uses 1 GB of memory or less by default; more memory costs more.
Source request$0.0001One public source request started, including empty results and jobs that do not match filters. Redirects and retries are included.
Saved job$0.0009 (from $0.00063 on paid Apify plans)One job saved in the dataset.

Examples

  • One result: about $0.0019.
  • 1,000 results: about $0.90.
  • Every day 100 results, for 30 days: about $2.73 a month.

Free to try: the Apify free plan gives you $5 of usage every month, no credit card needed. That is enough for about 5,500 results.

Prices checked on 8 November 2026. See the current price on Apify.

Questions

Do I need an Upwork account or cookies?

No. The Actor reads only what Upwork shows to visitors. Do not give it your login.

Why is clientRating null?

The client has no public reviews yet. Null means unknown or hidden. It is not the same as 0.

Can this Actor apply for jobs or contact clients?

No. It only reads public job posts.

Can I scrape Upwork jobs by a search link?

Yes. Run your search on Upwork, copy the link and paste it in startUrls. Filters in the link are used.

How do I get only new jobs?

Set onlyNew: true and run the Actor on an Apify Schedule. The first run saves all matches up to maxItems as a starting point. Later runs save only jobs not saved before.

Why do I pay for source requests when no job is saved?

The Actor must read the source to find out if a job matches. So each source request is charged, even if your filters remove all jobs. Make filters part of the search when you can, for example jobType or experienceLevel.

How fresh is the data?

Each row is read during the run, and fetchedAt shows the time. Rows are not updated later. Run again or use a schedule for fresh data.

Is this an official Upwork product?

No. This Actor is not affiliated with or endorsed by Upwork.

Details

Step by step on Apify
  1. Open the Input tab. Keep web scraping in Search phrases, or type your own phrase (box 1).
  2. Keep 10 in Maximum results for a first test (box 2). Filters are optional, see Input.
  3. Click Start.
  4. When the run ends, open the Output tab. Each row is one job (box 4). Check the job title, budget, client spend and applicants.
Use cases
TaskInputYou getKey fieldsNext step
Find clients who pay wellqueries, minClientTotalSpent, paymentVerified: trueOne job per rowtitle, clientCountry, clientTotalSpent, clientRating, urlCRM or a sheet
Get new job alertsqueries, onlyNew: true, Apify ScheduleOnly jobs not saved beforetitle, budget, hourlyRange, postedAt, urlSlack or Notion with deliveryConnector
Track market demand and payqueries or categories, maxItems: 1000One job per rowskills, hourlyBudgetMin, hourlyBudgetMax, budget, categorySheet or BI tool
Copy a search you made on UpworkstartUrls with an Upwork search linkOne job per rowtitle, jobType, experienceLevel, postedAt, urlDataset API
Check known jobsjobIds or job links in startUrlsOne row per public jobjobStatus, totalApplicants, hired, clientLastActivity, detailsStatusYour own job tracker
Tips for better results
  • Keep 10 in Maximum results for a first test.
  • Paste a search link from Upwork in startUrls. The filters in the link are used.
  • Set onlyNew to true and use an Apify Schedule to get only new jobs.
Limits and good to know
  • Only public data. There is no login, so private and invite-only jobs are not available
  • Some jobs show details only to members. In our 6,000-job test, 1,055 jobs had no public details. These rows keep the search fields and have detailsStatus: "members_only"
  • clientAvgHourlyRate and clientHireRatePercent are hidden from visitors, so they stay null
  • The largest tested run saved 6,000 jobs in about 20 minutes. The default timeout is 300 seconds. Raise it for runs over about 1,000 jobs
  • A big search is split by category, type and experience level to get past the source limit of about 5,000 results per search. So a big result has no single global order
  • If the source still holds back part of a search, the summary says SOURCE_CAP and sourceCapPartitions counts the affected parts
  • skipReposts skips only exact repeats of the cleaned title and description. Reworded reposts are saved
  • A monitor history keeps up to 100,000 jobs. Closed and then the oldest jobs are dropped first

For developers

Sample result

One result from a real test run, in JSON. Real values change from run to run. In Excel or CSV each field is a column.

one result · JSON
{
  "jobId": "2117702916010329632",
  "title": "Social Media automated data collection (API) and Website Data Collection",
  "jobType": "hourly",
  "hourlyRange": {
    "min": 6,
    "max": 25
  },
  "budget": null,
  "experienceLevel": "intermediate",
  "skills": [
    "Data Scraping",
    "Web Scraping",
    "API Integration",
    "Social Media Marketing"
  ],
  "duration": "1 to 3 months",
  "postedAt": "2026-11-03T19:38:23.701Z",
  "clientCountry": "United States",
  "clientPaymentVerified": true,
  "clientTotalSpent": 599.1,
  "clientSpentCurrency": "USD",
  "clientRating": 5,
  "clientReviewCount": 2,
  "clientTotalHires": 5,
  "totalApplicants": 37,
  "jobStatus": "open",
  "detailsStatus": "available",
  "url": "https://www.upwork.com/jobs/~022117702916010329632",
  "fetchedAt": "2026-11-04T12:08:00.362Z"
}

Use it from code

Actor ID: cliqtomedia/upwork-jobs-scraper. You need your Apify API token from Apify Console → Settings → API & Integrations.

Python · apify-client
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("cliqtomedia/upwork-jobs-scraper").call(run_input={
    "queries": [
        "web scraping"
    ],
    "maxItems": 10
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
cURL
curl -X POST "https://api.apify.com/v2/acts/cliqtomedia~upwork-jobs-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"queries": ["web scraping"], "maxItems": 10}'
LangChain · langchain-apify
# pip install langchain-apify
# set APIFY_TOKEN in your environment
from langchain_apify import ApifyActorsTool

tool = ApifyActorsTool("cliqtomedia/upwork-jobs-scraper")
result = tool.invoke({"run_input": {"queries": ["web scraping"], "maxItems": 10}})
print(result)

The cURL call waits for the results, up to 300 seconds. For longer runs, start a run (/runs) and get the results with a webhook or by checking the run. Apify API docs. LlamaIndex, MCP for AI agents and the JavaScript client: AI agents & MCP.

Data fields (40)
FieldTypeMeaning
jobIdstringUpwork job ID.
idstringThe same ID as jobId, for imports.
ciphertextstringUpwork ID used in the job link.
titlestringJob title, with contact details removed.
descriptionstringFull public job text, with email addresses and phone-like numbers removed.
budgetnumberFixed-price budget. Null for hourly jobs or an undisclosed budget.
budgetCurrencystringCurrency code of the fixed budget.
hourlyRangeobjectKnown minimum and maximum hourly rates. Null limits mean undisclosed.
hourlyBudgetMinnumberKnown minimum hourly rate.
hourlyBudgetMaxnumberKnown maximum hourly rate.
weeklyRetainerBudgetnumberWeekly retainer budget, when public.
jobTypestringhourly, fixed or weekly_retainer.
experienceLevelstringentry, intermediate or expert.
skillsarrayPublic skill names.
skillIdsarrayPublic skill IDs.
durationstringProject duration label.
durationWeeksnumberProject duration in weeks.
workloadstringWeekly work requirement.
postedAtstringPublication time reported by Upwork.
absoluteDatestringThe same publication time as postedAt.
createdAtstringTime the job was created.
renewedAtstringSource renewal or sourcing time, if given.
clientCountrystringClient country name. Source country codes are converted to country names. Null when hidden.
clientCountryCodestringTwo-letter ISO country code from the public client country name. Null when the name cannot be matched.
clientCitystringPublic client city, when visible.
clientTimezonestringPublic client timezone label.
clientPaymentVerifiedbooleanWhether the public page shows a verified payment method.
paymentVerifiedbooleanThe same value as clientPaymentVerified.
clientTotalSpentnumberPublic lifetime client spend. A hidden amount stays null.
clientSpentCurrencystringCurrency of the public client spend.
clientRatingnumberPublic client rating. Null when the client has no reviews.
clientReviewCountnumberPublic review count.
clientTotalHiresnumberPublic total client assignments.
clientActiveHiresnumberPublic active assignments.
clientTotalHoursnumberPublic hours billed.
clientMemberSincestringPublic client account creation date.
clientIndustrystringPublic client industry. Null when empty.
clientCompanySizenumberCompany size group reported by Upwork. The group code is not a staff count.
clientHireRatePercentnumberNull when this value is hidden from visitors.
clientAvgHourlyRatenumberNull when this value is hidden from visitors.
Input settings (25)

The main fields of the input form. With the API you send them as JSON.

SettingName in the APITypeExample value
Search phrasesqueriesarray["web scraping"]
Search or job URLsstartUrlsarray
Job IDsjobIdsarray
Maximum resultsmaxItemsinteger10
Read public job detailsincludeDetailsbooleantrue
Run modemodestring"search"
Payment typesjobTypearray
Experience levelsexperienceLevelarray
Categoriescategoriesarray
Minimum fixed budgetminBudgetnumber
Maximum fixed budgetmaxBudgetnumber
Minimum hourly rateminHourlyRatenumber
Maximum hourly ratemaxHourlyRatenumber
Weekly workloadworkloadarray
Project durationdurationarray
Contract-to-hire onlycontractToHirebooleanfalse
Required wordsincludeKeywordsarray
Excluded wordsexcludeKeywordsarray
Required skillsrequiredSkillsarray
Words in titletitleContainsstring
Maximum job age in minutesmaxAgeMinutesnumber
Job agemaxJobAgeobject
Published fromfromDatestring
Published throughtoDatestring
Proposal rangesproposalsarray

Start on Apify

Make a free Apify account: you get $5 of free usage every month. Missing a tool? Suggest it. We read every idea, but we do not promise to build it.

Apify links on this page are affiliate links. We may earn a commission. You pay the same price. Affiliate disclosure