# 🏆 Advanced MeineStadt.de Job Listing Scraper  🏆 (`claygenius/advanced-meinestadt-de-job-listing-scraper`) Actor

Scrape German regional job listings from jobs.meinestadt.de by keyword, city and radius.

- **URL**: https://apify.com/claygenius/advanced-meinestadt-de-job-listing-scraper.md
- **Developed by:** [Muhammad Shamshad Aslam](https://apify.com/claygenius) (community)
- **Categories:** Jobs, Automation, AI
- **Stats:** 4 total users, 2 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## MeineStadt.de Job Scraper

Scrapes German regional job listings from [jobs.meinestadt.de](https://jobs.meinestadt.de) by
keyword, city and radius — or directly from pasted job / search URLs. Results come from the
site's internal `jobsSearch` JSON API (called from within a real browser session), so the data
is complete and stable even when the page markup changes.

### Input

| Field | Type | Description |
|-------|------|-------------|
| `searchUrls` | array | **Search URLs** copied from the site (`…/leipzig/suche?words=…`) — reproduced exactly with all their filters. Individual job detail URLs (`…/leipzig/premium?id=123`) also work. Takes precedence: when set, keyword search is skipped. |
| `searchKeywords` | array | Search terms; each runs as its own search, results deduplicated by job ID. |
| `city` | string | City to search near (e.g. `Berlin`). Empty = all of Germany. Geocoded automatically so the radius works exactly like on the site. |
| `radius` | integer | Search radius in km (default `30`). |
| `postedWithin` | select | Timeliness (Aktualität): `any`, `1` = last 24 hours, `7` = last 7 days — the same options the site offers. |
| `workTime` | multi-select | `Vollzeit` and/or `Teilzeit`. Empty = all. |
| `homeOfficeOnly` | boolean | Only jobs marked "Homeoffice möglich". |
| `directOffersOnly` | boolean | Only direct employer offers (Direktangebot), excluding staffing agencies. |
| `includeMinijobs` | boolean | Also include minijob listings. |
| `includeRelatedResults` | boolean | Also scrape the related/nearby jobs the site appends after the real hits (default off = only what the site's "X Treffer" counter shows). |
| `maxResultsPerQuery` | integer | Cap per keyword (`0` = unlimited). |
| `maxTotalResults` | integer | Global cap across all queries (`0` = unlimited). |
| `includeFullJobDetails` | boolean | Visit each detail page for description, contact person, apply email (default `true`). SERP-only runs are ~3× faster and still include salary, skills, benefits. |
| `fetchCompanyDetails` | boolean | Also extract company description / website / logo from detail pages (default `false`). |
| `proxyConfiguration` | object | Apify proxy. **RESIDENTIAL recommended** (site is behind Akamai Bot Manager). |

#### Pasting search URLs

Compose any filtered search in the meinestadt.de UI, copy the address-bar URL, and paste it into
`searchUrls` — the actor reproduces it exactly, including filters carried in the URL hash
(`radius`, `d` timeliness, `minijob`, `work_time`, `homeoffice`, `mode_of_employment`):

```
https://jobs.meinestadt.de/leipzig/suche?words=zimmerer#order=search(stelle%2Cfalse)&jobsSearch={"radius":100,"d":7,"filters":["work_time:Vollzeit"]}
```

### Output

One dataset item per job, in the shared cross-scraper schema:

```json
{
  "id": "ms-100012922043001",
  "title": "Schreiner, Zimmerer, Tischler o. ä. als Schalungsbauexperte (m/w/d)",
  "company": "Doka Deutschland GmbH",
  "location": "Nossen",
  "distance_km": 23,
  "job_status": "online",
  "top_listing": "premium",
  "employment_type": "full-time",
  "contract_type": "Festanstellung",
  "fixed_term": "Unbefristet",
  "workload_min": 100,
  "workload_max": 100,
  "remote_option": null,
  "salary_text": "30.100 € - 39.000 €/Jahr (geschätzt)",
  "description_snippet": "…",
  "requirements": ["Bauwesen", "Teamfähigkeit", "Montage"],
  "posted_at": "2026-07-13T00:00:00Z",
  "expires_at": null,
  "source_url": "https://jobs.meinestadt.de/nossen/premium?id=100012922043001",
  "source_platform": "meinestadt.de",
  "contact_salutation": "Herr",
  "contact_firstname": "Gunnar",
  "contact_lastname": "Griese",
  "contact_email": "jobs@example.de",
  "contact_phone": "05032 - 898 461",
  "apply_url": "https://jobs.meinestadt.de/nossen/premium?id=100012922043001",
  "apply_email": "jobs@example.de",
  "company_logo_url": "https://image-resize.meinestadt.de/…",
  "company_benefits": ["Job-Rad", "Flexible Arbeitszeiten"],
  "categories": ["Handwerk & Produktion|Bau & Ausbau|Zimmerer|Bauzimmerer"],
  "ad_type": "premium",
  "link_out": false,
  "result_type": "core",
  "country": "DE",
  "search_query": "zimmerer",
  "scraped_at": "2026-07-14T10:00:00.000Z"
}
```

Notes:

- **`result_type`**: `"core"` = actual search hit (what the site's "X Treffer" counts); other
  values appear only with `includeRelatedResults` and mark appended related/nearby jobs.
- **On-site listings** (premium/standard) get detail-page data merged in (description, contact, apply email).
- **Linkout ads** (`link_out: true`, external redirect URLs) are saved with SERP data only — no on-site detail page exists.
- `contact_*` fields come from the detail page's "Kontakt" block and are `null` when the ad has none.

### Why this scraper

- **Exact results** — search counts match what you see on the site, including radius,
  timeliness and all other filters. No inflated numbers from "related" filler jobs
  (unless you opt in via *Include Related Results*).
- **Rich data** — salary ranges, skills, benefits, employment and contract type, posted
  dates, company logos, and (from detail pages) full contact persons with phone and email.
- **Reliable** — built-in blocking countermeasures with automatic retries; runs
  hands-off on a schedule.
- **Flexible input** — keyword searches, or just paste any search URL from the site and
  it's reproduced 1:1 with all its filters.

### Use cases

- **Lead generation** — extract hiring companies with direct contact persons, phone
  numbers and application emails.
- **Job monitoring** — track new postings for specific keywords/regions on a schedule
  (combine with *Posted Within: last 24 hours* for daily deltas).
- **Market research** — salary ranges, in-demand skills and benefits across German
  regions and industries.
- **Job aggregation** — feed structured listings into your own job board or CRM.

# Actor input Schema

## `searchUrls` (type: `array`):

Search URLs copied from jobs.meinestadt.de (…/leipzig/suche?words=…) — reproduced exactly, including all filters in the URL (radius, work time, home office, timeliness). Individual job detail URLs (…/leipzig/premium?id=123) also work. Takes precedence: when set, keyword search below is skipped.

## `searchKeywords` (type: `array`):

One or more search terms. Each keyword is searched separately and results are merged.

## `city` (type: `string`):

City/region name to search near, e.g. 'Berlin'.

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

Search radius around the city in kilometers.

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

Timeliness filter — same options the site offers.

## `workTime` (type: `array`):

Filter by working hours. Leave empty for all.

## `homeOfficeOnly` (type: `boolean`):

Only jobs marked 'Homeoffice möglich'.

## `directOffersOnly` (type: `boolean`):

Only direct employer offers (Direktangebot), excluding staffing agencies.

## `includeMinijobs` (type: `boolean`):

Also include minijob listings.

## `maxResultsPerQuery` (type: `integer`):

Maximum number of job listings to collect per keyword/query. 0 = unlimited.

## `maxTotalResults` (type: `integer`):

Hard cap on total job listings across all queries. 0 = unlimited.

## `includeRelatedResults` (type: `boolean`):

Also scrape the related/nearby jobs the site appends after the real search hits. Off = only the exact hits the site's own counter shows.

## `fetchCompanyDetails` (type: `boolean`):

Extract extended company information from each job detail page (description, logo, benefits, website). Only applies when 'Include Full Job Details' is on.

## `includeFullJobDetails` (type: `boolean`):

Visit each job detail page to extract full description, company, requirements, etc. Slower but richer.

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

Proxy settings. jobs.meinestadt.de is behind Akamai Bot Manager — RESIDENTIAL proxies are strongly recommended; datacenter proxies are usually blocked.

## Actor input object example

```json
{
  "searchUrls": [],
  "searchKeywords": [
    "Software Engineer"
  ],
  "city": "Berlin",
  "radius": 30,
  "postedWithin": "any",
  "workTime": [],
  "homeOfficeOnly": false,
  "directOffersOnly": false,
  "includeMinijobs": false,
  "maxResultsPerQuery": 10,
  "maxTotalResults": 0,
  "includeRelatedResults": false,
  "fetchCompanyDetails": false,
  "includeFullJobDetails": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

All scraped job listings: title, company, location, salary, employment type, requirements, benefits, contact details, apply links and metadata.

## `contacts` (type: `string`):

Contact-person view (salutation, name, phone, email, apply links) extracted from on-site job detail pages.

# 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 = {
    "searchUrls": [],
    "searchKeywords": [
        "Software Engineer"
    ],
    "city": "Berlin",
    "radius": 30,
    "maxResultsPerQuery": 10,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("claygenius/advanced-meinestadt-de-job-listing-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 = {
    "searchUrls": [],
    "searchKeywords": ["Software Engineer"],
    "city": "Berlin",
    "radius": 30,
    "maxResultsPerQuery": 10,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("claygenius/advanced-meinestadt-de-job-listing-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 '{
  "searchUrls": [],
  "searchKeywords": [
    "Software Engineer"
  ],
  "city": "Berlin",
  "radius": 30,
  "maxResultsPerQuery": 10,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call claygenius/advanced-meinestadt-de-job-listing-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,claygenius/advanced-meinestadt-de-job-listing-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/dyxkxrwxYMaIdBNGG/builds/w5PshbaUCQggiau8N/openapi.json
