# StepStone Scraper - Scrape Jobs in Germany, Austria & Belgium (`s-r/stepstone-scraper`) Actor

Scrape StepStone job postings in Germany (DE), Austria and Belgium. A web scraping dataset with job data per vacancy: title, employer, location, direct job link, posting date and salary. Search by keyword, city or a StepStone URL. No login or API key. For recruiters and labour market research.

- **URL**: https://apify.com/s-r/stepstone-scraper.md
- **Developed by:** [SR](https://apify.com/s-r) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Features:** Limited permissions
- **Stats:** 4 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 run start fees

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

## StepStone Jobs Scraper

StepStone Jobs Scraper is a StepStone scraper that collects public job postings from
StepStone in Germany, Austria and Belgium. Search by job title or keyword, narrow the
search to a city, or provide the search URL you already use. The dataset contains one
row per unique vacancy, with the employer, location, direct job link, posting date and
salary availability. No StepStone account, login or API key is needed, and every row
arrives as structured JSON that you can export to CSV, Excel or your own database.

This actor is useful when you need a structured view of vacancies for recruitment
research, employer monitoring or labour market analysis. A search card gives a quick
view of a vacancy. It does not include the complete description, and this actor does
not open every individual job page. Use the direct links when you need to inspect
those pages yourself.

### StepStone scraper input

Use `query` for a job title or keyword. A German term is usually the natural choice
for the German and Austrian sites. The optional `location` field narrows the search
to a city or region. Leave it empty to search across the selected market. Choose
`de`, `at` or `be` in `market`; the default is Germany.

The following input was used for a real search:

```json
{"query": "data engineer", "limit": 50}
```

You can supply `url` instead of building a search from the other fields. Both absolute
StepStone search URLs and relative search paths work. A supplied URL takes priority
over `query` and `location`. The query remains in the output when you supply both.
Only StepStone URLs for the three supported markets are accepted.

`radius` sets the search radius in kilometres, from zero to 200. Zero leaves the
radius parameter out. `sort` accepts `relevance` or `date`; relevance is the default,
and date asks StepStone to put recent postings first. `limit` controls the maximum
number of delivered vacancies, from one to 500, with a default of 50. `retries`
accepts one to six attempts per page and defaults to three. Keep your search fields
consistent when continuing a larger request.

### What the StepStone scraper returns (output)

Each dataset row keeps the original fields: `job_id`, `title`, `url`, `company`,
`company_url`, `location`, `posted_relative`, `work_from_home`, `salary_text`,
`salary_available_on_page`, `contract_type`, `work_type`, `snippet`, `is_promoted`,
`market`, `query` and `position`. Positions start at one after duplicate vacancies
have been removed. Job identifiers remain text, and unavailable text fields remain
null instead of disappearing.

The output also includes `source`, `platform`, `fetched_at`, `country_code`,
`posted_at`, `salary_min`, `salary_max`, `salary_currency` and `salary_period`.
Timestamps use UTC. The country code identifies the StepStone site being read,
including when an absolute URL refers to another supported market. `location`
remains the source's text and may name several cities. It is not converted into
a guessed city or postcode.

Here is one actual row from the real data-engineer search:

```json
{
  "job_id": "14439627",
  "title": "Requirements- & Data-Engineer*",
  "url": "https://www.stepstone.de/stellenangebote--Requirements-Data-Engineer-Koeln-Wuppertal-BarmeniaGothaer--14439627-inline.html",
  "company": "BarmeniaGothaer",
  "company_url": "https://www.stepstone.de/cmp/de/barmeniagothaer-29978/jobs",
  "location": "Köln, Wuppertal",
  "posted_relative": "vor 1 Tag",
  "work_from_home": false,
  "salary_text": null,
  "salary_available_on_page": true,
  "contract_type": null,
  "work_type": null,
  "snippet": "Bei uns zählt, wer du bist. Mit all deinen Fähigkeiten, Ideen und Möglichkeiten. In der IT der BarmeniaGothaer entwickelst du Plattformen und Lösungen, die Kund*innen und Kolleg*innen spürbar weiterbringen. Du verbindest Menschen und Technologien. Mit Rückhalt in einem Team aus 7.500 Kolleg*innen u",
  "is_promoted": false,
  "market": "de",
  "query": "data engineer",
  "position": 1,
  "source": "stepstone-scraper",
  "platform": "stepstone",
  "fetched_at": "2026-10-03T16:27:50.515Z",
  "country_code": "DE",
  "posted_at": "2026-10-01T06:40:54Z",
  "salary_min": null,
  "salary_max": null,
  "salary_currency": null,
  "salary_period": null
}
```

`snippet` is the visible search-card excerpt, rather than the full vacancy description.
`posted_relative` keeps StepStone's local wording, while `posted_at` uses the available
structured posting date. The two fields serve different purposes: the relative text
is easy to display, and the UTC timestamp is useful for sorting and comparison.

### Salary availability

StepStone often offers a salary estimate behind a show-salary control without printing
the amount on the search card. `salary_available_on_page` indicates that control is
present. It does not promise that this actor has retrieved an amount. `salary_text`
can therefore remain null while salary availability is true. Structured salary amounts
are included only when the page actually supplies them. Missing amounts are never
estimated from a job title, employer name or free-form text.

### Use cases for a StepStone scraper

- **Recruitment research.** See which employers are hiring for a role in a city, how
  many of those vacancies are promoted placements and which postings offer remote work.
- **Employer monitoring.** Run the same search daily with `sort` set to `date` and keep
  the new `job_id` values. You see when a competitor or client starts hiring for a role.
- **Labour market analysis.** Compare demand for a job title between Germany, Austria
  and Belgium, or between cities in one market, using the same fields for every row.
- **Job boards and aggregators.** Feed vacancy titles, employers and direct links into
  your own index, and send readers to the original StepStone page for the full text.
- **Salary research.** Use `salary_available_on_page` and the structured salary fields
  to see which postings expose pay information and which do not.

For a recurring monitor, deduplicate across runs with `job_id`; the actor removes
duplicates within one run only. Results change as StepStone adds, updates or removes
listings, so a later run of the same search can return a different set.

### StepStone scraper compared with the alternatives

StepStone's official API is aimed at employers, agencies and applicant tracking systems
that publish vacancies and receive applications. It is not a public search feed, so it
does not give you other employers' vacancies for a keyword and city. Copying results
by hand or with a browser extension works for a single page but does not scale to
hundreds of vacancies or daily monitoring. Open-source scripts need your own maintenance
when the site changes. This actor runs in the Apify platform, accepts the same search
you would type on StepStone, and returns a stable set of fields in every row. You can
schedule it, call it from the Apify API, or connect it to integrations such as Google
Sheets, Make or Zapier.

### Pricing

The existing pay-per-event price is $0.0005 for `run_start`, once per run, and $0.00175
for each delivered vacancy through the `job` event. A run that returns no vacancies
has no job charges; the existing start fee still applies. Duplicate vacancies are
removed before delivery and are charged only once. Results are delivered before their
job events are charged.

Users without a paid Apify plan receive at most ten vacancies per run. The run output
reports the free-plan cap and whether it applied. Paid users retain the requested
limit up to 500. This limit applies to delivered vacancies, rather than to the number
of pages the search says are available.

### Run summary and errors

The key-value store contains a `summary` record with delivered item and error counts.
Successful searches also report pages requested, pages served, jobs returned, vacancies
with links, salary availability and elapsed collection time. If some pages fail,
available vacancies are retained and the `errors` record describes the failed pages.
An unavailable source or empty search produces a successful empty actor run. A missing
query and missing URL also give a readable input error instead of invented results.

### Frequently asked questions

#### Which countries are supported?

Germany, Austria and Belgium, using their respective StepStone sites. The selected
market controls a constructed search. An absolute URL selects its own supported site.

#### Does the actor collect complete job descriptions?

It collects search cards and their excerpts. The `url` field links to the complete
vacancy, but fetching its detail page is outside this actor's scope.

#### Why are there fewer vacancies than the limit?

The limit is a maximum. The search may contain fewer unique vacancies, some cards can
repeat between pages, and temporarily unavailable pages may leave partial results.
The summary and errors let you distinguish these cases.

#### Can I combine job data across sources?

Use the source, platform, job identifier and timestamps as stable context. Employer
and location text can help research, but neither is a guaranteed company identifier.
Keep multi-city locations intact instead of treating them as a single address.

#### Is there an official StepStone API for job search?

StepStone offers interfaces for employers and partners who post vacancies. They are not
meant for searching other employers' job postings. This StepStone scraper fills that gap
with the public search results.

#### Can I export StepStone jobs to CSV or Excel?

Yes. The dataset can be downloaded as JSON, CSV, Excel, XML or HTML from the run page,
or fetched through the Apify API in any of those formats.

# Actor input Schema

## `query` (type: `string`):

Job title or keyword. German terms work best on the German and Austrian sites.

## `location` (type: `string`):

City or region, for example Berlin or Wien. Leave empty to search the whole market.

## `market` (type: `string`):

Which StepStone site to read.

## `url` (type: `string`):

A StepStone search URL to read instead of building one from the fields above. Paste it from your browser after applying filters.

## `radius` (type: `integer`):

Search radius around the location.

## `sort` (type: `string`):

Relevance is StepStone's default. Date puts the newest first.

## `limit` (type: `integer`):

How many jobs to return, 1 to 500. A page carries 25.

## `retries` (type: `integer`):

Retry attempts per page. StepStone was measured as an open target, so this rarely matters.

## Actor input object example

```json
{
  "query": "data engineer",
  "location": "Berlin",
  "market": "de",
  "url": "https://www.stepstone.de/jobs/data-engineer/in-berlin",
  "sort": "relevance",
  "limit": 50,
  "retries": 3
}
```

# Actor output Schema

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

One row per job posting.

## `summary` (type: `string`):

Pages served, jobs returned, and how salary information was available.

## `errors` (type: `string`):

Per-page failures with a code and a redacted message.

# 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 = {
    "query": "data engineer",
    "limit": 50,
    "retries": 3
};

// Run the Actor and wait for it to finish
const run = await client.actor("s-r/stepstone-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 = {
    "query": "data engineer",
    "limit": 50,
    "retries": 3,
}

# Run the Actor and wait for it to finish
run = client.actor("s-r/stepstone-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 '{
  "query": "data engineer",
  "limit": 50,
  "retries": 3
}' |
apify call s-r/stepstone-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,s-r/stepstone-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/8NeRAX9KNnbFah9ZX/builds/U2rtsGOYTfjCqQ9LS/openapi.json
