# StepStone Germany Jobs Scraper (`automation-lab/stepstone-germany-job-listings`) Actor

Export StepStone Germany job listings by keyword and location or results URL. Collect vacancy IDs, titles, employers, locations, snippets and displayed card metadata for recurring recruiting snapshots.

- **URL**: https://apify.com/automation-lab/stepstone-germany-job-listings.md
- **Developed by:** [Automation Lab](https://apify.com/automation-lab) (community)
- **Categories:** Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.72 / 1,000 item extracteds

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

## StepStone Germany Jobs Scraper

Export **StepStone Germany jobs** as structured listing-card records for recurring recruiting snapshots and hiring analysis. Search by keyword and location, or supply StepStone.de results URLs. Get job IDs, titles, employers, locations, snippets, posting timestamps and available card metadata without opening every job detail page.

This Actor collects a bounded snapshot. It does not harvest contact details, enrich full descriptions, apply for jobs, or compare snapshots automatically.

### Who is it for?

- Recruiting operations teams collecting vacancies for a role and city.
- Hiring analysts comparing employer activity across repeatable searches.
- Data engineers moving public job listings into spreadsheets or a warehouse.

### Why use this Actor?

Stable source job IDs support joins between your own scheduled snapshots. Each record retains its results-page URL, source section and collection timestamp so you can audit where it appeared. Listing snippets provide useful context without the cost of fetching every detail page.

Salary estimates remain identified as estimates. Missing metadata is null rather than guessed. Jobs are deduplicated across pages and search URLs within a run.

### Getting started

1. Enter a keyword such as `software engineer`.
2. Optionally enter a German city such as `Berlin`.
3. Set `maxItems` to your desired global record cap.
4. Run the Actor and open the **Job listings** dataset view.
5. Download JSON, CSV or Excel using Apify's dataset export tools.

```json
{
  "keyword": "software engineer",
  "location": "Berlin",
  "maxItems": 10,
  "maxPages": 10
}
```

### Search StepStone Germany jobs by results URL

Copy an HTTPS StepStone.de `/jobs` results URL. Its source filters and starting page are preserved. Clear keyword and location before using URL mode; mixing both input routes is rejected rather than silently ignoring filters.

```json
{
  "startUrls": [
    { "url": "https://www.stepstone.de/jobs/pflege/in-hamburg" }
  ],
  "maxItems": 25,
  "maxPages": 3
}
```

Only German StepStone results pages are supported. Job-detail, company-profile, other-country and arbitrary website URLs are not accepted.

### Input parameters

| Field | Meaning |
|---|---|
| `keyword` | Required in search mode. Job title, skill or employer sent through StepStone's search URL. Leading/trailing spaces are removed, text is lowercased and spaces become hyphens. |
| `location` | Optional city or postcode in search mode. StepStone controls radius, remote and multi-location inclusion. |
| `startUrls` | Up to 10 results URLs, processed in order. Mutually exclusive with keyword/location. |
| `maxItems` | Global unique-job cap, default 100, range 1–2500. Zero/unlimited is not supported. |
| `maxPages` | Global results-page cap, default 10, range 1–100, across all URLs. |

StepStone's relevance engine controls matching. A keyword is not an exact phrase, title-only or whole-field filter. A location is not an exact location post-filter. The source may return semantic, regional, recommended or multi-location cards, even for a query with no exact matches. Inspect `section` and your downstream relevance rules when exact matching matters.

### Extracted data

| Field | Meaning |
|---|---|
| `jobId` | Stable StepStone identifier, represented as a string. |
| `title`, `employer` | Plain-text title and displayed employer. |
| `location` | Source location text, potentially multiple places. |
| `jobUrl` | Job URL with tracking query removed. |
| `snippet` | Listing-card text, not a full job description. |
| `datePosted` | Source timestamp when supplied. |
| `section` | Source result category such as main, semantic or regional. |
| `labels` | Available card labels; empty array if absent. |
| `isSponsored` | Source sponsorship flag when available. |
| `workFromHome` | Raw source code string, such as `"2"` or `"0"`; not a human-readable label or interpreted remote-work status. |
| `salaryMin`, `salaryMax` | Available source salary bounds, not calculated by this Actor. |
| `salaryCurrency`, `salaryPeriod`, `salaryType` | Source salary qualifiers. `Predicted` means an estimate, not confirmed employer pay. |
| `searchUrl`, `scrapedAt` | Results-page provenance and UTC snapshot time. |

Optional values are null when absent. Card availability varies by query and listing. Salary, remote-work and label fields are not guaranteed on every record.

### Output example

A representative listing returned during testing (optional metadata shortened):

```json
{
  "jobId": "13817131",
  "title": "Software Engineer Public Sector (all genders)",
  "employer": "msg systems ag",
  "location": "Berlin, Chemnitz, Dresden, Düsseldorf, Essen, Frankfurt am Main, Hamburg, Hannover",
  "jobUrl": "https://www.stepstone.de/stellenangebote--Software-Engineer-Public-Sector-all-genders-Berlin-Chemnitz-Dresden-Duesseldorf-Essen-Frankfurt-am-Main-Hamburg-Hannover-msg-systems-ag--13817131-inline.html",
  "section": "main",
  "salaryMin": 46000,
  "salaryMax": 74000,
  "salaryCurrency": "EUR",
  "salaryPeriod": "Annually",
  "salaryType": "Predicted",
  "searchUrl": "https://www.stepstone.de/jobs/software-engineer/in-berlin"
}
```

### How much does it cost to export StepStone Germany jobs?

Billing uses one `start` event per valid run plus one `item` event per unique saved listing. No item events are charged for duplicates, rejected cards or empty pages. Card metadata is included with its listing; there are no separate salary or snippet charges.

At BRONZE, the run fee is **$0.005** and listings cost **$0.0012 each**. Examples: 10 listings cost $0.017; 100 cost $0.125; 1,000 cost $1.205. These are Actor event charges, not a claim about other services in your Apify account.

| Plan tier | Per listing |
|---|---:|
| FREE | $0.00138 |
| BRONZE | $0.0012 |
| SILVER | $0.000936 |
| GOLD | $0.00072 |
| PLATINUM | $0.00072 |
| DIAMOND | $0.00072 |

The start fee is $0.005 at every tier. A valid empty search still incurs the start charge. A failed run may have already saved and charged earlier pages. Use Apify's maximum-charge setting as an additional billing limit; it can stop collection before the requested item count.

### Pagination, limits and failure behavior

The Actor follows source next-page links serially and stops at source exhaustion, the global page cap, the global unique-item cap, or the billing cap. Results URLs keep their starting page. Earlier URLs can use the whole run budget before later URLs are visited.

The dataset is a snapshot, not guaranteed complete coverage of all StepStone vacancies. Listings can move, disappear or appear on several pages while a run is in progress. Deduplication is within a run; repeats across scheduled runs are intentional.

HTTP/1 structured listing retrieval is used without paid proxy fallback. Transient network errors, rate limits and server errors receive at most three attempts. Permanent denial, a challenge page or missing structured results fails honestly rather than returning false empty success. There is no guarantee against future source changes. Runtime timeout can leave partial output.

### Integrations

Use Apify schedules to repeat a fixed search, then join on `jobId` and compare your stored snapshots. A vacancy absent from one bounded snapshot is not proof it closed; search ranking and limits also affect visibility.

Send dataset exports to Google Sheets, Make, Zapier or your own warehouse. A practical recruiting pipeline stores `jobId`, `employer`, `location`, `section` and `scrapedAt`, filters relevance downstream, and retains the full dataset outside an AI prompt.

### API usage

Start an asynchronous run and retain its returned run ID and storage IDs. Keep your Apify token in an environment variable, not in shared scripts or URLs.

```bash
curl -X POST \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"keyword":"software engineer","location":"Berlin","maxItems":10}' \
  'https://api.apify.com/v2/acts/automation-lab~stepstone-germany-job-listings/runs'
```

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/stepstone-germany-job-listings').call({
    keyword: 'software engineer', location: 'Berlin', maxItems: 10,
});
if (run.status !== 'SUCCEEDED') throw new Error(`Run ${run.id}: ${run.status}`);
const page = await client.dataset(run.defaultDatasetId).listItems({ limit: 10 });
console.log(page.items);
```

```python
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/stepstone-germany-job-listings').call(
    run_input={'keyword': 'software engineer', 'location': 'Berlin', 'maxItems': 10})
if run['status'] != 'SUCCEEDED':
    raise RuntimeError(f"Run {run['id']}: {run['status']}")
page = client.dataset(run['defaultDatasetId']).list_items(limit=10)
print(page.items)
```

### MCP integration

Select a stable Actor subset rather than an unqualified tool catalog:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/stepstone-germany-job-listings"
```

#### Claude Desktop, Cursor, and VS Code

Equivalent editor/desktop configuration for clients supporting remote HTTP servers:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/stepstone-germany-job-listings"
    }
  }
}
```

Authenticate through your client's supported Apify flow. Discover actual tool names and argument schemas with scoped `tools/list`. Actor selection also adds run/data helpers; it does not expose exactly one tool. Tool availability depends on account access and publication state.

Example prompt: “Collect 10 software engineer listing cards in Berlin, then show titles, employers, locations and source sections. Do not fetch full descriptions.”

For an authorized invocation, start once and retain its run ID/status/storage IDs. `call-actor` waits at most 45 seconds (`waitSecs`, default 30), so a reply may be metadata rather than rows. For a nonterminal run, follow that same ID with `get-actor-run` using bounded backoff (2, 4, 8 seconds, capped at 10) and a 120-second overall deadline. Set the client timeout above the chosen server wait plus transport margin. On client timeout, recover the known run, not a new invocation; if the ID is unknown, report uncertainty. At the deadline report pending and stop. Report terminal failures honestly, with any rows marked partial.

After success, use `get-dataset-items` with the returned `defaultDatasetId`, explicit offsets, limits and fields. Example consumer budget: 20 source rows per page, at most 100 rows and 64 KiB serialized UTF-8 across pages admitted to model context, whichever comes first. Enforce bytes host-side before injection; omit or summarize oversized rows with disclosure. If your client cannot intercept oversized replies, do not claim a hard byte ceiling. Prefer untransformed JSON, track source offsets rather than transformed counts, and report returned rows, next offset and truncation. Keep full exports in storage. This is a consumer context budget, not a reduction of Actor collection limits. No universal token-saving guarantee is made.

### Legality, responsible use and diagnostics

Use publicly available job data responsibly, respect applicable law and source terms, and avoid unnecessary collection or redistribution. This Actor is independent of StepStone and is not an official StepStone API. Public availability is not legal advice or permission for every use. It does not collect applicant data or employer contact details.

Failed operations send sanitized diagnostic input, exceptions and Actor/build/run IDs to our private GlitchTip service for repair. Secret fields and URL queries are removed. Reports are retained for 30 days. Do not put sensitive information in job-search inputs. No runtime AI provider is called; source snippets and estimates are not enriched by this Actor. Run input, datasets and logs follow your Apify account's retention settings; delete them through Apify storage controls. The Actor keeps no global cache or persistent cross-run session. For help, use the Actor's Apify Issues tab and include a run ID rather than secrets.

### FAQ and troubleshooting

**Why do some results not exactly match my keyword or city?** StepStone expands relevance and can include nearby, semantic or multi-location vacancies. Inspect `section` and implement your own downstream exact-match rule if needed.

**Why did a nonsense query still return jobs?** The source can offer suggested vacancies instead of an empty page. This Actor exports the source's cards, not a fabricated zero-result answer.

**Why are salary fields null or marked Predicted?** Many cards omit salary. Predicted values are source estimates and should not be represented as employer-confirmed compensation.

**Can I get full descriptions or contacts?** No. This product is listing-only, and does not open detail pages for enrichment.

**Why did a run fail with missing state or HTTP denial?** The source may have changed its layout or blocked access. Do not assume an empty dataset proves no jobs exist. Share the run ID with support; avoid blind repeated runs.

**Can I monitor changes?** Schedule snapshots using Apify, then compare datasets in your own pipeline. Built-in alerts, history and change detection are not provided.

### Related Actors

For complementary German vacancy corpora, consider [Arbeitsagentur Jobs Scraper](https://apify.com/automation-lab/arbeitsagentur-germany-job-listings) and [XING Jobs Scraper](https://apify.com/automation-lab/xing-job-listings-scraper-retry). They collect different sources; their records are not substitutes for StepStone listings.

# Changelog

This Actor's version history is a separate document: https://apify.com/automation-lab/stepstone-germany-job-listings/changelog.md

# Actor input Schema

## `keyword` (type: `string`):

Job title, skill or employer sent to StepStone's search through a lowercased URL slug (trimmed, spaces replaced by hyphens). Required unless results URLs are supplied. Source relevance and synonyms apply, not exact phrase or whole-field matching; related/regional cards can appear and are labeled by section. Cannot be combined with results URLs.

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

Optional German city or postcode, trimmed and lowercased into the StepStone search URL. Used only with keyword; cannot be combined with results URLs. StepStone may include surrounding locations, remote roles and multi-location jobs. This is not an exact location post-filter.

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

Up to 10 HTTPS stepstone.de /jobs results URLs, processed in order with their source filters and starting page preserved. No detail/company URLs or other domains. Mutually exclusive with keyword and location; clear their prefilled values first. Deduplication and limits apply globally across all URLs.

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

Global maximum unique job IDs saved across all searches and pages, after deduplication. Default 100; 1–2500. Zero/unlimited is unsupported. Source exhaustion, page limit, billing limit or runtime timeout may return fewer records; failed runs contain partial results only.

## `maxPages` (type: `integer`):

Global cap on fetched results pages across all URLs, including pages with duplicate jobs. Default 10; 1–100. Stops earlier at maxItems, source exhaustion or billing limits. Starting URLs retain their starting page. This is a bounded snapshot, not guaranteed complete source coverage.

## Actor input object example

```json
{
  "keyword": "software engineer",
  "location": "Berlin",
  "maxItems": 10,
  "maxPages": 10
}
```

# Actor output Schema

## `dataset` (type: `string`):

Collected StepStone vacancy records; failed runs may contain partial output.

# 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 = {
    "keyword": "software engineer",
    "location": "Berlin",
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/stepstone-germany-job-listings").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 = {
    "keyword": "software engineer",
    "location": "Berlin",
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/stepstone-germany-job-listings").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 '{
  "keyword": "software engineer",
  "location": "Berlin",
  "maxItems": 10
}' |
apify call automation-lab/stepstone-germany-job-listings --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/stepstone-germany-job-listings"
        }
    }
}
```

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/1SdF6xY9iKuHrg5m3/builds/b7OJEVGforpcse0ip/openapi.json
