# Arbeitsagentur Jobs Scraper - Germany, Austria, CH & EURES (`tinyrex/dach-jobs-scraper`) Actor

Jobs from official sources: Bundesagentur für Arbeit (Germany) and EURES (Austria/AMS, Switzerland, EU). Salary, location, full description, filters and monitoring of new jobs. Pay per job.

- **URL**: https://apify.com/tinyrex/dach-jobs-scraper.md
- **Developed by:** [TinyRex](https://apify.com/tinyrex) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 jobs

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

## Arbeitsagentur & EURES Jobs Scraper: German, Austrian, Swiss and EU jobs

Get jobs from the **official public employment services**: the **Bundesagentur für Arbeit** (Arbeitsagentur, Germany's largest job database with over a million listings) and **EURES**, the European Commission's job mobility portal with vacancies from public employment services in **Austria (AMS), Switzerland** and every other EU/EEA country. Search by job title and location and get clean, structured jobs with salary, location, contract type and the full description. You pay only for the jobs you get.

**Why this one:** **$1 per 1,000 jobs with full descriptions included**, while most Arbeitsagentur and EURES scrapers on the Store charge about $1.50–3 per 1,000, or extra for details. It uses the official public job search APIs (no fragile HTML scraping), so runs are fast and reliable. Jobs removed by your filters and jobs whose details could not be loaded are **free**.

### Why this scraper

- **Official sources.** Bundesagentur für Arbeit Jobsuche API and the EURES public job search. The same data job seekers see on arbeitsagentur.de and europa.eu/eures.
- **Germany + Austria + Switzerland + EU in one run.** One normalized schema for both sources, so you can mix them in one dataset.
- **Full details included.** Full description, salary range (when published), postal code, city, federal state, coordinates, working time, contract type, home office, career changers welcome, start date and posting date. Same price with or without descriptions.
- **Fast.** About 60 jobs with full descriptions in 4 seconds. No browser.
- **Filters.** Location + radius, offer type (job, apprenticeship, internship), working time (full-time, part-time, shift, home office, mini-job), permanent/temporary, exclude temp agencies, employer, posted within N days, strict title match.
- **Monitoring built in.** Turn on *Only new jobs* and schedule the Actor daily to get only jobs not seen before.

### What you get

| Field | Example |
|---|---|
| source, jobId | arbeitsagentur, 10001-1003690738-S |
| title, occupation | Junior Data Analyst (m/w/d), Data-Analyst/in |
| employer | IABG Industrieanlagen Betriebs-GmbH |
| location, city, postalCode, region, country | 85521 Ottobrunn, Ottobrunn, 85521, BAYERN, DE |
| latitude, longitude, locations | 48.05, 11.66, all job locations |
| workTime, contractType, homeOffice | \[fulltime], permanent, true |
| salary | {min: 45000, max: 65000, currency: EUR, period: year} |
| startDate, postedAt, updatedAt | 2026-09-29, 2026-09-11 |
| url, externalUrl | arbeitsagentur.de / europa.eu job page, employer's own page |
| descriptionText | full job description |
| languages, escoOccupationUris, euresFlag | EURES extras |

### How to use

1. Add one or more **job titles / keywords** (German titles work best for Germany, e.g. *Pflegefachkraft*, *Elektriker*, *Data Analyst*). Leave empty to get the newest jobs.
2. Choose **sources**: Bundesagentur für Arbeit (Germany), EURES (Austria, Switzerland, EU) or both.
3. Optional: **locations in Germany** (cities or postal codes) with a radius, and **EURES countries or regions** (`at`, `ch`, `nl`, or NUTS codes like `at13` for Vienna).
4. Run and download the results as JSON, CSV, Excel or HTML, or use them via the API, webhooks or integrations (Google Sheets, Make, Zapier, n8n, Slack).

#### Example input

```json
{
  "keywords": ["Data Analyst", "Elektriker"],
  "sources": ["arbeitsagentur", "eures"],
  "baLocations": ["Berlin", "München"],
  "baRadiusKm": 25,
  "euresLocations": ["at", "ch"],
  "publishedWithinDays": 7,
  "maxResultsPerSearch": 200
}
```

#### Example output (shortened)

```json
{
  "source": "arbeitsagentur",
  "jobId": "10001-1003690738-S",
  "title": "Junior Data Analyst militärische Fahrzeuge (m/w/d)",
  "employer": "IABG Industrieanlagen Betriebs-GmbH",
  "location": "85521 Ottobrunn",
  "region": "BAYERN",
  "country": "DE",
  "workTime": ["fulltime"],
  "contractType": "permanent",
  "homeOffice": true,
  "salary": { "min": 45000, "max": 65000, "currency": "EUR", "period": "year" },
  "postedAt": "2026-09-11",
  "url": "https://www.arbeitsagentur.de/jobsuche/jobdetail/10001-1003690738-S",
  "descriptionText": "Beschreibung der Stelle\n\nWollen Sie unser Team der Datenanalyse für militärische Fahrzeuge verstärken? ..."
}
```

### Monitoring new jobs

Set **Only new jobs** to true and add a schedule (for example daily). Each run returns only jobs that were not returned before for the same search and **State key**. The first run returns all matching jobs as the baseline.

### Run report

- **`SEARCHES`**: for every search (source, keyword, location), jobs available, fetched and saved, and any error.
- **`SUMMARY`**: totals for the run.

### Pricing

Pay per event:

- **Job** (`job`): one charge per job saved to your dataset, full description included.
- **Free:** jobs removed by your filters, duplicates, already-seen jobs in monitoring mode, and jobs whose details could not be loaded.

See the *Pricing* tab for the current price. Set a maximum cost per run and the Actor stops gracefully when it is reached.

### Limitations

- Each source returns at most 10,000 jobs per search. Split big searches by keyword or location (each location is a separate search).
- Salary, coordinates, home office and start date come from the Arbeitsagentur; EURES ads usually give region codes (NUTS) instead of cities and rarely a salary.
- Some ads hide the employer name; it is then `null`.
- No contact persons, phone numbers or emails are extracted. Only the job ad itself.

### Use with AI agents (MCP)

This Actor works as a tool for AI agents through the **Apify MCP server** at `https://mcp.apify.com`. Connect Claude, Cursor, VS Code, n8n or any other MCP client to `https://mcp.apify.com?tools=tinyrex/dach-jobs-scraper` and the agent can run it from a plain-language request, for example: *"Find nursing jobs (Pflegefachkraft) in Munich and Vienna posted this week, with salary"*. Results come back as clean, structured JSON at the same pay-per-result price, and failed results stay free.

📘 **Step-by-step guide with Python, JavaScript, curl and MCP examples:** [How to export jobs from the Bundesagentur für Arbeit (Arbeitsagentur) and EURES](https://emirmrkaljevic.github.io/tinyrex-data-tools/arbeitsagentur-jobs-api/)

### Related actors

- [Greenhouse / Lever / Ashby Jobs Scraper](https://apify.com/tinyrex/ats-jobs-scraper): Jobs straight from company career sites on Greenhouse, Lever, Ashby, Personio, Teamtailor or Recruitee, with the same clean job schema.
- [Workday Jobs Scraper](https://apify.com/tinyrex/workday-jobs-scraper): All jobs from companies that hire on Workday (myworkdayjobs.com), with full descriptions.
- [Remote Jobs Scraper](https://apify.com/tinyrex/remote-jobs-scraper): Remote jobs from Himalayas, Remote OK, We Work Remotely, Working Nomads and Arbeitnow in one run, with salary, location rules and full descriptions.
- [Tech Stack Detector](https://apify.com/tinyrex/tech-stack-detector): Enrich hiring companies with their tech stack, email provider and DMARC for sales outreach.

### FAQ

**Is it legal?** The Actor reads public job ads from official public employment services through their public job search interfaces. It does not log in, does not apply to jobs, and does not collect candidate or contact-person data. Use the data in line with your local laws.

**Does it cover Austria (AMS)?** Yes, through EURES: Austrian public employment service vacancies are published on EURES. Use `at` or Austrian NUTS codes (e.g. `at13` Vienna, `at22` Styria).

**How fast is it?** Dozens of jobs per second, with full descriptions.

# Actor input Schema

## `keywords` (type: `array`):

Each keyword is a separate search, e.g. Data Analyst, Pflegefachkraft, Elektriker. German job titles give the best results for Germany. Leave empty to get the newest jobs for the selected locations.

## `sources` (type: `array`):

Bundesagentur für Arbeit: Germany's official job board (largest German job database). EURES: the European Commission's job mobility portal with vacancies from public employment services across Europe, including Austria (AMS) and Switzerland.

## `maxResultsPerSearch` (type: `integer`):

Maximum jobs per keyword (and per location for Germany) and source. 0 = as many as the source allows (up to 10,000 per search; split big searches by location).

## `publishedWithinDays` (type: `integer`):

Only jobs published in the last N days. 0 = any time.

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

Filter by working time. Shift, home office and mini-job filters apply to Germany only.

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

Adds the full job description text. For Germany this needs one extra request per job (still fast). Same price either way.

## `strictTitleMatch` (type: `boolean`):

Drop jobs whose title does not contain every word of the keyword (the sources also return related titles). Dropped jobs are free.

## `baLocations` (type: `array`):

Cities, postal codes or regions (e.g. Berlin, 80331, Hamburg). Each location is a separate search. Leave empty for all of Germany.

## `baRadiusKm` (type: `integer`):

Search radius around each location.

## `baOfferType` (type: `string`):

Type of offer.

## `baContract` (type: `string`):

Permanent or temporary contracts.

## `baIncludeTempAgencies` (type: `boolean`):

Turn off to exclude jobs from temp agencies (Zeitarbeit).

## `baEmployer` (type: `string`):

Only jobs from this employer (optional).

## `euresLocations` (type: `array`):

Country codes (at, ch, de, nl, ...) or NUTS region codes (e.g. at13 = Vienna). Default Austria and Switzerland (Germany is covered best by the Bundesagentur source).

## `euresKeywordIn` (type: `string`):

Job title only (precise, faster) or anywhere in the ad (broader).

## `onlyNewJobs` (type: `boolean`):

Return only jobs not returned by previous runs with the same searches and state key. Ideal for daily schedules. The first run returns everything.

## `stateKey` (type: `string`):

Name of the monitoring state. Use different keys for different schedules.

## `maxConcurrency` (type: `integer`):

How many job details are fetched at once (Germany).

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

Not needed normally.

## Actor input object example

```json
{
  "keywords": [
    "Data Analyst"
  ],
  "sources": [
    "arbeitsagentur",
    "eures"
  ],
  "maxResultsPerSearch": 100,
  "publishedWithinDays": 0,
  "workTime": [],
  "includeDescription": true,
  "strictTitleMatch": false,
  "baLocations": [],
  "baRadiusKm": 25,
  "baOfferType": "job",
  "baContract": "any",
  "baIncludeTempAgencies": true,
  "baEmployer": "",
  "euresLocations": [
    "at",
    "ch"
  ],
  "euresKeywordIn": "TITLE",
  "onlyNewJobs": false,
  "stateKey": "default",
  "maxConcurrency": 16,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Normalized jobs from all searches.

## `searches` (type: `string`):

For every search: source, keyword, location, jobs available, fetched and saved, errors.

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

Totals for the run.

# 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 = {
    "keywords": [
        "Data Analyst"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("tinyrex/dach-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 = { "keywords": ["Data Analyst"] }

# Run the Actor and wait for it to finish
run = client.actor("tinyrex/dach-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 '{
  "keywords": [
    "Data Analyst"
  ]
}' |
apify call tinyrex/dach-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,tinyrex/dach-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/h3IDR8wzgzu9MOquz/builds/mIEbew5oqMrb3I0G2/openapi.json
