ActorStack.dev

How to scrape Workana project listings and read freelance demand

A walkthrough of extracting LATAM freelance demand: the five filters that work, the coverage ceiling nobody can exceed, and why the language setting changes what a budget means.

By Oswaldo Carabano9 min read

Short answer

Workana can be scraped without a login, and the two things that decide whether the data is usable are which filters you use and how you handle budgets. Only five of Workana's URL parameters actually filter — category, subcategory, skill, country and free-text search — and budgets have to be read with `budget_type` and `locale`, because a quarter of them have no lower bound and the thousands separator changes with the language.

Key points

  • No login, no cookies, no proxy. Concurrency 3 is the measured default: at 5 Workana returns 5% HTTP 503.
  • Only five filters work. Thirteen more are accepted with HTTP 200 and silently ignored.
  • About 350 projects per query is the ceiling — 7 per page, no page 51 — so large queries are split by country.
  • `budget_type` tells you whether a missing `budget_min` is a gap or a budget that has no lower bound. 25.0% are `max_only`.
  • 80.5% of client ratings are 0.00 meaning "no ratings yet", so `client_has_rating` is the field to filter on.
On this page9 sections

Workana is the largest freelance marketplace in Latin America, and its project listings are the closest thing there is to a public record of what LATAM clients are willing to pay for. Reading them is easy. Reading them correctly takes two decisions most tools get wrong.

What Workana exposes without a login

Project listings: title, description, budget, skills, category and subcategory, the client's country, their reputation signals, the proposal count, and the structured answers they gave Workana's posting form. Client names arrive already masked by Workana.

No login, no cookies, no proxy. Concurrency 3 is the measured default — at 5, Workana's own servers returned 5% HTTP 503, so the polite setting is again the reliable one.

Step 1 — use only the filters that filter

Workana accepts a lot of URL parameters and applies five of them: category, subcategory, skill, country and free-text search. Thirteen others return HTTP 200 and change nothing — budget_min, is_hourly, duration, payment_verified and nine more. The full list and how they were tested.

Step 2 — pick the locale deliberately

locale looks cosmetic and is not. It changes the language Workana renders its text in, and with it the thousands separator: "USD 1,000" in English and "USD 1.000" in Spanish are both one thousand.

The Actor parses per locale and records which one was used on every row, so the parse is checkable. Why that is a three-orders-of-magnitude problem if you get it wrong.

Step 3 — set a cap you understand

maxItems defaults to 500, and the site's own limit sits below that for a single query: 7 projects per page, no page 51, so about 350 projects per query for everyone. Bigger runs come from more queries, and the Actor splits by country automatically — an axis measured at 4% overlap and 6.8x more unique projects across six countries.

Step 4 — run it and read the coverage report

input.json
{
  "subcategory": "web-development",
  "country": "AR",
  "maxItems": 500,
  "locale": "es",
  "maxCacheAgeHours": 6
}

Then read COVERAGE in the key-value store. One entry per query: what Workana declared, what was delivered, whether the page-50 ceiling was hit, and how many projects are out of reach. If a run could not give you everything, the output says so rather than leaving you to assume — why there is no coverage percentage.

Reading budgets without breaking them

Three fields, in this order:

  1. budget_type — `range` 70.6%, `max_only` 25.0%, `min_only` 4.4%. A null budget_min on a `max_only` budget is not missing data; there is no minimum to report.
  2. budget_unit — `project` or `hour`. Mixing the two in one average produces a number that means nothing.
  3. budget_raw — Workana's original string, kept so you can check the parse rather than trust it.

Reading client signals without discarding the market

client_rating is present on every project, and 80.5% of the values are 0.00 — which means “no ratings yet”, not “rated zero”. Filter on client_has_rating first or you will remove four fifths of the market believing you removed bad clients. The measurement.

client_payment_verified (true on 18.9%) and total_bids are the other two signals worth reading — and total_bids is time-sensitive, because the median goes from 1 proposal to 10 within twelve hours.

What a run costs

$0.002 per project and $0.00001 to start. Five hundred projects is a dollar. Failed requests go to ERRORS in the key-value store and are never charged — and if a run has no failures, no ERRORS record is created at all, because an empty error file suggests something went wrong when nothing did.

Four mistakes that waste a run

  1. Filtering on a parameter that does nothing. You pay for rows you did not want and believe you filtered them.
  2. Averaging budget_min. It silently drops the quarter of projects that never had one and biases the average upward.
  3. Filtering on client_rating alone. Four fifths of the market disappears.
  4. Judging competition from a day-old row. Proposal counts move in hours.

Frequently asked questions

Do I need an account to scrape Workana?
No. Project listings are public, and the Actor uses no login, cookies or proxy. Client names arrive already masked by Workana.
How many projects can I get from one query?
About 350. Workana serves 7 projects per page and stops at page 50, which applies to every tool. The Actor splits large queries by country and writes a coverage report saying what it could not reach.
Why does the Actor offer so few filters?
Because Workana only applies five of them. Thirteen others return HTTP 200 and change nothing, so offering them would promise filtering that does not happen and bill you for rows you did not ask for.
Does the language setting matter?
Yes, more than it looks. It changes the thousands separator in budgets — "USD 1,000" and "USD 1.000" are both one thousand — so the Actor parses per locale and records which one was used.

Sources

Every URL below was requested and returned a page on the date shown.

  1. Operator claimchecked 19 Aug 2026
    Workana Projects & Client Demand Scraper — Actor README and input schemaActorStack / Apify Store
  2. Site declarationchecked 19 Aug 2026
    workana.com/robots.txtWorkana
  3. Platform docschecked 18 Aug 2026
    Actors — Apify platform documentationApify
  4. Platform docschecked 18 Aug 2026
    Dataset storageApify
Aerial view of a Latin American city centre at night, streets picked out in light.
WorkanaGuide

Market analysis

What listing data supports — demand by skill, budget distributions, competition levels — and the four claims it cannot carry.

8 min
A white measuring tape curving across a dark background, showing the numbers 15 to 45.
WorkanaMeasured

Proposal velocity

Measured across 401 projects: competition on a freelance listing has a half-life measured in hours, which makes a stale row a wrong row.

6 min
Aerial view of a Latin American city centre at night, streets picked out in light.
WorkanaMeasured

The coverage ceiling

About 350 projects per query is the limit for every tool. The interesting part is that Workana cannot tell you what you are missing either — so the Actor writes a coverage report instead of a percentage.

7 min