# Freelancer Scraper — Projects, Freelancers, Bids & Contests (`logiover/freelancer-scraper`) Actor

Scrape Freelancer.com without login: projects (open now or 17M+ of history) with USD budgets and bid stats, freelancer profiles with rates, ratings and reviews, every bid with bidder and amount, and contests. Thousands of rows per minute. Not affiliated with Freelancer.com.

- **URL**: https://apify.com/logiover/freelancer-scraper.md
- **Developed by:** [Logiover](https://apify.com/logiover) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Freelancer Scraper

**Freelancer Scraper** is a fast, no-login **Freelancer.com scraper** that exports **projects, freelancer profiles, bids and contests** from Freelancer.com to **CSV, Excel, JSON or an API** in seconds. Scrape Freelancer.com projects that are open for bids right now, or go back through **more than 17 million historical projects**; pull **freelancer profiles** with hourly rates, ratings, reviews, skills and verification badges from the 1.6-million-profile directory; get **every bid** on a project with the bidder, the amount, the delivery time and the winner; and collect **design contests** with prizes and entry counts.

It works as a **Freelancer.com API alternative**: **scrape Freelancer.com projects and freelancers without login** — no Freelancer.com account, no OAuth app, no API key, no cookies and no browser. You type keywords or skills, pick countries and filters, and get clean, flat rows with budgets converted to **US dollars**, ISO dates and one column per fact — ready for lead generation, market research, rate benchmarking and AI agents. Measured on 2026-10-13: **25,000 projects in 44 seconds**, **12,000 freelancer profiles in 53 seconds**, the first rows of any run in **about 1–4 seconds**.

> Not affiliated with, endorsed by or sponsored by Freelancer Technology Pty Limited or Freelancer.com. "Freelancer" and "Freelancer.com" are trademarks of their owner and are used here only to describe the data source.

***

### What you get

| Row type | What it is | Highlights | Typical volume |
|---|---|---|---|
| **Project** | A job posted by a client | budget in the posted currency **and USD**, fixed/hourly, bid count and average bid, skills, status and close reason (awarded, expired, cancelled), posted date, full description, 11 upgrade flags, local-job location, client country (with a country filter) | ≈5,000 open now, 17.7 million in the history |
| **Freelancer** | A directory profile | **hourly rate (USD)**, country and city, **rating**, reviews, jobs completed, completion / on-budget / on-time %, five rating sub-scores, earnings score, all skills, exams, membership, Preferred Freelancer and verification badges, member since, photo, "About me" | 1.6 million profiles |
| **Bid** | One proposal on a project | amount (and USD), delivery days, rank, **award status (winner = `awarded`)**, sealed flag, the bidder's name, country, rate, rating, reviews and verification, plus the project's title, link, budget and bid count | 10–1,600+ per project |
| **Contest** | A design (or other) contest | prize (and USD), entries, duration, judging period, dates, status, type, skills | ≈180 active, 380,000+ in the history |

Every row has a `type` column (`project`, `freelancer`, `bid`, `contest`), a stable numeric `id`, a direct `url`, `scrapedAt`, and `searchQuery` — the keyword or skill that found it. Fields that do not apply to a row (a location on a remote job, a client country without a country filter) are left out instead of being written as empty columns, so exports stay tidy.

***

### Who uses a Freelancer.com scraper, and for what

- **B2B lead generation** — agencies, SaaS vendors and recruiters build lists of active freelancers by skill, country, hourly rate and rating ("React developers in Poland, 4.8+, 50+ reviews"), or find clients who keep posting projects in their niche.
- **Market research and demand analytics** — count how many projects ask for a skill per month, how budgets move, which categories grow, which countries hire. The full project history since the 2000s is reachable, newest first.
- **Rate benchmarking** — compare hourly rates of freelancers by skill and country, budgets of projects, average bids and **real bid amounts** to price your own services or justify a rate card.
- **Competitive intelligence on bids** — see who bids on projects like yours, at what price, how fast they promise delivery, and **who won** (`awardStatus = awarded`).
- **Job alerts and bidding bots** — schedule the Actor every 10–60 minutes with `postedAfter: "1 hour"` and your skills, then push new open projects to Slack, email, a CRM or an AI agent that drafts proposals.
- **Talent sourcing and research** — shortlist verified, high-completion freelancers before posting a project, or study gig-economy pricing across countries.
- **AI agents and LLM pipelines** — clean JSON rows with USD-normalised money and ISO dates are easy to feed into RAG, analytics notebooks or agent tools (see *MCP / AI agents* below).

***

### How it works

1. **Public JSON, no login.** The Actor reads the public JSON endpoints the Freelancer.com website itself uses for anonymous visitors — no HTML parsing to break, no browser, no account.
2. **Deep history without the paging wall.** Freelancer.com stops paging a project or contest search at 5,000 results, whatever total it reports. The Actor reads a big search in **windows of up to 5,000**, each ending where the previous one's oldest row is, and **pipelines** them: the next window starts as soon as the current window's last page is in, so 25,000 projects arrive in 44 seconds. Overlaps at the window edges are deduplicated by ID.
3. **Freelancer directory beyond 10,000.** The directory stops at 10,000 profiles per search. When you ask for more, the search is split into **hourly-rate bands** (which partition the directory exactly — measured) and, where a band is still bigger, into the **30 largest countries plus one "rest of the world" slice**. No profile is read twice on purpose; duplicates are removed by ID.
4. **Bids with bidder profiles.** For every project found, the Actor reads its bids and joins each bidder's public profile (rating, reviews, country, rate); on projects with hundreds of bids the profiles are looked up in batches.
5. **Rate limits handled for you.** Freelancer.com allows each IP about 200 project requests per minute and 1,000 per hour. The Actor reads the limit headers on every response, keeps a few requests in reserve, and moves extra work to fresh **Apify Proxy** IPs before a limit is hit — measured: 0 rate-limit errors in a 252-request run. Without a proxy it waits for the window to reopen instead of failing.
6. **Exact limits, honest outcomes.** `maxItems` is exact (slots are reserved before data is written, so parallel pages can never overshoot). Rows are saved page by page, so you see results within seconds. A search that genuinely has no results ends **SUCCEEDED** with a plain-English explanation; a run that could not reach Freelancer.com at all ends **FAILED** with the reason — the two are never confused. A `SUMMARY` record in the run's key-value store lists requests, windows, splits, duplicates, response times and anything not found.

***

### How to use it

1. Click **Try for free** / **Start** on this page (an Apify account is free to create).
2. Choose **What to scrape**: Projects, Freelancers, Bids or Contests.
3. Enter **search keywords** and/or **skills**, optionally **countries** and the filters for that mode.
4. Set **Max results** (0 = everything the search has) and press **Start**.
5. Watch rows appear in the **Output** tab; export them as **CSV, Excel, JSON, XML or HTML**, or fetch them through the API.

You can also paste **Freelancer.com URLs** — project pages, profiles (`/u/username`), contests, and skill pages such as `/jobs/python/`, `/freelancers/skills/python` or `/freelancers/india/python` — and the Actor fetches exactly those.

***

### Input reference

| Field | Type | Default | Used by | What it does |
|---|---|---|---|---|
| `mode` | `projects` / `freelancers` / `bids` / `contests` | `projects` | all | Which listing to search. URLs are always fetched whatever the mode. |
| `searchQueries` | array of strings | `[]` | all | One search per keyword; all words must match. Empty = list everything (newest first) with your filters. |
| `skills` | array of strings | `[]` | all | Freelancer.com skill names ("Python", "Logo Design", "Web Scraping") or numeric IDs. ANY skill matches. Close names are matched ("React" → React.js) and logged. |
| `countries` | array of strings | `[]` | projects, bids, freelancers | Projects/bids: the **client's** country (adds `clientCountry`). Freelancers: where they live. Names ("Germany", "UK") or ISO codes ("DE"). |
| `urls` | array of strings | `[]` | all | Project URLs or IDs, profile URLs or usernames, contest URLs, skill pages. With URLs and no keywords/skills, only the URLs are scraped. |
| `maxItems` | integer | `1000` | all | Total rows to save. 0 = no limit. Exact. |
| `projectStatus` | `open` / `all` / `closed` | `open` | projects, bids | Open for bids now, the whole history, or closed only. |
| `projectType` | `any` / `fixed` / `hourly` | `any` | projects, bids | Fixed-price or hourly projects. |
| `minBudgetUsd`, `maxBudgetUsd` | integer | `0` | projects, bids | Budget range in USD (the project's range must reach the minimum / start below the maximum). |
| `postedAfter` | date or relative | – | projects, bids, contests | `2026-01-31`, or relative: `1 hour`, `24 hours`, `7 days`, `3 months`. |
| `postedBefore` | date | – | projects, bids, contests | Up to and including this day. |
| `languages` | array | `[]` | projects, bids | Project language codes (`en`, `de`, `es`) or names. |
| `projectUpgrades` | multi-select | `[]` | projects, bids | Featured, Urgent, Sealed, NDA, Full-time, Qualified, Recruiter, IP agreement, Private (any of them). |
| `projectSort` | `newest` / `bids` / `avg_bid` | `newest` | projects, bids | Newest first reaches the end of any search; the other two orders show the top 5,000 per search. |
| `minHourlyRate`, `maxHourlyRate` | integer (USD) | `0` | freelancers | Hourly-rate range. |
| `minRating` | `0`–`5` | `0` | freelancers | Minimum overall rating (implies at least one review). |
| `minReviews` | integer | `0` | freelancers | Minimum number of reviews. |
| `onlineOnly` | boolean | `false` | freelancers | Only freelancers online at run time. |
| `freelancerSort` | `best` / `rating` / `reviews` / `rate` | `best` | freelancers | Freelancer.com's own ranking, highest rating, most reviews, highest rate. |
| `maxBidsPerProject` | integer | `0` | bids | Cap bids per project (0 = all), e.g. 20 to sample many projects. |
| `contestStatus` | `active` / `all` | `active` | contests | Running contests or the whole history. |
| `includeDescriptions` | boolean | `true` | all | Full descriptions and "About me" texts. Off = smaller rows (projects keep a 100-character preview). |
| `maxConcurrency` | integer 1–50 | `24` | all | Parallel API requests. |
| `proxyConfiguration` | proxy | Apify Proxy | all | Used only for overflow when a per-IP limit is reached. Leave as is. |

#### Example inputs

**Open Python projects (live leads):**

```json
{
  "mode": "projects",
  "searchQueries": ["python"],
  "maxItems": 100
}
```

**Project history for market research — every "Shopify" project of the last 90 days, USD budgets:**

```json
{
  "mode": "projects",
  "skills": ["Shopify"],
  "projectStatus": "all",
  "postedAfter": "90 days",
  "maxItems": 0
}
```

**Hourly projects from US and UK clients posted in the last 3 days:**

```json
{
  "mode": "projects",
  "projectStatus": "all",
  "projectType": "hourly",
  "countries": ["US", "United Kingdom"],
  "postedAfter": "3 days",
  "maxItems": 500
}
```

**Lead list — German freelancers with 4+ stars, 10+ reviews, from $30/hour:**

```json
{
  "mode": "freelancers",
  "countries": ["Germany"],
  "minRating": "4",
  "minReviews": 10,
  "minHourlyRate": 30,
  "maxItems": 1000
}
```

**Big directory export — 12,000 Python freelancers (split automatically):**

```json
{
  "mode": "freelancers",
  "searchQueries": ["python"],
  "maxItems": 12000
}
```

**Every bid on recent WordPress projects, with bidder profiles and the winner:**

```json
{
  "mode": "bids",
  "searchQueries": ["wordpress"],
  "projectStatus": "all",
  "maxItems": 2000
}
```

**Design contests history:**

```json
{
  "mode": "contests",
  "searchQueries": ["logo"],
  "contestStatus": "all",
  "maxItems": 1000
}
```

**Job alert (schedule hourly):**

```json
{
  "mode": "projects",
  "skills": ["Web Scraping", "Data Extraction", "Python"],
  "postedAfter": "1 hour",
  "minBudgetUsd": 100,
  "maxItems": 0
}
```

***

### Output data dictionary

#### Project rows (`type = "project"`)

| Field | Type | Description |
|---|---|---|
| `id` | number | Freelancer.com project ID (stable; use for deduplication). |
| `title` | string | Project title. |
| `url` | string | Project page. |
| `projectType` | string | `fixed` or `hourly`. |
| `status` | string | `open`, `work_in_progress`, `complete`, `closed`… |
| `statusDetail` | string | Why it is no longer open: `closed_awarded`, `closed_expired`, `frozen_timeout`, `cancel_seller`, `cancel_admin`, `cancel_buyer`… (absent while open). |
| `currency` | string | Posted currency (USD, EUR, INR, AUD, GBP…). |
| `budgetMin`, `budgetMax` | number | Budget range in that currency; hourly projects: per hour. `budgetMax` is empty for open-ended budgets. |
| `budgetMinUsd`, `budgetMaxUsd` | number | Same in US dollars (Freelancer.com's own exchange rate). |
| `hourlyHoursPerWeek` | number | Hourly projects: expected hours per week. |
| `bidCount` | number | Bids received. |
| `bidAvg`, `bidAvgUsd` | number | Average bid, in the project currency and in USD. |
| `skills` | string | Required skills, pipe-separated. |
| `categories` | string | Skill categories. |
| `description` | string | Full description with paragraph breaks. |
| `language` | string | Language code. |
| `postedAt` | string | Posting time, ISO 8601 UTC. |
| `bidPeriodDays` | number | Days the project accepts bids. |
| `isFeatured`, `isUrgent`, `isSealed`, `isNda`, `isFullTime`, `isPrivate`, `isRecruiterAssisted`, `isQualifiedOnly`, `isIpAgreement`, `isHireMe`, `isLocal` | boolean | Upgrades and project kind. |
| `location`, `latitude`, `longitude`, `localJobDate` | string / number | Local (on-site) jobs only. |
| `clientCountry` | string | Client's country — present when you filter projects by country. |
| `searchQuery` | string | Keyword or skill that found the row. |
| `scrapedAt` | string | Collection time. |

#### Freelancer rows (`type = "freelancer"`)

| Field | Type | Description |
|---|---|---|
| `id`, `username`, `url` | number / string | User ID, username and profile link. |
| `name`, `tagline` | string | Public name and headline. |
| `hourlyRateUsd` | number | Hourly rate in USD. |
| `country`, `countryCode`, `city`, `region` | string | Location. |
| `timezone`, `utcOffset` | string / number | IANA time zone and hours from UTC. |
| `rating`, `reviews` | number | Overall 0–5 rating (empty without reviews) and review count. |
| `jobsCompleted`, `completionRatePct` | number | Completed projects and completion rate. |
| `onBudgetPct`, `onTimePct` | number | Share of reviewed jobs on budget / on time. |
| `ratingQuality`, `ratingCommunication`, `ratingExpertise`, `ratingProfessionalism`, `ratingHireAgain` | number | Sub-scores 0–5. |
| `rating12Months`, `reviews12Months` | number | Last 12 months. |
| `earningsScore` | number | Freelancer.com's 0–10 earnings score. |
| `skills`, `skillCount`, `topCategories` | string / number | All listed skills, how many, and the three main categories. |
| `qualifications` | string | Exams passed with scores. |
| `portfolioItems` | number | Portfolio size. |
| `membership` | string | Membership plan. |
| `isPreferredFreelancer`, `isVerified`, `identityVerified`, `paymentVerified`, `phoneVerified`, `emailVerified`, `depositMade` | boolean | Trust badges. |
| `registeredAt` | string | Member since. |
| `language` | string | Primary language. |
| `avatarUrl` | string | Profile photo. |
| `profileDescription` | string | "About me" text. |

#### Bid rows (`type = "bid"`)

| Field | Type | Description |
|---|---|---|
| `id` | number | Bid ID. |
| `projectId`, `projectTitle`, `projectUrl`, `projectType`, `projectStatus` | | The project the bid belongs to. |
| `projectBudgetMinUsd`, `projectBudgetMaxUsd`, `projectBidCount`, `currency` | | Project budget in USD, its bid count and currency. |
| `bidAmount`, `bidAmountUsd` | number | Amount bid (hourly projects: per hour); absent on sealed bids. |
| `deliveryDays` | number | Promised delivery time. |
| `bidPostedAt` | string | When the bid was placed. |
| `bidRank` | number | Freelancer.com's ranking of the bid on that project. |
| `awardStatus` | string | `awarded` marks the winner; also `pending`, `rejected`, `canceled`. |
| `bidStatus` | string | `active`, `in_progress`, … |
| `milestonePercent` | number | Upfront milestone requested (%). |
| `isSealed`, `isHighlighted`, `isRetracted` | boolean | Bid flags. |
| `bidderId`, `bidderUsername`, `bidderName`, `bidderUrl` | | Who bid. |
| `bidderCountry`, `bidderCity`, `bidderHourlyRateUsd` | | Where they are and their profile rate. |
| `bidderRating`, `bidderReviews`, `bidderJobsCompleted`, `bidderCompletionRatePct`, `bidderEarningsScore` | number | Their track record. |
| `bidderIdentityVerified`, `bidderPaymentVerified`, `bidderRegisteredAt` | | Verification and member since. |

#### Contest rows (`type = "contest"`)

| Field | Type | Description |
|---|---|---|
| `id`, `title`, `url` | | Contest ID, title, page. |
| `status` | string | `active`, `pending` (judging), `closed`. |
| `contestType` | string | `guaranteed` or `prepaid`. |
| `prize`, `currency`, `prizeUsd` | | Prize, currency and USD value. |
| `entryCount` | number | Entries submitted. |
| `durationDays`, `judgingPeriodDays` | number | Contest length and judging window. |
| `postedAt`, `endsAt` | string | Start and end. |
| `skills`, `categories`, `description`, `language` | string | Content. |
| `isFeatured`, `isUrgent`, `isSealed`, `isHighlighted`, `isPrivate`, `isExtended` | boolean | Upgrades. |

***

### Output examples (real rows from test runs on 2026-10-13; long texts and a few fields shortened)

**Project:**

```json
{
  "type": "project",
  "id": 40765375,
  "title": "Bitcoin Trading Strategy Backtesting",
  "url": "https://www.freelancer.com/projects/data-analysis/Bitcoin-Trading-Strategy-Backtesting",
  "projectType": "hourly",
  "status": "open",
  "currency": "GBP",
  "budgetMin": 10,
  "budgetMax": 15,
  "budgetMinUsd": 13.24,
  "budgetMaxUsd": 19.86,
  "hourlyHoursPerWeek": 40,
  "bidCount": 27,
  "bidAvg": 15.81,
  "bidAvgUsd": 20.94,
  "skills": "Python | Statistics | R Programming Language | Financial Analysis | Statistical Analysis | Data Analysis | Backtesting | Cryptocurrency",
  "categories": "Websites, IT & Software | Engineering & Science | Business, Accounting, Human Resources & Legal",
  "description": "Cryptocurrency Trading Strategy Analysis\n\nI want to analyse a file containing historical Bitcoin price predictions…",
  "language": "en",
  "postedAt": "2026-10-13T10:25:11.000Z",
  "bidPeriodDays": 7,
  "isFeatured": false,
  "isUrgent": false,
  "isSealed": false,
  "isNda": false,
  "isFullTime": false,
  "isPrivate": false,
  "isRecruiterAssisted": false,
  "isQualifiedOnly": false,
  "isIpAgreement": false,
  "isHireMe": false,
  "isLocal": false,
  "searchQuery": "python",
  "scrapedAt": "2026-10-13T10:45:48.250Z"
}
```

**Freelancer:**

```json
{
  "type": "freelancer",
  "id": 60347976,
  "username": "neerajdhameliya",
  "url": "https://www.freelancer.com/u/neerajdhameliya",
  "name": "Niral",
  "tagline": "Full Stack Developer: Flutter, React, Node, Python",
  "hourlyRateUsd": 25,
  "country": "India",
  "countryCode": "IN",
  "city": "Surat",
  "region": "Gujarat",
  "timezone": "Asia/Calcutta",
  "rating": 4.99,
  "reviews": 97,
  "jobsCompleted": 103,
  "completionRatePct": 97.2,
  "onBudgetPct": 98.7,
  "onTimePct": 99.2,
  "ratingHireAgain": 4.96,
  "rating12Months": 5,
  "reviews12Months": 12,
  "earningsScore": 8.5575,
  "skills": "PHP | JavaScript | Python | Website Design | Mobile App Development | Django | eCommerce | MySQL | …",
  "skillCount": 53,
  "topCategories": "Websites, IT & Software | Design, Media & Architecture | Mobile Phones & Computing",
  "qualifications": "Preferred Freelancer Program SLA Exam (97%) | Python Level 1 (80%) | Python - Level 2 (75%)",
  "portfolioItems": 29,
  "membership": "premier",
  "isPreferredFreelancer": false,
  "isVerified": true,
  "identityVerified": true,
  "paymentVerified": true,
  "registeredAt": "2022-01-25T06:58:24.000Z",
  "avatarUrl": "https://cdn3.f-cdn.com/ppic/272514159/logo/60347976/Cyd9V/profile_logo_Facebook_60347976.jpg",
  "profileDescription": "Full stack web developer and mobile app developer building web apps, SaaS platforms, APIs and Flutter apps since 2015…",
  "searchQuery": "python",
  "scrapedAt": "2026-10-13T10:45:48.969Z"
}
```

**Bid (the winning one):**

```json
{
  "type": "bid",
  "id": 496578552,
  "projectId": 40765303,
  "projectTitle": "One-page website development (Bricks Builder)",
  "projectUrl": "https://www.freelancer.com/projects/graphic-design/One-page-website-development-Bricks",
  "projectType": "fixed",
  "projectStatus": "work_in_progress",
  "projectBudgetMinUsd": 250,
  "projectBudgetMaxUsd": 250,
  "projectBidCount": 1,
  "currency": "USD",
  "bidAmount": 250,
  "bidAmountUsd": 250,
  "deliveryDays": 27,
  "bidPostedAt": "2026-10-13T09:43:00.000Z",
  "bidRank": 1,
  "awardStatus": "awarded",
  "bidStatus": "in_progress",
  "milestonePercent": 0,
  "isSealed": false,
  "isHighlighted": false,
  "isRetracted": false,
  "bidderId": 35799422,
  "bidderUsername": "sarthakdhonchak",
  "bidderName": "Sarthak",
  "bidderUrl": "https://www.freelancer.com/u/sarthakdhonchak",
  "bidderCountry": "India",
  "bidderCity": "Panipat",
  "bidderHourlyRateUsd": 50,
  "bidderRating": 4.88,
  "bidderReviews": 193,
  "bidderJobsCompleted": 205,
  "bidderCompletionRatePct": 96.2,
  "bidderEarningsScore": 8.5947,
  "bidderIdentityVerified": true,
  "bidderPaymentVerified": true,
  "bidderRegisteredAt": "2019-06-15T11:46:20.000Z",
  "searchQuery": "wordpress",
  "scrapedAt": "2026-10-13T10:50:37.071Z"
}
```

Contest rows follow the same pattern (title, prize and `prizeUsd`, entries, dates, skills, status).

***

### How much data can I get?

Measured on the Apify platform on **2026-10-13** with default settings (512 MB memory):

| Input | Rows saved | Run time | Memory peak | Notes |
|---|---|---|---|---|
| Prefilled example: open "python" projects, 100 rows | 100 | 2.1 s (first rows after 0.6 s) | 43 MB | 1 API request |
| Historical "python" projects | 1,000 | 2.8 s | 66 MB | 11 requests |
| **All open projects on Freelancer.com** (`maxItems: 0`) | 5,103 | 6.0 s | 76 MB | 2 windows |
| **Whole project history, newest first** | **25,000** | **46 s** | 104 MB | 252 requests, 7 windows, 6 overlap duplicates removed, 0 rate-limit errors |
| Freelancers "web scraping" | 1,000 | 6.1 s | 76 MB | first rows after 4 s |
| **Freelancers "python"** (split into rate bands and countries) | **12,000** | **54 s** | 89 MB | 125 requests, 115 slices |
| Bids on "wordpress" projects (all statuses) | 2,000 | 3.6 s | 54 MB | bidder profiles joined |
| Contest history | 1,000 | 11.9 s | 51 MB | |
| Hourly projects, US + UK clients, last 3 days | 113 (all that exist) | 1.6 s | 41 MB | `clientCountry` filled |
| German freelancers, 4★+, 10+ reviews, $30+/h | 71 (all that exist) | 3.8 s | 41 MB | |

**Depth limits, in plain words**

- **Projects and contests:** no practical limit — a search is read to its very end, newest first (17.7 million projects and 380,000 contests exist). Only the *Most bids* and *Highest average bid* orders stop at the top 5,000 per search, because Freelancer.com does not page further in those orders.
- **Freelancers:** 10,000 per search slice; bigger searches are split by hourly rate and country automatically, so tens of thousands of profiles per run are normal. Very large slices (for example *every* $10/hour freelancer in India) are read to 10,000 and listed in `SUMMARY.cappedSlices`.
- **Bids:** all bids of every project (or `maxBidsPerProject`). Sealed bids show the bidder but not the amount.
- **Open projects:** about 5,000 at any time — the whole live market fits in one run of a few seconds.

**Big runs and the "Maximum cost per run" setting.** Every pay-per-event run on Apify has a maximum cost (*Run options → Maximum cost per run*, or `maxTotalChargeUsd` in the API). For **10,000+ results** set it to at least **results × price per result** (Pricing tab) — e.g. 25,000 × $2.50 / 1,000 = **$62.50**. With a smaller budget the run **stops cleanly at the number it covers**, ends **SUCCEEDED** and says so in its status (*"Saved 6,800 results — this run's maximum cost ($17.00) covers 6,800 results at the current price. Raise "Maximum cost per run" to get more."*); it never fails, aborts or charges past your limit (`SUMMARY.stoppedBy = "MAX_COST"`).

**What you pay:** a fixed price per result — see the *Pricing* tab (on 2026-10-13: $2.50 per 1,000 results on the Free plan, down to $1.50 per 1,000 from the Gold plan up). Compute, storage and proxies are included; there is no separate proxy bill and no subscription.

***

### Integrations

#### API (curl) — run and get the rows in one call

```bash
curl -X POST "https://api.apify.com/v2/acts/logiover~freelancer-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN&format=json" \
  -H "Content-Type: application/json" \
  -d '{"mode":"projects","searchQueries":["python"],"maxItems":200}'
```

Use `format=csv` or `format=xlsx` for spreadsheets. For long runs use the asynchronous `runs` endpoint and fetch `defaultDatasetId` when the run finishes.

#### Node.js

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('logiover/freelancer-scraper').call({
    mode: 'freelancers',
    skills: ['React.js'],
    countries: ['Poland'],
    minRating: '4',
    maxItems: 500,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length, items[0]);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("logiover/freelancer-scraper").call(run_input={
    "mode": "bids",
    "searchQueries": ["shopify"],
    "projectStatus": "all",
    "maxItems": 1000,
})
for bid in client.dataset(run["defaultDatasetId"]).iterate_items():
    if bid.get("awardStatus") == "awarded":
        print(bid["projectTitle"], bid["bidderUsername"], bid.get("bidAmountUsd"))
```

#### Make, Zapier, n8n

Use the official **Apify** apps/nodes: action *Run an Actor* with `logiover/freelancer-scraper` and your input JSON, then *Get dataset items*. Typical flows: new open project → Slack/Telegram message; new freelancer list → HubSpot/Pipedrive; weekly bid export → Google Sheets.

#### Google Sheets

Either connect the Apify integration for Google Sheets, or paste this into a cell to always load the latest run as CSV:

```
=IMPORTDATA("https://api.apify.com/v2/acts/logiover~freelancer-scraper/runs/last/dataset/items?token=YOUR_APIFY_TOKEN&format=csv")
```

#### Schedules and webhooks

Create a **Schedule** (for example every 30 minutes with `postedAfter: "30 minutes"`) and add a **webhook** on *Run succeeded* to push the new rows to your endpoint, CRM or bidding assistant.

#### MCP / AI agents

The Actor works as a tool for AI agents through the **Apify MCP server** — connect Claude, ChatGPT, Cursor or any MCP client to `https://mcp.apify.com/?actors=logiover/freelancer-scraper` and ask in plain language: *"Find open Shopify projects from US clients over $500 posted today"* or *"List 4.8-star Python freelancers in Germany with their rates"*. The flat, USD-normalised output is easy for an LLM to reason about.

***

### Freelancer Scraper vs. the alternatives

| | This Actor | Official Freelancer.com API | Manual browsing / copy-paste |
|---|---|---|---|
| Account, OAuth app, API key | **not needed** | needed for most use | needs an account for many pages |
| Past the 5,000 / 10,000 paging cap | **yes — windows and splits built in** | you build it | no |
| Rate limits | **handled (reserve + IP overflow)** | you handle 429s | – |
| Bids with bidder profiles and winner | **yes, joined** | separate calls per bid and user | slow |
| Money in USD, ISO dates, flat columns | **yes** | raw nested JSON | no |
| Export | CSV, Excel, JSON, API, Sheets, webhooks, MCP | code only | none |
| Speed | 25,000 projects in 46 s | depends on your code | hours |

***

### Limits and tips

- **Client identity is not public.** Freelancer.com hides who posted a project from anonymous visitors, so there is no client name, rating or contact. Filter by `countries` to get each project's client country.
- **No emails or phone numbers.** Profiles do not expose them; use the profile URL, name, company and location for enrichment.
- **Sealed bids** hide the amount (the row is still there with the bidder).
- **Budgets on hourly projects** are per hour; `hourlyHoursPerWeek` tells you the expected weekly load.
- **Totals vs rows:** Freelancer.com's counts include private and deleted items it does not return, so a search can yield slightly fewer rows than its headline total.
- **Fastest monitoring setup:** `projectStatus: "open"`, your `skills`, `postedAfter` equal to the schedule interval, `maxItems: 0`.
- **Fastest bulk export:** `maxConcurrency` 24–50 and `includeDescriptions: false` if you do not need long texts.

***

### Reliability and freshness

- **Live data**: every run reads Freelancer.com at that moment — nothing is cached or resold from an old database.
- **Retries and IP rotation**: transient errors are retried; a refused or rate-limited IP rests while work continues on another Apify Proxy IP.
- **No silent failures**: empty searches succeed with an explanation, unreachable sources fail with the reason, missing URLs are listed by name, and every run writes a `SUMMARY` with requests, windows, splits, duplicates and response times.
- **Exact `maxItems`** and **no duplicate rows** (deduplicated by ID across windows and slices); the run also respects your **maximum cost per run** to the result and stops cleanly there instead of failing.
- **Tested** on 2026-10-13 with 25,000-project, 12,000-freelancer, 2,000-bid and 1,000-contest runs plus negative tests (nonsense keyword, invalid URL, unknown skill, deleted project).

***

### FAQ

#### Do I need a Freelancer.com account, API key or cookies?

No. The Actor uses the public data Freelancer.com shows to anonymous visitors. You only need an Apify account to run it.

#### Is it legal to scrape Freelancer.com?

The Actor collects publicly visible information only — no login walls, no private messages, no personal contact details. Scraping public data is generally lawful in many jurisdictions, but you are responsible for how you use the data: respect Freelancer.com's terms, privacy laws such as GDPR/CCPA (especially for profile data used in outreach) and anti-spam rules. When in doubt, ask a lawyer.

#### How many projects can I scrape in one run?

As many as the search has. Projects are read newest first in windows of up to 5,000 with no total cap; a measured run saved 25,000 projects in 46 seconds. With `maxItems: 0` a run continues until the search is exhausted or the run's timeout is reached.

#### How many freelancer profiles can I get?

Up to 10,000 per search slice, and the Actor splits bigger searches by hourly rate and country automatically — 12,000 "python" freelancers took 54 seconds. Tens of thousands per run are normal.

#### Why did my run stop before reaching "Max results"?

Most likely the run's **maximum cost** was reached. Pay-per-event runs on Apify have a cost limit (*Maximum cost per run* in the run options, `maxTotalChargeUsd` in the API); the Actor saves exactly as many results as that limit pays for, then finishes successfully with a message such as *"Saved 6,800 results — this run's maximum cost ($17.00) covers 6,800 results at the current price."* Raise the limit to at least *results × price per result* — e.g. $62.50 for 25,000 results at $2.50 per 1,000 — and run again. Other reasons are reported the same way: the search ran out of results, or the run hit its time limit.

#### Can I get the bids on a project and see who won?

Yes. Choose **Bids** mode (with a search or project URLs). Each bid row contains the amount, delivery days, the bidder's profile stats, and `awardStatus` — `awarded` marks the winning bid.

#### Why is the bid amount empty on some bids?

Those are **sealed** bids: Freelancer.com hides the amount from everyone except the client. The bidder and the rest of the row are still provided.

#### Can I get the client's name, email or phone?

No. Freelancer.com does not expose client identities or contact details publicly. You can get the client's **country** by filtering projects by country.

#### How do I monitor new projects for my skills?

Create a schedule (e.g. every 30 minutes) with `mode: "projects"`, your `skills`, `postedAfter: "30 minutes"` and `maxItems: 0`, then add a webhook or a Make/Zapier/n8n flow to forward new rows to Slack, email or your CRM.

#### Are budgets converted to US dollars?

Yes. `budgetMinUsd`, `budgetMaxUsd`, `bidAvgUsd`, `bidAmountUsd` and `prizeUsd` use the exchange rate Freelancer.com itself attaches to each currency; the original currency and amounts are kept too. Freelancer hourly rates are stored in USD by Freelancer.com.

#### Which URLs can I paste?

Project pages (`/projects/category/title-123` or just the numeric ID), profiles (`/u/username` or the bare username), contests (`/contest/…-123.html`), and skill pages: `/jobs/python/`, `/freelancers/skills/python`, `/freelancers/india/python`. Regional domains (freelancer.in, freelancer.co.uk …) work too.

#### What happens when a search has no results?

The run succeeds with 0 rows and a status message explaining why ("Freelancer.com has nothing matching this search" or, for open projects only, a hint to search the full history). Unknown skills, unknown countries and invalid URLs are reported by name.

#### What if Freelancer.com rate-limits the scraper?

The Actor reads Freelancer.com's limit headers and stops short of the limit on each IP, continuing on other Apify Proxy IPs; without a proxy it waits until the limit window reopens. Measured: a 252-request run finished with zero rate-limit errors.

#### Can I export to Excel or Google Sheets?

Yes — the Output tab offers CSV, Excel (XLSX), JSON, JSONL, XML and HTML. For Google Sheets use the Apify integration or the `IMPORTDATA` formula above.

#### Can AI agents use it?

Yes, through the Apify MCP server (`https://mcp.apify.com/?actors=logiover/freelancer-scraper`) or as a tool in LangChain, LlamaIndex, CrewAI and similar frameworks via the Apify API.

#### I need a field that is missing. What can I do?

Open an issue on the **Issues** tab with an example URL — issues are answered within 24 hours, and reasonable field requests are usually added quickly.

***

### Changelog

- **2026-10-13 — first release.** Projects (open, closed or full history) with USD budgets and bid stats; freelancer directory with rate/country splitting past 10,000; bids with bidder profiles and award status; contests; URL input for projects, profiles, contests and skill pages; pipelined time windows (25,000 projects in 46 s); per-IP rate-limit handling with Apify Proxy overflow; exact `maxItems`; honest empty/failed outcomes with a `SUMMARY` record. Full history in the **Changelog** tab.

### Support

Questions, bugs or feature requests: open an issue on the **Issues** tab — answered within 24 hours. Please include the run ID so the run can be checked.

### Disclaimer

This Actor is an independent tool. It is **not affiliated with, endorsed by or sponsored by Freelancer.com** or Freelancer Technology Pty Limited. It collects only publicly available data; you are responsible for using that data lawfully and in line with the source's terms.

# Changelog

This Actor's version history is a separate document: https://apify.com/logiover/freelancer-scraper/changelog.md

# Actor input Schema

## `mode` (type: `string`):

Which Freelancer.com listing the keywords, skills and countries below search. Bids searches projects with the project filters and returns one row per bid with the bidder's profile. URLs, project IDs and usernames are always fetched, whatever you pick here (in Bids mode project URLs return their bids).

## `searchQueries` (type: `array`):

One search per keyword, e.g. "python", "logo design", "shopify store". All words must match. Leave empty to list everything (newest projects/contests, or the whole freelancer directory) — the filters below still apply.

## `skills` (type: `array`):

Skill names as Freelancer.com shows them ("Python", "Web Scraping", "Logo Design", "React.js") or numeric skill IDs. Results need ANY of the listed skills. Close names are matched ("React" → React.js, "Machine Learning" → Machine Learning (ML)); the run log shows what each name matched.

## `countries` (type: `array`):

Projects: the CLIENT's country (each row then gets clientCountry). Freelancers: where the freelancer lives. Names ("Germany", "United States", "UK") or two-letter codes ("DE", "US"). Ignored for contests.

## `urls` (type: `array`):

Fetched directly: project pages (freelancer.com/projects/…), profiles (freelancer.com/u/username), contests (freelancer.com/contest/…), numeric project IDs, bare usernames, and skill pages (freelancer.com/jobs/python/, freelancer.com/freelancers/skills/python, freelancer.com/freelancers/india/python), which run as searches. When you give URLs but no keywords or skills, only the URLs are scraped.

## `maxItems` (type: `integer`):

Stop after this many rows in total (projects + freelancers + contests). 0 = no limit: the run ends when every search is exhausted or the run times out.

## `projectStatus` (type: `string`):

Open projects are the live leads (about 5,000 at any time). "All" and "Closed" search the full history, newest first — use them for market research and budget benchmarks.

## `projectType` (type: `string`):

Fixed-price or hourly projects only.

## `minBudgetUsd` (type: `integer`):

Only projects whose budget range reaches at least this many US dollars (hourly projects: per hour). 0 = no minimum.

## `maxBudgetUsd` (type: `integer`):

Only projects whose budget range starts at or below this many US dollars. 0 = no maximum.

## `postedAfter` (type: `string`):

Projects and contests posted on or after this date — an absolute date (2026-01-31) or a relative one ("7 days", "24 hours", "3 months"). Empty = no limit.

## `postedBefore` (type: `string`):

Projects and contests posted on or before this date (the whole day counts). Empty = up to now.

## `languages` (type: `array`):

Only projects written in these languages: two-letter codes ("en", "de", "es") or names ("German").

## `projectUpgrades` (type: `array`):

Only projects with ANY of these paid upgrades.

## `projectSort` (type: `string`):

Newest first reads a search to its very end. The other orders show the top 5,000 of each search — Freelancer.com does not page further.

## `minHourlyRate` (type: `integer`):

Only freelancers charging at least this much per hour. 0 = no minimum.

## `maxHourlyRate` (type: `integer`):

Only freelancers charging at most this much per hour. 0 = no maximum.

## `minRating` (type: `string`):

Only freelancers with at least this overall rating (and at least one review).

## `minReviews` (type: `integer`):

Only freelancers with at least this many reviews. 0 = no minimum.

## `onlineOnly` (type: `boolean`):

Only freelancers who are online at the moment of the run.

## `freelancerSort` (type: `string`):

Order of the directory results. Searches past 10,000 freelancers are split by country and rate, so the order then holds within each slice.

## `maxBidsPerProject` (type: `integer`):

Bids mode: read at most this many bids of each project (in Freelancer.com's own ranking order). 0 = all bids. Use e.g. 20 to sample many projects quickly.

## `contestStatus` (type: `string`):

Running contests, or the full contest history newest first.

## `includeDescriptions` (type: `boolean`):

Full project/contest descriptions and freelancer "About me" texts. Switch off for smaller rows (projects then keep a 100-character preview).

## `maxConcurrency` (type: `integer`):

API pages fetched at the same time. 24 is fast and stays inside Freelancer.com's per-IP limits; extra work moves to Apify Proxy IPs automatically.

## `proxyConfiguration` (type: `object`):

Freelancer.com allows each IP about 200 project requests per minute. The run starts on a direct connection and moves extra work to Apify Proxy IPs when that limit is reached, so big runs never stall. Leave as is.

## Actor input object example

```json
{
  "mode": "projects",
  "searchQueries": [
    "python"
  ],
  "skills": [],
  "countries": [],
  "urls": [],
  "maxItems": 100,
  "projectStatus": "open",
  "projectType": "any",
  "minBudgetUsd": 0,
  "maxBudgetUsd": 0,
  "languages": [],
  "projectUpgrades": [],
  "projectSort": "newest",
  "minHourlyRate": 0,
  "maxHourlyRate": 0,
  "minRating": "0",
  "minReviews": 0,
  "onlineOnly": false,
  "freelancerSort": "best",
  "maxBidsPerProject": 0,
  "contestStatus": "active",
  "includeDescriptions": true,
  "maxConcurrency": 24,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

All rows collected in this run.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mode": "projects",
    "searchQueries": [
        "python"
    ],
    "maxItems": 100,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("logiover/freelancer-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "mode": "projects",
    "searchQueries": ["python"],
    "maxItems": 100,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("logiover/freelancer-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "mode": "projects",
  "searchQueries": [
    "python"
  ],
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call logiover/freelancer-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,logiover/freelancer-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/NGIQWe9eBkDMvbhVc/builds/nguQNvVis74k4xO8n/openapi.json
