# freelancermap Projects Scraper (`steadyscrape/freelancermap-projects-scraper`) Actor

Scrape freelancermap IT freelance projects and contract jobs in Germany, Austria, Switzerland and abroad: title, company, skills, contract type, remote %, start, duration, workload, budget, location and full description. Filter by keyword or skill. Export the data to JSON, CSV or Excel, or via API.

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

## Pricing

$1.00 / 1,000 projects

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## freelancermap Projects Scraper

Scrape IT freelance projects from **[freelancermap](https://www.freelancermap.de/projekte)**, one of the largest project boards
for freelancers in Germany, Austria and Switzerland. This freelancermap scraper reads the newest projects of
**freelancermap.de** (Germany, about 12,700 open projects), **freelancermap.at** (Austria), **freelancermap.ch**
(Switzerland) and the English **freelancermap.com** (projects outside the DACH countries), and gives every project with its
**title**, **company**, **contract type** (freelance, employee leasing / ANÜ, permanent), **remote share in %**, **start**,
**duration in months**, **workload**, **budget** when the poster gives one, **city and country**, **industry**, **skills in
English and German** and the **full description**.

Filter by **keyword or skill**, **contract type**, **remote / hybrid / on site**, **minimum remote share**, **city**,
**end-client projects only** and **posted within**, or paste project links. No login, no browser, no proxy. Pay only for the
projects you get.

### What you can do with this freelancermap scraper

- **IT staffing and consulting**: every new SAP, Java, cloud or project-management project in Germany, Austria and
  Switzerland the day it is posted, with its start, duration, remote share and who posted it.
- **Demand and rate research**: which skills, contract types and remote shares the DACH market asks for, week by week.
- **Freelancer project alerts**: schedule it daily with **Posted within** and **Only new projects** and receive only the
  projects posted since the last run — end-client projects only, if agencies are not for you.
- **Lead lists**: the companies and agencies posting projects now, with their freelancermap profile link.

### Input

| Field | What it does |
|---|---|
| `sites` | `de`, `at`, `ch`, `com` — each site publishes its own projects. Default `de`. |
| `keywords` | Keep projects naming one of them as a whole word or phrase in the title, the skills (German or English) or the description: `SAP`, `Java`, `SAP S/4HANA`, `Projektleiter`. |
| `searchInDescription` | Off: a keyword must be in the title or the skills. Default on. |
| `projectUrls` | Project pages to read as they are (`https://www.freelancermap.de/projekt/…`, `https://www.freelancermap.com/project/…`). |
| `contractTypes` | `contracting` (freelance / contract), `employee_leasing` (ANÜ), `permanent_position`. |
| `workplaces` | `remote` (100 %), `hybrid`, `on_site` (0 %), as freelancermap groups them. |
| `minRemotePercent` | At least this share of remote work, e.g. `80`. |
| `locations` | Cities, regions or countries in German or English: `München` or `Munich`, `Wien`, `Zürich`, `Poland`. |
| `onlyEndCustomer` | Only projects posted by the end client ("Endkundenprojekt"), no agencies. |
| `postedWithin` | `any`, `1`, `3`, `7`, `14`, `30` days. |
| `maxProjects` | How many projects to deliver, newest first; `0` for no maximum. Default 100. |
| `onlyNewProjects` | Monitor mode for scheduled runs: skip what an earlier run with the same sites and filters already handled. |

```json
{
    "sites": ["de", "at", "ch"],
    "keywords": ["SAP", "Java", "Python"],
    "contractTypes": ["contracting"],
    "minRemotePercent": 80,
    "postedWithin": "7",
    "maxProjects": 200
}
```

### Output: freelancermap projects data

One row per project, newest first:

```json
{
    "rowType": "project",
    "status": "ok",
    "search": "Newest projects on freelancermap.de",
    "position": 6,
    "projectId": "3064935",
    "url": "https://www.freelancermap.de/projekt/anue-senior-project-manager-product-owner-itsm-m-w-d-gesucht",
    "site": "de",
    "title": "ANÜ: Senior Project Manager / Product Owner ITSM (m/w/d) gesucht!",
    "company": "Computer Futures, ein Geschäftszweig der SThree GmbH",
    "companyUrl": "https://www.freelancermap.de/firma/911-computer-futures-ein-geschaeftszweig-der-sthree-gmbh-experten-verbinden-zukunft-gestalten",
    "companyVerified": false,
    "isEndCustomer": false,
    "contractType": "employee_leasing",
    "remotePercent": 60,
    "workplace": "hybrid",
    "country": "DE",
    "countryName": "Germany",
    "city": "Bonn",
    "locations": ["Bonn"],
    "locationsDe": ["Bonn"],
    "industry": "Defense",
    "skills": ["Certified Scrum Product Owner", "Product Management", "Scrum Methodology", "IT Project Management"],
    "skillsDe": ["Certified Scrum Product Owner", "Produkt Management", "Scrum", "IT-Projektmanagement"],
    "startAsap": false,
    "startMonth": 12,
    "startYear": 2026,
    "startText": null,
    "durationMonths": 18,
    "durationText": null,
    "extensionPossible": true,
    "workloadPercent": 100,
    "budgetAmount": 90000,
    "budgetCurrency": "EUR",
    "description": "Rahmendaten:\n\nStart: 01.12.\nLaufzeit: 18 Monate\nStandort: remote 60% + vor Ort in Bonn 40% …",
    "descriptionHtml": "<div class=\"ql-editor\"><div><strong>Rahmendaten: </strong></div> …",
    "postedAt": "2026-10-25T18:37:32.000Z",
    "updatedAt": "2026-10-25T18:37:32.000Z",
    "expiresAt": "2027-04-25T17:37:32.000Z",
    "applicationsPaused": false,
    "isTopProject": false,
    "matchedKeywords": [],
    "scrapedAt": "2026-10-26T06:35:00.000Z"
}
```

A search or link that gives nothing adds one **free** row with `rowType: "status"`, a `status` (`no_results`, `not_found`,
`invalid`, `blocked`) and a `reason` such as "freelancermap.at lists 1 project posted within the last 1 day, 1 read: 1 with
another contract type." The run's `SUMMARY` record counts the projects listed, the pages read and what each filter left out.

### freelancermap project fields

| Field | Meaning |
|---|---|
| `rowType`, `status` | `project` and `ok` on a project row; a free status row is described above |
| `search`, `position`, `scrapedAt` | the search or link that gave the row, its place in that search, and when it was read |
| `projectId`, `url`, `site` | freelancermap's project id, its page, and the site that lists it |
| `title`, `description`, `descriptionHtml` | as posted; the description as readable text and as HTML |
| `company`, `companyUrl`, `companyVerified` | who posted it and their freelancermap profile (`null` when none is linked) |
| `isEndCustomer` | posted by the end client, not an agency |
| `contractType` | `contracting`, `employee_leasing` or `permanent_position` |
| `remotePercent`, `workplace` | remote share 0–100 and freelancermap's grouping (`remote`, `hybrid`, `on_site`) |
| `country`, `countryName`, `city`, `locations`, `locationsDe` | ISO country, English country name, the city as written, the places freelancermap matched |
| `industry` | in English |
| `skills`, `skillsDe` | the project's skills in English and German |
| `startAsap`, `startMonth`, `startYear`, `startText` | the start: as soon as possible, a month and year, or the text as written |
| `durationMonths`, `durationText`, `extensionPossible` | how long, and whether it can be extended |
| `workloadPercent` | share of a full week (20 = one day a week, 100 = full time); `null` when not given |
| `budgetAmount`, `budgetCurrency` | when the poster enters one (a total or a rate, freelancermap does not say) |
| `postedAt`, `updatedAt`, `expiresAt` | ISO 8601 UTC |
| `applicationsPaused`, `isTopProject` | as freelancermap marks them |
| `matchedKeywords` | which of your keywords the project names |

The poster's first and last name are never collected.

### Pricing

| Event | Price |
|---|---|
| `project` — a project with everything its page gives | US$0.001 |
| Status rows (nothing found, ended project, bad link) | free |

1,000 projects cost US$1. Set a maximum cost per run in Apify and the Actor stops at what it can pay for.

### Limits

- **freelancermap shows visitors only the first page of any search** (the next pages ask to register), so this Actor does
  not use its search. It reads the project list freelancermap publishes for search engines (its sitemaps) newest first,
  opens each project page and applies your filters on its side. A narrow filter therefore reads more pages than it
  delivers: about one German project in five names SAP, Java or Python. **Posted within** shortens the walk.
- Projects come newest first by posting time. With several sites, the projects of one day follow the order of the sites
  you chose.
- Search pages are not accepted as links, for the same reason; paste project pages.
- Two requests a second, one IP, no proxy: 100 projects without filters take about a minute.

### Is it legal to scrape freelancermap?

This Actor reads only public project pages anyone can open without an account, at a gentle pace; freelancermap's
robots.txt allows crawling, and the Actor does not log in or pass any registration wall. It collects project postings, not
freelancer profiles, and leaves out the poster's name. You are responsible for how you use the data and for complying with
the laws and terms that apply to you. This Actor is unofficial and is not affiliated with, endorsed by, or sponsored by
freelancermap or its operator.

# Actor input Schema

## `sites` (type: `array`):

Each site publishes its own projects: freelancermap.de the projects in Germany (about 12,700 open), .at in Austria (about 420), .ch in Switzerland (about 670) and the English .com the projects outside these three countries (about 900). The newest projects come first.

## `keywords` (type: `array`):

Keep only projects that name at least one of these as a whole word or phrase, in German or English: <code>SAP</code>, <code>Java</code>, <code>Python</code>, <code>SAP S/4HANA</code>, <code>Projektleiter</code>, <code>Kubernetes</code>. The title and the project's skills are searched, and the description too unless switched off below. "Java" does not match "JavaScript"; case and accents do not matter. Leave empty for every project.

## `searchInDescription` (type: `boolean`):

Off: a keyword must be in the title or the skills, which leaves out projects that only mention it.

## `projectUrls` (type: `array`):

Project pages to read as they are, such as <code>https://www.freelancermap.de/projekt/…</code> or <code>https://www.freelancermap.com/project/…</code>. Pasted alone, only these links are read; the filters below do not apply to them. Search pages are not taken: freelancermap shows visitors only their first page.

## `contractTypes` (type: `array`):

Keep only projects of these contract types. Empty keeps all.

## `workplaces` (type: `array`):

freelancermap's own grouping of the remote share: Remote is 100 % remote, On site 0 %, Hybrid anything between. Empty keeps all.

## `minRemotePercent` (type: `integer`):

Keep only projects that allow at least this share of remote work, e.g. <code>80</code>. 0 keeps all.

## `locations` (type: `array`):

Keep only projects in one of these cities, regions or countries, in German or English: <code>München</code> or <code>Munich</code>, <code>Frankfurt</code>, <code>Wien</code>, <code>Zürich</code>, <code>Poland</code>. Remote projects name a place too, or the word Remote.

## `onlyEndCustomer` (type: `boolean`):

Keep only projects posted by the end client itself ("Endkundenprojekt"), leaving out agencies and recruiters.

## `postedWithin` (type: `string`):

Keep only projects posted in the last days. A short window also makes the run faster: only the projects posted in it are read.

## `maxProjects` (type: `integer`):

How many projects to deliver, newest first. 0 means no maximum: every project the sites list (inside the date asked) is read.

## `onlyNewProjects` (type: `boolean`):

For scheduled runs: skip projects an earlier run with the same sites and filters already delivered or left out, without reading them again. The memory lives in a key-value store named <code>steadyscrape-freelancermap-projects-state</code> in your account.

## Actor input object example

```json
{
  "sites": [
    "de"
  ],
  "keywords": [
    "SAP",
    "Java",
    "Python"
  ],
  "searchInDescription": true,
  "projectUrls": [],
  "contractTypes": [],
  "workplaces": [],
  "minRemotePercent": 0,
  "locations": [],
  "onlyEndCustomer": false,
  "postedWithin": "any",
  "maxProjects": 10,
  "onlyNewProjects": false
}
```

# Actor output Schema

## `projects` (type: `string`):

No description

## `summary` (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 = {
    "sites": [
        "de"
    ],
    "keywords": [
        "SAP",
        "Java",
        "Python"
    ],
    "maxProjects": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("steadyscrape/freelancermap-projects-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 = {
    "sites": ["de"],
    "keywords": [
        "SAP",
        "Java",
        "Python",
    ],
    "maxProjects": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("steadyscrape/freelancermap-projects-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 '{
  "sites": [
    "de"
  ],
  "keywords": [
    "SAP",
    "Java",
    "Python"
  ],
  "maxProjects": 10
}' |
apify call steadyscrape/freelancermap-projects-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,steadyscrape/freelancermap-projects-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/sBS7e39OKBlkU7hpF/builds/jcyDYLSF6xi863V7n/openapi.json
