# Stepstone Jobs Scraper - Stepstone, Totaljobs, IrishJobs, Pnet (`datasignalslab/stepstone-jobs-scraper`) Actor

Scrape job listings from 14 job boards of the Stepstone group: Stepstone Germany, Austria, Belgium, Netherlands, Totaljobs, CWJobs, Caterer, IrishJobs, Pnet and more. Optional full job description. From $1 per 1,000 jobs, no login, no proxy setup.

- **URL**: https://apify.com/datasignalslab/stepstone-jobs-scraper.md
- **Developed by:** [DataSignals Lab](https://apify.com/datasignalslab) (community)
- **Categories:** Jobs, Lead generation, AI
- **Stats:** 3 total users, 2 monthly users, 84.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 job returneds

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: 14 job boards of the Stepstone group, with full descriptions

Get the job listings behind any search on Stepstone and its sister job boards as clean JSON: title, company, location, posting date, home office flag, teaser and benefits. Tick one box to add the full job description, employment type, closing date, industry and address. Search by keyword and city, or set your filters on the site in the browser and paste the URL of the result page.

One Actor, one schema, 14 job boards in 7 countries: Germany, Austria, Belgium, Netherlands, United Kingdom, Ireland and South Africa.

No login, no API key, no proxy setup: the residential proxy these sites require is built in and included in the price.

**Run it with the default input to see it work.** It returns Python jobs in Berlin from stepstone.de.

### Supported job boards

| `site` | job board |
|---|---|
| `stepstone.de` | Stepstone Germany |
| `stepstone.at` | Stepstone Austria |
| `stepstone.be` | Stepstone Belgium |
| `stepstone.nl` | Stepstone Netherlands |
| `totaljobs.com` | Totaljobs UK |
| `cwjobs.co.uk` | CWJobs UK, IT jobs |
| `caterer.com` | Caterer UK, hospitality |
| `careerstructure.com` | CareerStructure UK, construction |
| `retailchoice.com` | RetailChoice UK, retail |
| `catererglobal.com` | Caterer Global, international hospitality |
| `nijobs.com` | NIJobs Northern Ireland |
| `irishjobs.ie` | IrishJobs Ireland |
| `jobs.ie` | Jobs.ie Ireland |
| `pnet.co.za` | Pnet South Africa |

### What you get

One row per job:

| field | meaning |
|---|---|
| `job_id` | the site's id, stable across runs, use it with `site` to detect new jobs |
| `title`, `company` | job title and employer, `company` is empty for anonymous listings |
| `company_id`, `company_url`, `company_logo` | employer id, employer page and logo |
| `location`, `postal_code` | city or cities as posted |
| `home_office` | `hybrid`, `remote`, or empty when the listing has no home office flag |
| `date_posted` | ISO 8601 timestamp |
| `snippet`, `benefits` | the teaser text and the benefits block from the result list |
| `salary`, `salary_min`, `salary_max`, `salary_currency`, `salary_period` | filled when the site publishes a salary, which is common on the UK boards and rare on the German ones |
| `match_type` | `exact` for a direct hit, `related` for the jobs the site appends after the exact hits |
| `is_sponsored` | true for sponsored and top job placements |
| `url`, `site`, `country`, `search_url` | link, job board, country code and the search the job came from |

With `includeDescription` each row also gets:

| field | meaning |
|---|---|
| `description` | the full job description as plain text |
| `employment_type` | `FULL_TIME`, `PART_TIME` and similar |
| `valid_through` | closing date of the listing |
| `industry` | industry as the site labels it |
| `city`, `street_address`, `latitude`, `longitude` | the job address |

Example row, with the description shortened here:

```json
{
  "job_id": "107890395",
  "title": "Python Developer with Data experience",
  "company": "Hackajob Ltd",
  "company_id": "1461528",
  "company_url": "https://www.cwjobs.co.uk/jobs/hackajob-ltd?cmpId=1461528&cmp=1",
  "company_logo": "https://tjgliveassets.s3.eu-west-1.amazonaws.com/company-logos/01a731a76abe4ee4b5f58b72600d5a61.png",
  "location": "London",
  "postal_code": null,
  "home_office": null,
  "date_posted": "2026-08-24T13:49:35.167Z",
  "salary": "Competitive",
  "salary_min": null,
  "salary_max": null,
  "salary_currency": null,
  "salary_period": null,
  "snippet": "Our client is a digital and technology consultancy.About Us: Our client, part of our client, is a technology consultancy and digital transformation partner that helps organisations solve complex chall",
  "benefits": null,
  "skills": null,
  "match_type": "exact",
  "is_sponsored": false,
  "url": "https://www.totaljobs.com/job/python-developer/hackajob-ltd-job107890395",
  "site": "cwjobs.co.uk",
  "country": "gb",
  "search_url": "https://www.cwjobs.co.uk/jobs/python/in-london",
  "description": "Our client is a digital and technology consultancy.\nAbout Us:\nOur client, part of our client, is a technology consultancy and digital transformation partner that helps organisations solve complex challenges through strategy, design, engineering, and delivery.\nWe work closely with our clients to deliver secure, accessible, user-focused services that evolve with their needs. By combining deep",
  "employment_type": "FULL_TIME",
  "valid_through": "2026-10-05T12:49:35.167Z",
  "industry": "IT, IT-Software Development",
  "city": "City of London",
  "street_address": null,
  "latitude": null,
  "longitude": null
}
```

### Input

| field | what it does |
|---|---|
| `site` | the job board, see the table above. Default `stepstone.de` |
| `queries` | search terms, one search per line |
| `location` | city or region, optional |
| `includeDescription` | add the full description and the detail fields |
| `startUrls` | search URLs of any supported job board, used in addition to the search terms |
| `sort` | `relevance` (default) or `date` for newest first |
| `postedWithinDays` | `"1"`, `"3"` or `"7"` to keep only recent jobs, default `"any"` |
| `exactMatchesOnly` | drop the related jobs the site appends |
| `maxJobsPerSearch` | cap per search, default 100 |
| `maxJobs` | hard stop across the run, also your budget cap |

Minimal input:

```json
{ "site": "totaljobs.com", "queries": ["data engineer", "python"], "location": "London", "sort": "date", "postedWithinDays": "7", "includeDescription": true }
```

To search several job boards in one run, paste one search URL per board in `startUrls`.

### Pricing

Pay per result, two events:

- **$1 per 1,000 jobs** for every job row in the dataset.
- **$4 per 1,000 descriptions** on top, only with `includeDescription` and only for rows where the description was actually retrieved.

A job with its full description costs $0.005. Searches that fail cost nothing. Apify's free monthly credit covers thousands of jobs, so you can evaluate without paying.

#### Subscriptions and shared agent access

Scored signals from SEC, FDA, Congress and other official filings. The daily output is hashed and anchored, so past signals cannot be edited. Agents call it over MCP. [See the track record](https://datasignalslab.com/proof.html)

Every score in every report lists the terms it was built from, so you can check the number instead of trusting it.

This Actor is part of [DataSignals Lab](https://datasignalslab.com). It does not feed the signal reports. The plans below cover those and the shared MCP access. All prices are listed on the [pricing page](https://datasignalslab.com/pricing.html):

- **Free.** Report previews, a weekly signal digest and 50 free MCP calls per month for AI agents.
- **Snapshot, $19 one time.** The current edition of one report plus 30 days of updates.
- **DataSignals Pro, $29 per month or $290 per year.** All three reports refreshed monthly, MCP access for AI agents (2000 calls per month fair use), email alerts. Cancel anytime.

### Who uses this

- Recruiters and staffing agencies tracking which companies hire for a role in a city.
- Sales teams using fresh job posts as a buying signal: a company hiring five SAP consultants has a project.
- Labour market researchers who need a daily count per role and region, across countries in one schema.
- Job boards and aggregators covering the German, UK, Irish or South African market.
- AI agents that answer "who is hiring data engineers in Munich this week" from live data.

Need jobs straight from company career sites instead of a job board? See [Job Search API](https://apify.com/datasignalslab/job-search-api). For Indeed see [Indeed Jobs Scraper](https://apify.com/datasignalslab/indeed-jobs-scraper).

### Limits and honesty

- The sites block some requests. Every page is tried three times. If a description still cannot be retrieved, the row is delivered without it and the description is not charged. In our tests about one in six descriptions on stepstone.de failed this way.
- Stepstone.nl works but has few listings.
- The sites append related jobs after the exact matches and count them in their total. Use `match_type` or `exactMatchesOnly` to separate them.
- Salary is filled only when the site shows it without a login.
- To track new jobs over time, run it on a schedule with `sort` set to `date` and de-duplicate on `site` plus `job_id`.

### Integrations

Works with the Apify API, scheduled runs, webhooks, and the Apify MCP server, so Claude, ChatGPT and other agents can call it as a tool. Export to JSON, CSV, Excel or push into Google Sheets.

### Support

Issues tab on this page, or support@datasignalslab.com. Built and maintained by [DataSignals Lab](https://datasignalslab.com).

# Actor input Schema

## `site` (type: `string`):

Which site of the Stepstone group to search. All of them share one result format.

## `queries` (type: `array`):

One search per line, for example a job title or a skill. Each term is searched on the job board and in the city below.

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

Optional. For example Berlin, Wien, London, Dublin or Cape Town. Leave empty to search the whole country.

## `includeDescription` (type: `boolean`):

Opens each job page and adds the full description, employment type, closing date, industry and address. Charged as an extra event per job with a description, and it makes the run slower.

## `startUrls` (type: `array`):

Optional. Set your filters on any of the supported job boards in the browser and paste the URL of the result page here. Used in addition to the search terms.

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

Relevance ranking or newest first. Applies to the search terms, pasted URLs keep their own sorting.

## `postedWithinDays` (type: `string`):

Keep only recent jobs. Applies to the search terms.

## `exactMatchesOnly` (type: `boolean`):

The sites fill the result list with related jobs after the exact matches. Tick this to drop the related ones. Each row carries match_type either way.

## `maxJobsPerSearch` (type: `integer`):

Cap per search term or URL. The sites show 25 jobs per page.

## `maxJobs` (type: `integer`):

Hard stop across all searches. 0 means no limit. You pay per job returned, so this is also your budget cap.

## Actor input object example

```json
{
  "site": "stepstone.de",
  "queries": [
    "python"
  ],
  "location": "Berlin",
  "includeDescription": false,
  "sort": "relevance",
  "postedWithinDays": "any",
  "exactMatchesOnly": false,
  "maxJobsPerSearch": 100,
  "maxJobs": 0
}
```

# Actor output Schema

## `jobs` (type: `string`):

All jobs from this run as JSON, one object per job.

## `jobsCsv` (type: `string`):

The same jobs as a CSV download.

# 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 = {
    "queries": [
        "python"
    ],
    "location": "Berlin",
    "maxJobsPerSearch": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("datasignalslab/stepstone-jobs-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 = {
    "queries": ["python"],
    "location": "Berlin",
    "maxJobsPerSearch": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("datasignalslab/stepstone-jobs-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 '{
  "queries": [
    "python"
  ],
  "location": "Berlin",
  "maxJobsPerSearch": 100
}' |
apify call datasignalslab/stepstone-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datasignalslab/stepstone-jobs-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/PYZvYR3On6kxzl06v/builds/K1GcmrLWXXpgFgEb5/openapi.json
