# meinestadt.de Jobs Scraper - German Job Listings (`studio-amba/meinestadt-scraper`) Actor

Scrape German job listings from jobs.meinestadt.de: titles, companies, locations, work time, estimated salaries and posting dates. Optional detail fetch adds full job descriptions and validity dates.

- **URL**: https://apify.com/studio-amba/meinestadt-scraper.md
- **Developed by:** [Studio Amba](https://apify.com/studio-amba) (community)
- **Categories:** Jobs
- **Features:** Limited permissions
- **Stats:** 1 total users, 1 monthly users, 98.5% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 result scrapeds

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

### What does meinestadt.de Scraper do?

**meinestadt.de Scraper** extracts job listings from [jobs.meinestadt.de](https://jobs.meinestadt.de) — a German local-city job board covering thousands of towns and cities across Germany. It collects **job titles, companies, locations, work time, posting dates, and salaries** for any keyword and city, up to 1,000 listings per query (994 unique listings came back from a nationwide "Verkäufer" run in 214 seconds). An optional detail mode adds the **full job description, structured salary range, and posting expiry date**. No login or cookies required.

Use the Apify platform to run this scraper on a schedule, access results via API, or integrate with tools like Google Sheets, Slack, Zapier, and Make.

### Why use meinestadt.de Scraper?

- **Market research** — Track job availability and salary ranges for a role across German cities
- **Recruitment intelligence** — Monitor which companies are hiring, in which cities, and at what pay
- **Salary benchmarking** — meinestadt.de shows a salary on about 40 to 70 percent of listings, either stated by the employer or estimated by the site
- **Lead generation** — Collect hiring-company data for recruitment agencies or HR tech outreach
- **Labor market analysis** — Aggregate job counts and salary bands by city, keyword, or industry
- **Aggregation** — Combine with other German job boards (arbeitsagentur, stepstone, jobware) for fuller market coverage

### How to scrape meinestadt.de jobs data

1. Go to the [meinestadt.de Scraper](https://apify.com/studio-amba/meinestadt-scraper) page on Apify
2. Click **Try for free** to open the actor in Apify Console
3. Enter a German keyword (e.g. "Krankenpfleger", "Elektriker", "Verkäufer")
4. Enter a city slug (e.g. "berlin", "muenchen", "koeln") — or "deutschland" for a nationwide search
5. Optionally set a search radius in kilometers
6. Optionally enable **Fetch full job details** for the full description, structured salary, and expiry date
7. Set the maximum number of results you need (up to 1,000 per query — the site's own cap)
8. Click **Start** and wait for the scraper to finish
9. Download your data in JSON, CSV, Excel, or HTML format

### Input

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `searchQuery` | String | No | German job keyword (default: "Krankenpfleger"). Examples: "Elektriker", "Verkäufer", "Lagerhelfer" |
| `citySlug` | String | No | City URL slug, lowercase with umlauts transliterated and hyphens (default: "berlin"). Examples: "muenchen", "koeln", "bergisch-gladbach". Use "deutschland" for a nationwide search |
| `radius` | Integer | No | Search radius around the city in kilometers (site's "umkreis" parameter). Leave empty for the site default |
| `fetchDetails` | Boolean | No | Fetch each job's detail page for the full description, structured salary, and validity date. Costs one extra HTTP request per job (default: false) |
| `maxResults` | Integer | No | Maximum job listings to return (default: 20). The site caps any single query at 1,000 results — use a narrower city, keyword, or radius to go beyond that |
| `proxyConfiguration` | Object | No | Proxy settings. **Residential proxies targeting Germany are required** — see Limitations below |

### Output

Each job listing contains:

| Field | Type | Example |
|-------|------|---------|
| `jobTitle` | String | `"Pflegefachkraft (m/w/d)"` |
| `company` | String | `"Krankenhaus Waldfriede e. V."` |
| `location` | String | `"Berlin"` |
| `date` | String | `"30.10.2026"` (day.month.year) |
| `workTime` | String | `"Vollzeit oder Teilzeit"` (empty on about 6 percent of listings) |
| `salary` | String | `"38.300 € - 49.000 €/Jahr (geschätzt)"` (empty on 30 to 60 percent of listings) |
| `salaryEstimated` | Boolean | `true` |
| `url` | String | Full job detail URL on meinestadt.de |
| `jobDescription` | String | Full job description (fetchDetails only) |
| `salaryMin` | Number | `38316` (fetchDetails only) |
| `salaryMax` | Number | `48995` (fetchDetails only) |
| `validThrough` | String | `"2026-08-20"` (fetchDetails only) |
| `scrapedAt` | String | `"2026-07-12T22:37:52.139Z"` |

### Example output

```json
{
    "jobTitle": "Pflegefachkraft oder Gesundheits- und Krankenpfleger/in (m/w/d)",
    "company": "Krankenhaus Waldfriede e. V. Akademisches Lehrkrankenhaus der Charité",
    "location": "Berlin",
    "date": "12.07.2026",
    "workTime": "Vollzeit oder Teilzeit",
    "salary": "38.300 € - 49.000 €/Jahr (geschätzt)",
    "salaryEstimated": true,
    "url": "https://jobs.meinestadt.de/berlin/premium?id=100012771570",
    "jobDescription": "<ul>\n <li>Ganzheitliche, professionelle Pflege unserer Patient/innen</li>\n...</ul>",
    "salaryMin": 38316,
    "salaryMax": 48995,
    "validThrough": "2026-08-20",
    "scrapedAt": "2026-07-12T22:37:52.139Z"
}
```

### How much does it cost to scrape meinestadt.de?

It costs $0.02 per run plus $0.002 per job listing, regardless of whether detail mode is on — detail mode makes one extra request per job to enrich the same row, it doesn't add more results or change the per-item price.

- **~20 listings**: $0.06
- **~100 listings**: $0.22
- **~1,000 listings** (the site's per-query cap): $2.02

The start fee is $0.005 per GB of memory and the actor defaults to 4 GB. Detail mode adds time, not cost: 20 listings took 32 seconds with details on.

This actor requires residential proxies (see below) for reliable results.

### Limitations

- **Requires residential proxies targeting Germany.** jobs.meinestadt.de runs Akamai Bot Manager, which blocks by TLS fingerprint rather than IP. Datacenter proxies get connection resets on a large share of requests, and there is no German datacenter proxy pool available — residential/DE is preconfigured as the default and should not be changed.
- **1,000 results per query.** This is a hard cap on the site itself (page 51 returns a 404), not a scraper limitation. Split large harvests by city, keyword, or radius to go beyond it.
- **Salary is usually site-estimated**, not employer-stated — check `salaryEstimated` before treating it as authoritative.
- **Keyword matching is the site's own.** A search for "Krankenpfleger" in Berlin returned related roles such as Erzieher and Heilerziehungspfleger next to nursing jobs. Filter on `jobTitle` if you need an exact role.
- **Nearby towns are included.** A search for Berlin also returns listings in Potsdam, Zeuthen and Ludwigsfelde. Set `radius` to narrow it.
- **Salary and work time are not on every listing.** In a 50-row Berlin run, 19 had a salary and 34 had a work time. In a 994-row nationwide run, 705 had a salary and 939 had a work time. The empty fields are left empty.
- **Detail mode can return one row more than `maxResults`.** A run with 20 asked and details on returned 21 rows. `salaryMin` and `salaryMax` were set on 20 of those 21.
- Data is scraped from the public website and may change without notice.

### FAQ and support

**Is it legal to scrape meinestadt.de?**
This actor extracts publicly available data from jobs.meinestadt.de. Users are responsible for ensuring their use complies with applicable laws and the website's terms of service.

**Why do I need a residential proxy?**
jobs.meinestadt.de's anti-bot system (Akamai Bot Manager) fingerprints the TLS handshake, not just the IP. Datacenter IPs get their connections reset on detail pages roughly half the time. Residential proxies scoped to Germany avoid this reliably.

**The scraper returned 0 results?**
A search with no matches ends as SUCCEEDED with an empty dataset and the status message "No jobs: jobs.meinestadt.de has 0 results for ...". Only the start fee is charged. Check that `citySlug` is a valid meinestadt.de city slug (lowercase, umlauts transliterated: "muenchen" not "münchen") and that `searchQuery` has real results for that city. Also confirm the proxy configuration is RESIDENTIAL with country DE.

**Can I search all of Germany at once?**
Yes — set `citySlug` to `"deutschland"` for a nationwide search across all cities.

### Related Scrapers

Looking for more German job market data? We also maintain scrapers for:

- **Arbeitsagentur Scraper** — Germany's federal job agency listings
- **StepStone Scraper** — one of Germany's largest job boards
- **Jobware Scraper** — German B2B and skilled-trades job board
- **Eures Scraper** — EU-wide job mobility portal, including German listings

# Actor input Schema

## `searchQuery` (type: `string`):

Job keyword to search for, in German, e.g. 'Krankenpfleger', 'Elektriker', 'Verkäufer'.

## `citySlug` (type: `string`):

City to search in, as a URL slug (lowercase, umlauts transliterated, hyphenated), e.g. 'berlin', 'muenchen', 'koeln'. Use 'deutschland' for a nationwide search.

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

Optional search radius around the city in kilometers (maps to the site's 'umkreis' parameter). Leave empty for the site default.

## `fetchDetails` (type: `boolean`):

Fetch each job's detail page for the full HTML description, validThrough date and structured salary. Costs ONE EXTRA HTTP request per job on top of the search-page walk — with up to 1,000 results per query this can meaningfully increase run time. Leave off for a fast listing-only crawl.

## `maxResults` (type: `integer`):

Maximum number of job listings to return. The site caps any single search query at 1,000 results (50 pages of 20) — use a narrower city/keyword/radius to go beyond that.

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

meinestadt.de's Akamai Bot Manager blocks by TLS fingerprint. Datacenter proxies get reset mid-crawl (NGHTTP2 errors) and there is no German datacenter pool on this account — RESIDENTIAL with country DE is required for a reliable crawl.

## Actor input object example

```json
{
  "searchQuery": "Krankenpfleger",
  "citySlug": "berlin",
  "fetchDetails": false,
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "DE"
  }
}
```

# Actor output Schema

## `results` (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 = {
    "searchQuery": "Krankenpfleger",
    "citySlug": "berlin",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "DE"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/meinestadt-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 = {
    "searchQuery": "Krankenpfleger",
    "citySlug": "berlin",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "DE",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/meinestadt-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 '{
  "searchQuery": "Krankenpfleger",
  "citySlug": "berlin",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "DE"
  }
}' |
apify call studio-amba/meinestadt-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,studio-amba/meinestadt-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/N1YYSAxS5EO8xslyl/builds/sz6Lk4vSzyCgveCyG/openapi.json
