# Arbeitsagentur Jobs Scraper: German Jobs, Salaries, Full Text (`pikoulas/arbeitsagentur`) Actor

Scrape the Bundesagentur für Arbeit's Jobbörse, Germany's largest job board: jobs, apprenticeships and internships by keyword, place and filters, or by URL. Title, employer, salary range, location, hours, temporary agency, full description. No login.

- **URL**: https://apify.com/pikoulas/arbeitsagentur.md
- **Developed by:** [Spyridon Pikoulas](https://apify.com/pikoulas) (community)
- **Categories:** Jobs, Lead generation, AI
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 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.
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

## Arbeitsagentur Jobs Scraper: German Jobs, Salaries, Full Text

Scrape job ads from the Bundesagentur für Arbeit's Jobbörse (arbeitsagentur.de/jobsuche), Germany's
largest job board, with jobs from employers and from partner boards across the country, without an
account or a browser:

- **Search:** keywords and a place, with the Jobbörse's filters: distance, jobs, apprenticeships,
  internships or self-employment, full-time, part-time, shifts, home office or mini-job, permanent
  or fixed-term, days since posting, and no temporary agencies.
- **Search URLs:** paste a search from the Jobbörse, and the filters you set there come with it.
- **Job URLs:** any job by its link (`arbeitsagentur.de/jobsuche/jobdetail/<reference>`).
- **Every page of a search:** it pages on to the end, past 10,000 jobs for a broad search.

Every job comes with its reference number, title, employer, occupations, offer type, postcode, city
and state with coordinates for each place it's offered in, distance from your location, full-time,
part-time, shifts, home office, mini-job, the salary range where the employer gives one, an
apprenticeship's pay per year, permanent or fixed-term, start date, dates posted and updated, and
the partner board's link where the ad came from one. With details on, the default, it also comes
with the full description, the schooling asked for, and whether the job is through a temporary
agency or a private recruiter.

100 jobs with details take about a minute, and 100 without about 12 seconds. It costs **$0.50 per
1,000 jobs**, details included.

### What people use it for

- **Job market analysis:** who is hiring, where, and in which occupations, across Germany.
- **Lead generation:** employers hiring right now, by occupation and region.
- **Salary research:** the salary ranges employers give, and apprenticeship pay by year.
- **Job boards and alerts:** the day's new jobs for any search, every morning, through the API or a
  schedule.

### How to scrape the Arbeitsagentur Jobbörse

1. Click **Try for free**; Apify's free plan covers a first run.
2. Enter **Search terms** and a **Location**, or paste **Arbeitsagentur URLs**.
3. Click **Start**, then download the results as JSON, CSV, Excel or HTML, or read them through
   the API.

An input with more options:

```json
{
  "searchTerms": ["Pflegefachkraft", "Altenpfleger"],
  "location": "Hamburg",
  "distance": 25,
  "maxJobsPerSearch": 200,
  "includeDetails": true,
  "offerType": "job",
  "workingTime": ["partTime"],
  "contract": "permanent",
  "postedWithinDays": 7,
  "excludeTemporaryAgencies": true,
  "startUrls": ["https://www.arbeitsagentur.de/jobsuche/suche?was=Kaufmann&angebotsart=4"]
}
```

Each search term runs with the location and filters given; a search URL keeps its own. Leave the
location empty to search all of Germany, and turn off `includeDetails` for what the search list
shows.

### Output

```json
{
  "jobId": "12265-485644_JB5289422-S",
  "url": "https://www.arbeitsagentur.de/jobsuche/jobdetail/12265-485644_JB5289422-S",
  "title": "Softwareentwickler in Linux (m/w/d)",
  "company": "FERCHAU GmbH Niederlassung München Mobility",
  "occupation": "Softwareentwickler/in",
  "occupations": ["Softwareentwickler/in"],
  "offerType": "job",
  "apprenticeshipType": null,
  "city": "München",
  "postcode": "80687",
  "region": "BAYERN",
  "locations": [{"postcode": "80687", "city": "München", "street": null, "region": "BAYERN", "country": "DEUTSCHLAND", "latitude": 48.140433435, "longitude": 11.506015614}],
  "distanceKm": 5,
  "homeOffice": null,
  "fullTime": true,
  "partTime": false,
  "shifts": null,
  "miniJob": false,
  "salaryFrom": 60000,
  "salaryTo": 80000,
  "apprenticeshipPayPerYear": [],
  "contract": null,
  "fixedTermMonths": null,
  "startDate": "2026-11-03",
  "datePosted": "2026-11-03",
  "dateUpdated": "2026-11-03T07:44:29",
  "careerChangers": false,
  "externalUrl": null,
  "partner": "FERCHAU Engineering GmbH",
  "searchQuery": "Softwareentwickler in München",
  "description": "Du möchtest deine Karriereentwicklung nicht dem Zufall überlassen? ...",
  "education": null,
  "temporaryAgency": true,
  "privateRecruiter": false,
  "forSeverelyDisabled": false
}
```

`salaryFrom` and `salaryTo` are per year, given by few employers. `contract` is null where the ad
doesn't say. `externalUrl` is the partner board's page for jobs that came from one, where applying
happens. A job asked for by URL has no `distanceKm` and a `searchQuery` of null. Without details, a
job has the fields up to `searchQuery`, `partner` empty.

### Use it as an API

One call runs it and returns the results as JSON (for runs under 5 minutes; longer ones start a
run and read its dataset). Apify's Python and JavaScript clients, and its Make, Zapier and n8n
integrations, work the same way.

```bash
curl -X POST "https://api.apify.com/v2/acts/pikoulas~arbeitsagentur/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searchTerms": ["Softwareentwickler"], "location": "München", "maxJobsPerSearch": 20}'
```

AI agents can call it as a tool through Apify's MCP server: `https://mcp.apify.com?tools=pikoulas/arbeitsagentur`.

### How much does it cost to scrape the Arbeitsagentur?

You pay **$0.0005 per job**, which is $0.50 per 1,000 jobs, with or without details, on Apify's paid
plans, and $1 per 1,000 on the free plan. There are no monthly fees, and a search that finds
nothing costs nothing. Set a spending limit on a run and it stops there with what it has.

### Good to know

- A job found by several search terms is given once per run, under the first.
- Search pages are read 3 seconds apart: the site refuses faster paging for a while.
- Employers' contact people, which the Jobbörse shows only after a captcha, aren't collected.
- It reads the Jobbörse as a guest: it names itself in its User-Agent (`ArbeitsagenturActor`),
  keeps to the site's `robots.txt`, reads at a steady pace from one address, and uses no proxy. If
  the site answers with a check or a refusal, the run stops there and keeps what it has; the log
  says so.

### FAQ

#### Is it legal to scrape the Arbeitsagentur Jobbörse?

It collects only what the Jobbörse shows publicly, without logging in, and job ads rather than
people's profiles or contacts. [The Arbeitsagentur's terms](https://www.arbeitsagentur.de/nutzungsbedingungen)
prohibit this, and your use of it is your own responsibility. The EU's database right can also
protect a collection like its job listings, and personal data is protected by laws such as the
GDPR. If you're unsure, ask a lawyer; Apify's [Is web scraping
legal?](https://blog.apify.com/is-web-scraping-legal/) is a good start. This Actor isn't affiliated
with or endorsed by the Bundesagentur für Arbeit.

#### Something missing or not working?

Open an issue on the **Issues** tab with the input you used, or ask there for a field you need.

# Actor input Schema

## `searchTerms` (type: `array`):

Job titles, occupations or employers, as you'd type them in the Jobbörse, such as Pflegefachkraft or Softwareentwickler. Each is searched separately.

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

A town, city, state or postcode, such as München or 10115. Leave it empty for all of Germany.

## `distance` (type: `integer`):

How far from the location: 0, 10, 15, 20, 25, 50, 100 or 200 km. The Jobbörse's default is 25.

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

Job search pages (arbeitsagentur.de/jobsuche/suche?…), with any filters set there, or single job pages (…/jobsuche/jobdetail/<reference>).

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

Jobs taken from each search term or search URL, and so what a run can cost: each job is charged.

## `includeDetails` (type: `boolean`):

Opens each job for its full description, the education asked for, and whether it's through a temporary agency or a private recruiter. Off, a run is faster and gives what the search list shows.

## `offerType` (type: `string`):

Jobs, when empty.

## `workingTime` (type: `array`):

Any, when empty; several give jobs matching any of them.

## `contract` (type: `string`):

Both, when empty.

## `postedWithinDays` (type: `integer`):

Only jobs published in the last this many days; 0 is today.

## `excludeTemporaryAgencies` (type: `boolean`):

Leaves out jobs offered through temporary employment agencies (Zeitarbeit).

## Actor input object example

```json
{
  "searchTerms": [
    "Softwareentwickler"
  ],
  "location": "München",
  "maxJobsPerSearch": 20,
  "includeDetails": true,
  "excludeTemporaryAgencies": false
}
```

# Actor output Schema

## `overview` (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 = {
    "searchTerms": [
        "Softwareentwickler"
    ],
    "location": "München",
    "maxJobsPerSearch": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("pikoulas/arbeitsagentur").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 = {
    "searchTerms": ["Softwareentwickler"],
    "location": "München",
    "maxJobsPerSearch": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("pikoulas/arbeitsagentur").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 '{
  "searchTerms": [
    "Softwareentwickler"
  ],
  "location": "München",
  "maxJobsPerSearch": 20
}' |
apify call pikoulas/arbeitsagentur --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,pikoulas/arbeitsagentur"
        }
    }
}
```

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/c2zrDj8vgbb2zwKUU/builds/QSah7RmMraAJxhxWp/openapi.json
