# Contra Scraper \[💰$5/1K] | Freelancer Rates | Portfolios (`ahmed_jasarevic/contra-scraper`) Actor

Scrape detailed freelance profiles from contra.com — hourly rates, skills, ratings, availability, portfolio projects and social links. Discover talent by profile URL or keyword.

- **URL**: https://apify.com/ahmed\_jasarevic/contra-scraper.md
- **Developed by:** [Ahmed Jasarevic](https://apify.com/ahmed_jasarevic) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.70 / 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

## Contra Scraper

**Scrape detailed freelance profiles from [contra.com](https://contra.com) — the commission-free freelance marketplace — for talent research, rate benchmarking and lead generation.** Extract hourly rates, skills, client ratings, availability, portfolio projects and contact-ready social links in clean JSON.

This is the **only dedicated Contra.com profile scraper in the Apify Store**. It runs entirely over plain HTTP (no browser): it reads the server-rendered Relay data embedded in each profile page and enriches it with Contra's internal GraphQL API — fast, cheap and no API key required.

### Freelance Talent Use Cases

- **Freelance rate benchmarking** — compare hourly rates and rates-per-project across disciplines, roles and locations (design, development, writing, marketing, video and more)
- **Talent research & recruiting** — screen independents by skill, role, rating, availability and location before outreach
- **Freelance talent database building** — assemble a structured dataset of independents with skills, rates, ratings and portfolio links for staffing or reselling
- **Market research on the freelance economy** — analyze headcount, rates and in-demand skills on a commission-free platform
- **Competitor / agency intelligence** — monitor independent worker profiles for agencies and hiring platforms

### How It Works

Provide `profileUrls` (direct profile links), or let the actor discover profiles automatically via `searchQuery` / `searchRoles` / `searchTools`. Every profile page embeds a server-rendered Relay data blob (the same JSON the site's own frontend hydrates from); the actor parses it and replays Contra's internal GraphQL persisted queries to fill in the fields that are only loaded client-side (bio, minimum hourly rate, productized services, work experience). Everything is written to your Apify dataset as clean JSON.

### Build a Freelance Talent Database Without API Keys

Contra's public read-only API (X-API-Key) exists but is limited. This actor doesn't need it: it reads the embedded Relay profile store plus the internal GraphQL persisted queries directly, so you get **profile details, availability, ratings, portfolio and productized services** out of the box — no API keys, no browser, no CAPTCHAs.

### Input

| Field | Type | Required | Default | Notes |
| --- | --- | --- | --- | --- |
| `profileUrls` | array | – | \[] | Direct Contra profile URLs, e.g. `https://contra.com/username`. Mutually exclusive with discovery params. |
| `searchQuery` | string | – | — | Keyword search over profiles: title, role, skills, tools. |
| `searchRoles` | array | – | \[] | Filter by role names, e.g. `["Web Developer", "Product Designer"]`. Use individual role names (comma-separated text supported). |
| `searchTools` | array | – | \[] | Filter by tools, e.g. `["Figma", "React"]` (comma-separated text also supported). |
| `minRateUsd` | integer | – | – | Minimum hourly rate filter. |
| `maxRateUsd` | integer | – | – | Maximum hourly rate filter. |
| `availableOnly` | boolean | – | false | Only profiles marked as available for work (requires `searchQuery`). |
| `maxItems` | integer | – | 50 | Maximum number of profiles to export (max 1000). |
| `proxy` | object | – | off | Optional; usually not needed. |

#### Example Input

```json
{
    "searchQuery": "React developer",
    "maxRateUsd": 100,
    "availableOnly": true,
    "maxItems": 200
}
```

### Output

One dataset row per freelancer profile, with profile details where exposed by Contra's Public API.

| Field | Description |
| --- | --- |
| `username` / `url` | Profile handle and URL |
| `name` | Display name |
| `headline` / `professionalTitle` | Profile headline |
| `hourlyRate` | Rate (per hour or per project) |
| `skills` | Skills list |
| `location` | Location string |
| `bio` | Profile bio |
| `availability` | Availability status |
| `rating` / `reviewCount` | Client rating and number of reviews |
| `followerCount` / `hiredCount` | Social proof counts |
| `platformEarningsBadge` | Earnings badge (`$1+` … `$10K+` etc.) |
| `portfolioProjects` | Portfolio items (title, description, media) |
| `productizedServices` | Services with price points |
| `workExperience` | Work history |
| `socialLinks` | GitHub/LinkedIn/etc. links |
| `avatarUrl` | Avatar image URL |

#### Example Output

```json
{
    "username": "janedoe",
    "url": "https://contra.com/janedoe",
    "name": "Jane Doe",
    "headline": "Senior Product Designer",
    "hourlyRate": 85,
    "skills": ["Figma", "UI Design", "Design Systems"],
    "location": "Lisbon, Portugal",
    "bio": "I design SaaS products for early-stage startups.",
    "availability": true,
    "rating": 4.9,
    "reviewCount": 23,
    "platformEarningsBadge": "$5K+",
    "portfolioProjects": [{ "title": "Fintech dashboard", "media": ["https://…"] }],
    "socialLinks": ["https://linkedin.com/in/janedoe"]
}
```

Download the dataset as **JSON, HTML, CSV or Excel**, or pull it via the Apify API.

### Integrations & Automation

Use the actor's **API endpoint** from your CRM or scripts, trigger **webhooks** when a run finishes, or wire it into **Zapier / Make** via Apify integrations. For periodic market research, schedule a **weekly "top freelancers by skill" run** — recurring runs keep your talent dataset current.

### Related Actors

- [Upwork Freelancers Scraper](https://apify.com/parseforge/upwork-freelancers-scraper) — Upwork's largest freelancer-profile actor, same use cases
- [Upwork Talent Scraper — Freelancers, Rates & Earnings](https://apify.com/bovi/upwork-talent-scraper) — Upwork rates and lifetime earnings
- [Upwork Freelancer & Talent Scraper](https://apify.com/parseforge/upwork-scraper) — Upwork profile export

### FAQ

#### Why use this actor instead of Contra's official API?

Contra does have a **Public API** (X-API-Key) and even a hosted **MCP server** (`https://contra.com/mcp`) for AI agents — but access requires requesting a free API key, and the API is **read-only and limited** (programs, filters, expert profiles). This actor needs **no API key**: it reads the server-rendered Relay data embedded in each profile page and enriches it via Contra's internal GraphQL persisted queries, so you get more profiles per run, headlessly, with no setup on Apify.

#### Is Contra commission-free?

Yes — that's Contra's core differentiator: it takes **0% commission**, billing flat plans instead (typically €9–25/month for clients). Freelancers keep 100% of what they earn. Rate data scraped from profiles therefore reflects full rates, not commission-adjusted ones.

#### What are alternatives to this actor for freelance data?

The main alternatives are **Upwork scrapers** (see Related Actors). For Contra specifically, no other dedicated scraper exists in the Apify Store at the time of writing — this is the only one.

#### Can the actor find profiles automatically without URLs?

Yes. Use `searchQuery` (e.g. "React developer") and optionally filter by `searchRoles`, `searchTools`, `minRateUsd`/`maxRateUsd`, or `availableOnly`. Direct `profileUrls` are preferred when you have a specific target list.

#### Does the actor return profile details or only search results?

The output profile data comes in two tiers: basic profile fields (name, headline, skills, hourly rate, location, rating, counts) are always present; **details** (bio, portfolio projects, productized services, work experience) are fetched via Contra's internal GraphQL persisted queries, which return them for profiles that expose them. Profiles that are "under construction" may have mostly null fields; discover search additionally returns only the first page of results (8 profiles) per query.

#### Is scraping contra.com legal?

Web scraping operates in a legal gray area. This actor reads only publicly available profile pages/API responses. You are responsible for complying with contra.com's Terms of Service and applicable law (including GDPR when storing personal data such as names, bios and rates).

### For AI Agents & LLM Apps

**Purpose:** Returns structured freelance profiles from contra.com — headline, hourly rate, skills, location, rating, availability, portfolio, social links — from direct URLs or keyword search.

**Minimal input (search mode):**

```json
{ "searchQuery": "React developer", "maxItems": 50 }
```

**Minimal input (direct URLs):**

```json
{ "profileUrls": [{ "url": "https://contra.com/username" }] }
```

**Output fields:** `username`, `url`, `name`, `headline`, `professionalTitle`, `skills`, `hourlyRate`, `location`, `bio`, `availability`, `rating`, `reviewCount`, `followerCount`, `hiredCount`, `platformEarningsBadge`, `canReceiveInquiries`, `portfolioProjects`, `productizedServices`, `workExperience`, `socialLinks`, `avatarUrl`.

**Behaviors an agent should know:**

- `profileUrls` and discovery params (`searchQuery`, `searchRoles`, `searchTools`) are mutually exclusive — supplying URLs takes precedence.
- `availableOnly` requires `searchQuery` to be set; it is ignored otherwise.
- `searchRoles`/`searchTools` accept either arrays of names or a comma-separated string per field.
- `maxItems` caps billing (default 50, max 1000).
- Discover search returns only the first page of results (8 profiles) per query; for full coverage, re-run with the collected profile URLs.
- Profile details (bio, portfolio, services) come from Contra's internal GraphQL API — profiles "under construction" may return mostly null fields.
- **Billing (pay-per-result):** $0.005 per profile + $0.00005 actor start.

### SEO Keywords

contra scraper, contra.com scraper, freelance profile scraper, freelance talent database, freelance rate benchmarking, upwork alternative data, freelance market research, independent contractor profiles, hire freelancers data, contra api alternative, freelance hourly rates, product designer rates, freelance skills data, commission-free freelance platform, talent acquisition data, freelancer lead generation, contra mcp, freelance portfolio data, remote freelancers database, contractor rate data

### Legal & Compliance Disclaimer

This actor is an independent tool and is **not affiliated with, endorsed by, or sponsored by Contra** (contra.com).

It accesses only **publicly available profile pages and Contra's public API endpoints** — no login bypass, no CAPTCHA solving, no credentials.

Users are responsible for their own compliance with contra.com's Terms of Service and applicable data-protection law (GDPR applies to profiles of private individuals). Output includes personal data (names, bios, rates, locations) that should not be used for unsolicited commercial outreach in violation of applicable law (e.g. GDPR, CAN-SPAM). This section is informational, not legal advice.

# Actor input Schema

## `profileUrls` (type: `array`):

Contra.com profile URLs (e.g. https://contra.com/ivan\_wong\_9207) or bare usernames (e.g. ivan\_wong\_9207).

## `searchQuery` (type: `string`):

Optional. When set (and no profileUrls given), the actor runs a discover search on Contra and scrapes the resulting profiles. E.g. "product designer".

## `searchRoles` (type: `array`):

Optional. Filter discover results by role names, e.g. \["Product Designer"]. Only used in search mode.

## `searchTools` (type: `array`):

Optional. Filter discover results by tool names, e.g. \["Figma"]. Only used in search mode.

## `minRateUsd` (type: `integer`):

Optional. Filter discover results by minimum hourly rate. Only used in search mode.

## `maxRateUsd` (type: `integer`):

Optional. Filter discover results by maximum hourly rate. Only used in search mode.

## `availableOnly` (type: `boolean`):

Optional. Only return independents who are currently available for work. Only used in search mode.

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

Maximum number of profiles to scrape.

## `proxy` (type: `object`):

Select proxies to be used by your crawler.

## Actor input object example

```json
{
  "profileUrls": [
    "https://contra.com/ivan_wong_9207",
    "https://contra.com/oleksandra_marchenko"
  ],
  "searchRoles": [],
  "searchTools": [],
  "availableOnly": false,
  "maxItems": 50,
  "proxy": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

No description

# 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 = {
    "profileUrls": [
        "https://contra.com/ivan_wong_9207",
        "https://contra.com/oleksandra_marchenko"
    ],
    "searchQuery": "",
    "searchRoles": [],
    "searchTools": [],
    "proxy": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("ahmed_jasarevic/contra-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 = {
    "profileUrls": [
        "https://contra.com/ivan_wong_9207",
        "https://contra.com/oleksandra_marchenko",
    ],
    "searchQuery": "",
    "searchRoles": [],
    "searchTools": [],
    "proxy": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("ahmed_jasarevic/contra-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 '{
  "profileUrls": [
    "https://contra.com/ivan_wong_9207",
    "https://contra.com/oleksandra_marchenko"
  ],
  "searchQuery": "",
  "searchRoles": [],
  "searchTools": [],
  "proxy": {
    "useApifyProxy": false
  }
}' |
apify call ahmed_jasarevic/contra-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ahmed_jasarevic/contra-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/vp3z3JCMvIyXg1POR/builds/XWWIpqfXqcEjyoW7A/openapi.json
