# ProUnity Scraper — Belgian Freelance Missions & Consulting Jobs (`studio-amba/prounity-scraper`) Actor

Scrape freelance missions, consulting assignments, and job listings from ProUnity (pro-unity.com) — Belgium's largest freelance talent marketplace with 3,200+ missions per year.

- **URL**: https://apify.com/studio-amba/prounity-scraper.md
- **Developed by:** [Studio Amba](https://apify.com/studio-amba) (community)
- **Categories:** Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## ProUnity Scraper

Scrape freelance missions, consulting assignments, and IT job listings from ProUnity (pro-unity.com) -- Belgium's largest freelance talent marketplace connecting 3,200+ specialists with major companies across the Benelux region every year.

### How to scrape ProUnity data

ProUnity is a Vendor Management System (VMS) and freelance marketplace used by large Belgian enterprises and government agencies to source external IT consultants, business analysts, project managers, and other specialists. Missions are typically 3-12 month consulting engagements at organizations like SMALS, BNP Paribas Fortis, Belgian federal services, and major telcos.

This actor extracts structured mission data from publicly available ProUnity job listings. It discovers missions through two channels:

1. **Sitemap crawling** -- parses the XML sitemaps to discover all published mission URLs (5,000+ historical listings across multiple sitemap files)
2. **Listing page** -- scrapes the `/freelance-missions/` page for the ~45 most recently posted missions

Each mission detail page is then scraped for title, company, location, duration, dates, skills with proficiency levels, language requirements, and full description text.

#### Use cases

- **Freelance consultants** tracking new missions matching their skill set
- **Recruitment agencies** monitoring the Belgian consulting market
- **HR analytics** benchmarking skill demand and contract durations
- **Market researchers** analyzing Benelux IT staffing trends
- **Competitors** tracking which companies are hiring and for what roles

### Input

| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `searchQuery` | String | No | `""` | Filter missions by keyword (e.g., `"Java developer"`, `"SAP"`, `"project manager"`). Matches against title, company, description, and skills. Leave empty to scrape all. |
| `maxResults` | Integer | No | `100` | Maximum number of mission listings to return. The site has 1,000+ active missions at any time. |
| `language` | String | No | `"en"` | Preferred site language (`en`, `fr`, `nl`). Note: mission content language depends on the posting itself. |
| `proxyConfiguration` | Object | No | Auto | Proxy settings. Belgian residential proxies recommended for reliability. |

#### Example input

```json
{
    "searchQuery": "Java",
    "maxResults": 50,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "BE"
    }
}
````

### Output

Each result contains complete mission details:

| Field | Type | Example |
|-------|------|---------|
| `title` | String | `"Fullstack Java developper Senior"` |
| `referenceId` | String | `"K09931"` or UUID |
| `company` | String | `"SMALS"` |
| `location` | String | `"Brussels"` |
| `country` | String | `"Belgium"` |
| `duration` | String | `"6 months"` |
| `startDate` | String | `"2026-06-10"` |
| `endDate` | String | `"2026-12-31"` |
| `description` | String | Full mission description text |
| `skills` | Array | `[{"name": "Java", "level": "Expert"}, {"name": "Spring Boot", "level": "Confirmed"}]` |
| `languages` | Array | `[{"name": "French", "level": "Active knowledge"}, {"name": "Dutch", "level": "Active knowledge"}]` |
| `domain` | String | `"IT"` or `"Finance"` |
| `experienceLevel` | String | `"Senior"` |
| `remoteWork` | String | `"Hybrid"`, `"Remote"`, or `"On-site"` |
| `url` | String | Full mission detail page URL |
| `scrapedAt` | String | ISO 8601 timestamp |

#### Example output

```json
{
    "title": "Fullstack Java developper Senior",
    "referenceId": "K09931",
    "company": "SMALS",
    "location": "Brussels",
    "country": "Belgium",
    "duration": "6 months",
    "startDate": "2026-06-10",
    "endDate": "2026-12-31",
    "description": "We are looking for a senior Java developer to modernize legacy systems within a complex technological environment combining historical applications and modern components...",
    "skills": [
        { "name": "Java", "level": "Expert" },
        { "name": "Spring Boot", "level": "Expert" },
        { "name": "Angular", "level": "Confirmed" },
        { "name": "Docker", "level": "Confirmed" },
        { "name": "REST APIs", "level": "Expert" }
    ],
    "languages": [
        { "name": "French", "level": "Active knowledge" },
        { "name": "Dutch", "level": "Active knowledge" },
        { "name": "English", "level": "Active knowledge" }
    ],
    "domain": "IT",
    "experienceLevel": "Senior",
    "remoteWork": "Hybrid",
    "url": "https://www.pro-unity.com/job/1d09b541-e62b-496f-a221-b7119fd34737/",
    "scrapedAt": "2026-06-01T14:30:00.000Z"
}
```

### How it works

1. **Discovery phase** -- The actor reads the ProUnity XML sitemap index to find all job sitemap files, plus scrapes the listing page for the latest missions
2. **Deduplication** -- URLs are deduplicated so each mission is only scraped once
3. **Detail scraping** -- Each mission detail page is fetched and parsed using CheerioCrawler (fast HTTP-only, no browser needed)
4. **Filtering** -- If a `searchQuery` is provided, missions are matched against title, company, description, location, and skills
5. **Validation** -- Output is validated for required fields before the actor exits

### Cost estimate

This actor uses CheerioCrawler (HTTP-only, no browser), making it very efficient:

- **~50 results per $0.10** of Apify compute credits
- A full run of 100 missions typically takes 1-2 minutes
- Sitemap discovery adds minimal overhead (a few XML requests)

### Tips

- **Start with a small run** (`maxResults: 20`) to verify the output matches your needs
- **Use search queries** to narrow results -- the filter matches against title, company, description, and skills
- **Belgian residential proxies** work best since ProUnity is a Belgian platform
- **Schedule regular runs** to track new missions as they are posted (ProUnity adds missions daily)
- **Skills data is structured** -- each skill includes a proficiency level (Expert, Advanced, Confirmed, Junior), making it easy to filter programmatically

### Limitations

- **No rate/salary data** -- ProUnity does not publicly display day rates or salary information on mission pages
- **Company names** may not always be extracted if the posting uses a logo instead of text
- **Historical missions** in the sitemap may have expired or been filled; the actor scrapes whatever is publicly available
- **WordPress-based** -- the site uses a WordPress theme (Avada) with custom job post types; structural changes may require scraper updates
- **Language mix** -- mission descriptions are posted in the language chosen by the client (French, Dutch, or English), regardless of the `language` input setting

# Actor input Schema

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

Filter missions by keyword (e.g., 'Java developer', 'project manager', 'SAP consultant'). Leave empty to scrape all available missions.

## `maxResults` (type: `integer`):

Maximum number of mission listings to return.

## `language` (type: `string`):

Preferred language for the site (en, fr, nl). Note: Mission content language depends on the posting, not this setting.

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

Proxy settings. Belgian residential proxies recommended for best reliability.

## Actor input object example

```json
{
  "searchQuery": "developer",
  "maxResults": 20,
  "language": "en",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "BE"
  }
}
```

# 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 = {
    "searchQuery": "developer",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "BE"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/prounity-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 = {
    "searchQuery": "developer",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "BE",
    },
}

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

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

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

```

## CLI example

```bash
echo '{
  "searchQuery": "developer",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "BE"
  }
}' |
apify call studio-amba/prounity-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=studio-amba/prounity-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "ProUnity Scraper — Belgian Freelance Missions & Consulting Jobs",
        "description": "Scrape freelance missions, consulting assignments, and job listings from ProUnity (pro-unity.com) — Belgium's largest freelance talent marketplace with 3,200+ missions per year.",
        "version": "0.1",
        "x-build-id": "3gtzLqvRIgAeh3Mek"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/studio-amba~prounity-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-studio-amba-prounity-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/studio-amba~prounity-scraper/runs": {
            "post": {
                "operationId": "runs-sync-studio-amba-prounity-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/studio-amba~prounity-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-studio-amba-prounity-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "searchQuery": {
                        "title": "Search Query",
                        "type": "string",
                        "description": "Filter missions by keyword (e.g., 'Java developer', 'project manager', 'SAP consultant'). Leave empty to scrape all available missions."
                    },
                    "maxResults": {
                        "title": "Max Results",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Maximum number of mission listings to return.",
                        "default": 100
                    },
                    "language": {
                        "title": "Language",
                        "enum": [
                            "en",
                            "fr",
                            "nl"
                        ],
                        "type": "string",
                        "description": "Preferred language for the site (en, fr, nl). Note: Mission content language depends on the posting, not this setting.",
                        "default": "en"
                    },
                    "proxyConfiguration": {
                        "title": "Proxy Configuration",
                        "type": "object",
                        "description": "Proxy settings. Belgian residential proxies recommended for best reliability."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
