Upwork Job Scraper (Pay Per Result) avatar

Upwork Job Scraper (Pay Per Result)

Pricing

from $6.50 / 1,000 jobs

Go to Apify Store
Upwork Job Scraper (Pay Per Result)

Upwork Job Scraper (Pay Per Result)

Scrape recent and relevant Upwork.com jobs, filter and only pay for what you need. Unauthed runs = no ban risk.

Pricing

from $6.50 / 1,000 jobs

Rating

0.0

(0)

Developer

Matthew James

Matthew James

Maintained by Community

Actor stats

4

Bookmarked

78

Total users

5

Monthly active users

a day ago

Last modified

Share

🔎 Upwork Job Scraper

Find Upwork jobs by keyword or search URL. Filter the results, download them, or send them to your workflow.

No Upwork login needed for basic results. Add your Upwork authorization header or cookies for available client information and Extra Details.

📦 What you get

🧾 Example output

Without authentication — 16 standard fields

Client information and proposal counts are null. There is no Extra Details field.

{
"Job ID": "1000000000000000001",
"Time Posted": "2026-09-04T14:18:13.670Z",
"Project Payment Type": "Hourly",
"Budget": "$8.0 - $12.0",
"Skill Level": "Intermediate",
"Title": "Example automation job",
"URL": "https://www.upwork.com/jobs/~example1",
"Description": "Build a Node.js integration with clear tests.",
"Location": null,
"Total Spent": null,
"Feedback": null,
"Proposals": null,
"Project Length": "1 to 3 months",
"Weekly Hours": "Less than 30 hrs/week",
"Skills": ["Node.js", "API Integration"],
"Date Scraped": "2026-09-12T12:00:00.000Z"
}

With authentication — client information and Extra Details

The same 16 fields stay in place. Available client values are filled in, and Extra Details is added automatically unless turned off. Some values may still be null.

{
"Job ID": "1000000000000000003",
"Time Posted": "2026-08-21T17:52:00.733Z",
"Project Payment Type": "Hourly",
"Budget": "$30.0 - $123.0",
"Skill Level": "Intermediate",
"Title": "Example automation job",
"URL": "https://www.upwork.com/jobs/~example3",
"Description": "Build a Node.js integration with clear tests.",
"Location": "United States",
"Total Spent": "$18,854.87",
"Feedback": 4.97,
"Proposals": 8,
"Project Length": "Less than 1 month",
"Weekly Hours": "Less than 30 hrs/week",
"Skills": ["Node.js", "API Integration"],
"Date Scraped": "2026-09-12T12:00:00.000Z",
"Extra Details": {
"Job": {
"Status": "Active",
"Start Date": null,
"Category": "Scripts & Utilities",
"Category Group": "Web, Mobile & Software Dev",
"Occupation": "Scripting & Automation",
"Additional Skills": [],
"Tools": ["Zapier"],
"Screening Questions": ["Describe a similar integration you have built."],
"Attachments": []
},
"Client": {
"City": "Austin",
"Timezone": "America/Chicago",
"Payment Verified": true,
"Enterprise": false,
"Company": null,
"Review Count": 12,
"Assignments": 15,
"Active Assignments": 2,
"Hours Billed": 250,
"Jobs Posted": 18,
"Open Jobs": 2,
"Jobs With Hires": 10,
"Average Hourly Rate": null,
"Work History": []
},
"Requirements": {
"Freelancer Type": "Independent",
"English Level": "Fluent",
"Languages": ["English"],
"Min Job Success Score": 90,
"Min Upwork Hours": 100,
"Portfolio Requested": false,
"Rising Talent Preferred": false,
"Countries": null,
"Regions": null,
"States": null,
"Timezones": null,
"Location Check Required": false,
"Location": null,
"On Site": null
},
"Activity": {
"Last Client Activity At": "2026-09-12T11:30:00.000Z",
"Hires": 0,
"Interview Invites": 2,
"Unanswered Invites": 1,
"Invites Sent": 3,
"Positions To Hire": 1
},
"Bid Stats": {
"Average": {
"Amount": 50,
"Currency": "USD"
},
"Lowest": {
"Amount": 30,
"Currency": "USD"
},
"Highest": {
"Amount": 100,
"Currency": "USD"
}
}
}
}

Each job is one row with these 16 standard fields:

GroupOutput fields
JobJob ID, Title, URL, Description, Skills
Pay and experienceProject Payment Type, Budget, Skill Level
ScheduleProject Length, Weekly Hours, Time Posted, Date Scraped
Client and activityLocation, Total Spent, Feedback, Proposals

Location means the client's country, not where applicants must live. Without authentication, client and proposal values are unavailable. The standard fields remain present.

With valid authentication, Extra Details is added to the same row:

GroupExamples of available details
JobCategory, screening questions, attachment links
ClientPayment status, work history, jobs posted
RequirementsLanguages, location rules, experience requirements
ActivityHires, invitations, recent client activity
Bid StatsAverage, lowest, and highest bids

Details vary by job. null means unavailable; [] means an empty list. Matching details already shown in standard fields are not repeated.

To turn off Extra Details, add "enrichDetails": false in the JSON input editor. Remove that setting to enable automatic details with authentication.

Download JSON, CSV, or Excel. Use JSON to keep the full Extra Details structure.

🎯 Choose your filters

FilterWhat it does
Job type, budget, experience, and workloadNarrow the jobs you want.
Sort OrderAsk Upwork for most recent or most relevant results. The Actor does not sort results afterward.
Maximum Job Age (hours)Use 24 for one day or 0.5 for 30 minutes. 0 turns this filter off.
Include / Exclude KeywordsKeep or skip jobs based on their text.
Client CountriesSelect countries to include or exclude. If both lists contain a country, exclusion wins.
Client payment, spending, rating, and reviewsKeep jobs from clients that meet your limits. Authentication is needed for these fields.
Maximum ProposalsKeep jobs at or below this count. 0 means no proposals; leave empty for no limit.

Missing data does not pass a filter. Selecting Canada excludes jobs with no client country. Maximum Proposals excludes jobs without an exact count.

The country list contains locations seen in Upwork results, so it may not include every country. The job-age cutoff stays fixed from run start through retries and restarts. Jobs without a posting time cannot pass that filter.

📝 Input guidance

  • Use Residential proxies for better reliability. They are selected by default.
  • For client information and Extra Details, add a current Upwork authorization header or cookies. The authorization header is recommended.
  • A Custom Search URL overrides Search Query and the matching search controls. Freshness, keyword, and client filters still apply to the results.
  • If you use cookies, export the full set from a signed-in Upwork browser session as a JSON array. Keep both cookies and authorization headers secret.
  • If both are supplied, the authorization header takes priority. A token rejected during search stops the run; the Actor does not switch to cookies.
  • Without a header, incomplete or rejected cookies can fall back to basic results with a warning. Malformed inputs must be fixed before the run can start.
  • Without valid authentication, you may get fewer jobs and pages. Filters that need client data or exact proposal counts exclude jobs when those values are missing.
  • Unavailable values are null. Valid authentication does not guarantee that every field is available.

🔐 Add your Upwork login details

  1. Sign in to Upwork and open your browser's developer tools.
  2. Select Network, then reload the page or open a job.
  3. Open an Upwork request and find authorization under Request Headers.
  4. Copy its value into Authorization Header (recommended). The Bearer prefix is optional.

Use your Upwork token, not an Apify API token or a cookie value.

🍪 Cookies (alternative)

Export the full cookies from your signed-in Upwork session as a JSON array. Paste the array into Cookies (alternative).

Both inputs are encrypted. Keep them private and replace them when they expire. Renewal is not automatic.

If you supply both, the authorization header takes priority. Rejected cookies can fall back to basic results. A token rejected during search stops the run.

⏱️ Results and run limits

  • Pages to Scrape: Up to 100 pages, with 50 jobs requested per page. Fewer than 50 returned jobs ends the search. This count is checked before filters.
  • Maximum Matching Results: Limits jobs saved after filtering and removing duplicates. Strict filters may scan many pages without saving any jobs.
  • Run time: New requests stop after one hour, including retries and restarts. Current requests and saves may finish afterward.
  • Spending limits: Apify's remaining result allowance also limits saved jobs and optional details.

Page size is fixed. Old page-size inputs and page-size values in custom URLs are ignored. Restarting a run does not reset its detail-request limit.

For the pay-per-result version, each saved job counts as one result. Extra Details adds no separate result. Filtering jobs later in your workflow does not reduce the number of delivered results.

🔗 Automate your workflow

Use Apify schedules for regular searches. Set a job-age limit to focus on fresh jobs. Keep your Upwork credentials current.

To use n8n or Make:

  1. Connect Apify using your Apify API token, not your Upwork token.
  2. Run this Actor and wait for success.
  3. Use Get Dataset Items with the dataset ID from that run.
  4. Filter Extra Details if needed, then save jobs or send alerts.

For example, to keep jobs with no hires, require Extra Details → Activity → Hires to equal 0. A missing value is not zero.

Already using a schedule? Add a Run succeeded webhook in the Actor's Integrations tab. The webhook sends run information, not jobs. Fetch results using resource.defaultDatasetId; do not start another scrape. See the webhook guide.

Save handled Job ID values to avoid duplicate alerts across runs. Ignore repeated webhook run IDs, skip empty datasets, and handle failed runs separately.

💡 Troubleshooting

ProblemWhat to check
No resultsCheck the run status. For a successful run, try fewer filters. A failed run does not prove there were no matches.
Missing client dataReplace expired Upwork credentials. Some values may be missing even with valid access. Basic access can return fewer jobs and pages.
Missing Extra DetailsCheck credentials and the enrichDetails setting. If details fail or reach their limit, selected jobs are still saved with unavailable details.
Run stopped earlyCheck its status and saved results. Failed runs can contain useful partial results.
Duplicate jobs across runsEach job appears once per run, but can appear again in a later run. Match by Job ID when combining results.
No alert after a successful runCheck your workflow and webhook delivery. A successful scrape does not guarantee an alert was sent.