moxlade/guides/find upwork freelancers by rate, JSS and country

How to find Upwork freelancers by hourly rate, Job Success Score, country and track record — with the numbers you choose, not fixed bands

Upwork's talent search filters by fixed bands — a rate step, a Job Success floor, an earned-amount step, a badge, a location — in one order, and shows what a card shows. Our actor takes the numbers you choose (rateMin: 47, jssMin: 93, hoursMin: 1000), adds hire-again rate, member-since, last-worked date, job counts and skills as filters, and sorts by any of them — because it searches a census of 30,042 profiles where those are columns. Here is how to use each filter, and what it reads.

published 2026-09-13 · updated 2026-09-13

By hourly rate

rateMin and rateMax, in USD per hour, as numbers. The listed rate is on every stored row. Measured on the release runs: 25 of 25 rows inside the band, every time. Sort by rate to read the distribution.

{"query": "python developer", "rateMin": 50, "rateMax": 100, "sort": "rate", "maxItems": 100}

Why this matters: the one run-time scraper in the lane with numeric rate fields returned zero rows whenever they were filled (measured); the others offer a fixed enum or nothing.

By Job Success Score

jssMin, a percentage. JSS is on 90.3% of stored rows as the profile's score (not a 0..1 fraction, not a flag); jss_hidden says when a profile shows none. A client's usual bar is 90 or 95; pair it with hoursMin so a 100% on two jobs does not outrank a 97% on two thousand hours.

{"jssMin": 95, "hoursMin": 1000, "lastWorkedWithinDays": 60, "sort": "jss", "maxItems": 50}

That exact input is a saved example: Active and proven: JSS 95+, 1,000+ hours, worked recently.

By country and region

countries takes country names as Upwork shows them (United States, United Kingdom, Germany …), any of them. regions takes Upwork's five regions. country, state, city and timezone are columns, so a sheet can pivot on them afterwards. 153 countries are in the census today.

By badge

topRated (includes Plus), topRatedPlus, risingTalent. Each row also carries badge as one field. The badge is read from Upwork's own search cards, so it is the one Upwork shows — one run-time scraper in the lane reported "Top Rated Plus" on 32 of 33 rows including people who have no badge; we measured that too.

By track record

  • hoursMin — hours billed on hourly contracts.
  • jobsMin — total jobs; jobs_hourly and jobs_fixed are separate columns.
  • earnedMin — lifetime earnings in USD; matches the exact figure or the band's lower bound, whichever the profile exposes.
  • hireAgainMin — the share of clients who would hire again, a percentage.
  • memberSinceAfter / memberSinceBefore — tenure, as dates.
  • lastWorkedWithinDays — active recently; reads the last contract's end date.
  • hasContracts, idVerified, availability (Upwork's availability states), excludeAgencies.
{"query": "react", "memberSinceAfter": "2022-01-01", "hireAgainMin": 90, "earnedMin": 10000, "sort": "earnings", "maxItems": 100}

By skills and keywords

query matches the title, overview and skills as text. skills is a list, any-of, against the profile's skill names as Upwork displays them (not slugs). Combine both: a query for the role, skills for the must-haves.

Putting it together

Filters combine with AND; list filters are any-of within the list. A shortlist for a Top Rated US Python developer in a $50–100 band, proven and active:

{"query": "python developer", "topRated": true, "countries": ["United States"],
 "rateMin": 50, "rateMax": 100, "jssMin": 90, "hoursMin": 500, "lastWorkedWithinDays": 90,
 "sort": "jss", "maxItems": 100}

Ready-made: Top Rated US Python developers at $50–100/h. Export the result as CSV or JSON from the run (how). In code, every flag above is an argument of search_freelancers.py in getmoxlade/upwork-freelancers-examples (Python, JavaScript and curl).

When you want Upwork's own order

A stored search sorts by our columns. liveSearch: true with a query asks Upwork for its current result for that query, with the badge, country, region, rate, JSS and earnings filters applied on Upwork's side, and returns it in Upwork's order as source: live — 25 rows in under 30 s on the release runs, at $5 per 1,000. Ready-made: Live search in Upwork's own order.

use it

Set the numbers a client cares about and get the list in seconds.

moxlade/upwork-freelancers on Apify
$4.00 per 1,000 stored rows · $5.00 per 1,000 live search rows · $20.00 per 1,000 full profiles · no start fee, a zero-row run is free

Questions

Can Upwork's own search filter by Job Success Score?
As a fixed floor, yes. Ours takes any threshold as a number, combines it with hours, jobs, hire-again rate, tenure and recency, and sorts by it — JSS is a column in the census, on 90% of stored rows.
Are the rates current?
The rate on a stored row is the listed rate when the profile was last read; every row carries fetched_at and age_days, and a stored search leaves out rows older than 30 days unless you ask for them. liveSearch reads Upwork now.
How do I find freelancers who worked recently?
lastWorkedWithinDays, e.g. 60. It reads the end date of the most recent contract, which is on every profiled row as last_worked_on.
Can I search by skills only, without a keyword?
Yes: leave query empty and set skills and any other filters. A run needs at least one filter, a query or a list of profile URLs.