Upwork Jobs Scraper: Public Jobs & New Job Alerts avatar

Upwork Jobs Scraper: Public Jobs & New Job Alerts

Pricing

from $1.00 / 1,000 jobs

Go to Apify Store
Upwork Jobs Scraper: Public Jobs & New Job Alerts

Upwork Jobs Scraper: Public Jobs & New Job Alerts

Collect signed-out Upwork job listings, budgets, skills and available client details. Filter public jobs and track newly seen job IDs between runs. Access checks and unavailable pages produce free notes.

Pricing

from $1.00 / 1,000 jobs

Rating

0.0

(0)

Developer

Zaiq

Zaiq

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

Upwork Jobs Scraper: public jobs, client details and new-job alerts

Get public job titles, descriptions, budgets, hourly ranges, skills and dates from keyword searches, category pages or individual job links. Load the public job page for available client country, payment verification, hires, rating and proposal activity. Every row starts with a plain result verdict.

$0.001 per basic job and $0.003 per job with client details, the same price on every Apify plan and on every connection route. A row uses one of these prices, never both. Failed pages and access notes are free. The default input requests ten detailed jobs.

Use a snapshot key with newOnly for scheduled collection of newly seen job IDs. The Actor remembers jobs it actually delivered, so a spending limit does not hide jobs that were never delivered. It does not submit proposals or send alerts itself.

What you get

FieldWhat it holds
Jobverdict, jobId, jobUid, title, url, posted, createdOn, renewedOn, description, skills
Budget and scopejobType, budget, hourlyMin, hourlyMax, currency, duration, experienceLevel; detailed rows also include category and category group
Client detailsclientCountry, paymentVerified, clientHires, clientActiveHires, clientRating, clientReviewCount, clientMemberSince, clientJobsPosted, clientLastActive, clientTotalSpent when exposed
Proposal activityproposalsBand, proposalsCount, jobHires, interviewing, invitationsSent, unansweredInvites when exposed on a public job page
Delivery and pricingchange, scrapedAt, sourceUrl, inputSource, detailsStatus, pricingEvent, usedResidential, notes, and the restart-safe resultId
Run summarySource totals, pages read, filtering, skipped malformed records, request bytes, route escalations, spending-limit status and snapshot coverage

What people use it for

  • New-job feeds: Run the same saved search on a schedule and consume new job rows through a webhook or dataset export.
  • Freelance prospecting: Find public jobs within a stated budget, hourly range and experience level.
  • Client screening: Use public verification, hiring history, ratings and proposal activity to prioritize jobs. Missing fields stay unknown.
  • Market research: Compare job requirements and budgets across public searches and categories, within the reported collection limits.

How to use it

  1. Enter a phrase in Search keywords. The prefill uses data analysis and requests ten jobs.
  2. Keep Load client details on for public client information, or turn it off for basic job rows.
  3. Choose job, budget, experience or client filters and set your Maximum cost per run.
  4. For repeat collection, set a Snapshot key, enable Only newly seen jobs, and reuse the same sources and filters. Start the run and open the Jobs table and SUMMARY.

Input

FieldExampleNotes
queries["data analysis"]Up to 40 sources combined. Empty source arrays use the default search.
categories["data-entry"]Public category slugs or links. The first page has the category’s own ordering; continuation follows its public search mapping.
jobUrls[]Public job links. Always charged at the detail rate when successful.
includeDetailstrueRead client and proposal fields. A failed detail request gives a free note, without charging a partial job.
maxJobs / maxPagesPerSource10 / 3Unique delivered jobs across all inputs, and pages per source. Maximums: 1,000 jobs and 20 pages per source.
pageSize5010, 20 or 50. Small maxJobs values use a consistent 10- or 20-item page to avoid fetching excess data.
sort / keywordMatchnewest / all-wordsEvery query word must appear in the title, description or skills by default. Phrase requires the whole phrase; source accepts the site’s own matching and suggestions.
jobType / experienceLevelfixed / intermediateHourly or fixed; entry, intermediate or expert. Use all for either filter to be unrestricted.
minBudget / maxBudget100 / 1000Stated fixed-price USD budget. Missing budgets and hourly jobs fail an active fixed-budget filter.
minHourlyRate / maxHourlyRate20 / 75Require the advertised lower rate to meet the minimum and the upper rate to fit the maximum. Unknown rates are excluded.
paymentVerified / clientHistoryverified / 10-plus-hiresApplied to public detail-page data. These require includeDetails=true. Unknown values are excluded.
minClientSpentOmittedOnly jobs with exposed total spending can pass. This field was hidden on the tested public job pages. Leave this filter unset unless your sources expose it.
snapshotKey / newOnlydaily-data-jobs / trueKeep a stable key for the same sources and filters. First run emits the baseline; later runs emit previously undelivered IDs.

Output

Each result is one row in the run's dataset (download it as JSON, CSV, Excel, XML or HTML, or read it through the API). An example row (values shortened):

{
"verdict": "Hourly $38–$48; intermediate; payment unverified; 5 to 10 proposals.",
"kind": "job",
"jobId": "~022114394737268013176",
"title": "Customer Satisfaction Feedback Analysis",
"posted": "2026-10-25T16:42:14.702Z",
"jobType": "hourly",
"budget": null,
"hourlyMin": 38,
"hourlyMax": 48,
"currency": "USD",
"duration": "1 to 3 months",
"experienceLevel": "intermediate",
"proposalsBand": "5 to 10",
"proposalsCount": 6,
"clientCountry": "India",
"paymentVerified": false,
"clientTotalSpent": null,
"clientHires": null,
"clientRating": null,
"detailsStatus": "available",
"url": "https://example.com/jobs/customer-feedback-analysis",
"notes": [
"clientTotalSpent was not exposed by the public job page.",
"clientHires was not exposed by the public job page.",
"clientRating was not exposed by the public job page."
],
"pricingEvent": "job-details",
"usedResidential": false
}

The example is an excerpt of a real run on 25 October 2026. Site addresses are replaced with example addresses; names and handles, where present, are removed or replaced. Numeric values and missing values are retained. The job description and named software skills are omitted from the example. The SUMMARY record lists coverage, failures, filtering, route usage and charges.

Pricing

  • Basic job: $0.001 ($1 per 1,000).
  • Job with client details: $0.003 (detail page included).
  • The same price on every Apify plan. Each delivered job has exactly one pricing event. There is no separate charge for loading the detail page.
  • Apify’s $0.00005 start charge counts towards the buyer’s Maximum cost per run. It is separate from the job events and may apply even when no jobs are returned.
  • Failures, login walls, access checks, filtered jobs, already-seen snapshot IDs and free notes have no job-event charge.
  • No AI model is used. Snapshot state is stored in a named key-value store; long-term storage follows Apify’s storage pricing.

What typical jobs cost at the list price:

JobCost
10 basic jobs$0.01005 including the start charge
10 jobs with client details$0.03005 including the start charge
1,000 basic jobs$1.00005 including the start charge
A search with no matching jobs$0.00005 (the start charge)

On Apify's Scale and Business plans the per-event prices are lower (Store discounts). Set Maximum cost per run and the Actor stops cleanly when it is reached: you never pay more than that.

Tips

  • Keep the default all-words keyword check when unrelated suggestions are unwanted. Use source matching when you deliberately want the site’s broader results.
  • Use basic rows for broad monitoring, and submit selected job links for client details.
  • Client filters can require reading several job pages before one matches. Set page limits and inspect filtered counts in SUMMARY.
  • Use a separate snapshot key for each schedule, and avoid overlapping runs that write the same key. Downstream systems can deduplicate on jobId or resultId.
  • An unchanged snapshot run still checks the requested public pages. It does not charge for job IDs it has already delivered.

Use it through the API

Python

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("zaiq/upwork-jobs-scraper").call(run_input={"queries": ["data analysis"], "maxJobs": 10, "includeDetails": true})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
print(row)

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('zaiq/upwork-jobs-scraper').call({"queries": ["data analysis"], "maxJobs": 10, "includeDetails": true});
const { items } = await client.dataset(run.defaultDatasetId).listItems();

HTTP (one call, results back)

curl -X POST 'https://api.apify.com/v2/acts/zaiq~upwork-jobs-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>' \
-H 'Content-Type: application/json' \
-d '{"queries": ["data analysis"], "maxJobs": 10, "includeDetails": true}'

Integrations and schedules

  • Schedules: run it every hour, day or week from the Apify Console (Schedules) and keep a history of results.
  • Make, Zapier, n8n, Google Sheets, Slack, Airtable: connect it through Apify's integrations, or send each finished run to a webhook.
  • Datasets: results stay in the run's dataset; export them or read them by API whenever you need them.

Use it with AI agents (MCP)

Add Apify's MCP server (https://mcp.apify.com) to Claude, ChatGPT, Cursor, VS Code or any MCP client. The agent can find this Actor and run it for you: ask it for "find new data analysis jobs with a stated budget and public client history". AI agents can also pay for runs directly through Apify's agentic payments.

Limits

  • Only public, signed-out pages are read. Login and verification redirects are not followed. No CAPTCHA or access check is solved. A refused route can be retried through datacenter and fresh residential connections.
  • Search pages hide much of the client record and can set verification=false as a placeholder. Basic rows report such values as null. Job pages may also omit total spending, hires, ratings or other client fields. A missing value is never inferred to be zero or false.
  • Client country is the source’s value and can be a country name or a three-letter country code. Job and client activity can change after collection.
  • Category ?page=2 links can repeat the first page. The Actor uses the category’s public search mapping when present and reports when continuation is unavailable.
  • Public searches can return broader suggestions. Local keyword and numeric filters remove nonmatching rows. Unknown fields fail active filters.
  • At most 150 HTTP requests and a 14-minute work budget checked between requests, with sequential requests and rate-limit backoff. Limits, short responses, repeated pages and malformed records make coverage incomplete in SUMMARY.
  • New-only mode tracks delivered IDs within the fetched pages. It is not a guarantee of seeing every new job. Missing jobs are never labelled removed. Snapshot history is capped at 100,000 IDs; use a new key when it fills.
  • Jobs and failure notes share the dataset. Filter kind=job for paid job rows. A successful Actor run can contain partial results or only free notes; read SUMMARY before treating coverage as complete.

FAQ

Do I need an account on the source site?

No. The Actor reads only signed-out public pages.

What happens when a job disappears?

An unavailable page produces a free note. The Actor does not guess whether it was removed, expired, made private or restricted.

Why is client spending missing?

The public pages tested did not expose it. The field stays null. Requiring a minimum spending amount excludes jobs where that value is hidden.

Why does the price change on some rows?

Some source addresses are refused; the Actor retries through datacenter and fresh residential connections at no extra charge. usedResidential shows which rows needed it.

Will I pay twice after a restart?

Rows with an acknowledged stable resultId are skipped on restart and are not charged again. Snapshot delivery state is reconciled from those rows.

Can I change filters and reuse a snapshot key?

Use a new key for different sources, matching rules, sorting or filters. The Actor stops with a free note if a key belongs to a different scope. You can change delivery and page limits.

Does this send alerts or apply to jobs?

It produces datasets suitable for scheduled workflows. Connect a webhook or your own automation for alerts. It never applies to jobs or contacts anyone.

Can I use it without code?

Yes. Fill in the input form and export the Jobs table as JSON, CSV or Excel.

Support

Questions, a site that changed, or a field you need? Open an issue on this Actor's Issues tab: we answer there, usually within a day.


Also found as: upwork jobs scraper, upwork job search, public freelance jobs, freelance job alerts, upwork client details, job budget data.