# Arbeitsagentur Jobs Scraper | Employer Profiles & Contacts (`corvuslab/arbeitsagentur-jobs-scraper`) Actor

Scrape every job, apprenticeship and internship on arbeitsagentur.de (Bundesagentur für Arbeit), past the 10,000-result limit. 82 fields: salary, contract, home office, GPS, full description, employer website, size, benefits, social media, emails and phones. Incremental + alerts.

- **URL**: https://apify.com/corvuslab/arbeitsagentur-jobs-scraper.md
- **Developed by:** [Corvuslab](https://apify.com/corvuslab) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.63 / 1,000 results

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

### What does Arbeitsagentur Jobs Scraper do?

Arbeitsagentur Jobs Scraper extracts jobs, apprenticeships, dual study programmes and internships from **[arbeitsagentur.de](https://www.arbeitsagentur.de/jobsuche/)**, the job board of the Bundesagentur für Arbeit and Germany's largest, with about **1 million open listings**. Give it search terms, places and any of the site's filters (or paste a search URL), and every matching job comes back as a clean record with up to **83 fields**: salary, contract, home office, GPS coordinates, the full description, the **employer's company profile** and the **emails and phones** found in the ad. Export to JSON, CSV or Excel, use the API, or hand the data to an AI agent. No code needed.

> New to Apify? Sign up free and use the included monthly platform credit to try this Actor. No credit card needed.

**Why this scraper**

- 📚 **Complete, not capped**: reads every matching job, even when the site only lists the first 10,000.
- 🏢 **Company and contact data by default**: no extra settings, no extra cost per job.
- ⚡ **Fast and low-cost**: lightweight requests, no proxy needed.
- ♻️ **Built for monitoring**: incremental mode plus Telegram, Slack, Discord and webhook alerts.

***

### What data can you extract from Arbeitsagentur?

| Group | Fields |
|---|---|
| **Job** | `id`, `title`, `url`, `jobType` (job / apprenticeship / internship / self-employment), `occupation`, `occupations`, `startDate`, `postedAt`, `publishedFrom`, `modifiedAt` |
| **Location** | `location`, `postalCode`, `street`, `region` (federal state), `country`, `countryCode`, `latitude`, `longitude`, `locations` (every site of a multi-site job), `distanceKm` from your search location |
| **Pay & conditions** | `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod` (hour / month / year), `salaryText`, `contractDuration` (permanent / fixed-term / not stated), `contractDurationMonths`, `contractEndDate`, `workingTime`, `isFullTime`, `isPartTime`, `isShiftWork`, `isMiniJob`, `isRemotePossible`, `remoteType`, `remotePercent` |
| **Apprenticeships** | `educationRequired`, `apprenticeshipType`, `apprenticeshipPay` (by year), `studyProgram`, `studyForm` |
| **Company profile** | `company`, `employerId`, `employerWebsite`, `employerLinks`, `employerDescription`, `employerSize`, `employerFoundedYear`, `employerHeadquarters`, `employerBenefits`, `employerKeywords`, `socialProfiles` (LinkedIn, Instagram, XING, kununu, …), `employerContact` |
| **Contacts** | `extractedEmails`, `extractedPhones`, `extractedUrls` from the ad and the company profile |
| **Flags & source** | `isTemporaryAgency`, `isPrivatePlacement`, `isDisabilityFriendly`, `isCareerChangeFriendly`, `isAgencySupported`, `isExternal`, `externalUrl` (the original ad), `sourcePartner`, `sourcePartnerUrl`, `cipherNumber` |
| **Description & run** | `description`, `descriptionHtml`, `descriptionMarkdown`, `searchKeyword`, `searchLocation`, `source`, `scrapedAt`, `detailFetched`, `contentHash` |
| **Monitoring** (incremental mode only) | `changeType`, `firstSeenAt`, `lastSeenAt`, `previousSeenAt`, `expiredAt`, `isRepost`, `repostOfId`, `repostDetectedAt` |

**How often each field is filled**, measured on 1,500 real jobs: **53 %** have an email or phone (emails 43 %, phones 35 %), **52 %** the employer's website, **35 %** a company description, **17 %** a benefits list, **12 %** social media or an HR contact, **28 %** a structured salary and **49 %** say whether home office is possible. Apprenticeship fields are filled on apprenticeships only.

***

### Key features

- 📚 **Every matching job, past the 10,000 limit.** Larger searches are split into smaller ones automatically and merged without duplicates, so `maxResults: 0` returns all matches.
- 🏢 **Employer profile on every job that has one.** Website, description, size, founding year, headquarters, benefits, keywords, social media and the published HR contact, filled in rather than left empty.
- 📇 **Contacts for lead generation.** German phone formats are handled correctly, and postcodes or reference numbers are never mistaken for phone numbers.
- 🔎 **Many searches in one run.** Several search terms × several locations, merged and de-duplicated.
- 🎚️ **Every site filter, applied by the site.** You never pay for jobs you filtered out. Partial employer and occupation-field names are resolved to the site's exact names, and `Muenchen` still finds München.
- 🆕 **Newest first.** Sort by newest, recently updated or distance, so a capped run returns the jobs you care about.
- 🧾 **Consistent columns.** Every record in a run has the same fields (missing values are `null`), and fields your settings can't fill are left out, so CSV and Excel exports stay clean.
- 🤖 **AI-ready.** Compact mode, drop-empty mode and a description length limit keep payloads small for LLMs and MCP.

***

### 🚀 How to scrape Arbeitsagentur

1. Enter one or more **search terms** (e.g. `Pflegefachkraft`) and **locations** (e.g. `Hamburg`), then pick filters. Or paste an arbeitsagentur.de URL.
2. Set **Max results** (0 = every matching job).
3. (Optional) Turn on **incremental mode** and a **notification** channel, then **Schedule** it.
4. Click **Start** and download the results as **JSON, CSV or Excel**, or pull them from the **API**.

No login, cookies or proxy needed.

#### Quick-start example input

```json
{
  "searchTerms": ["Pflegefachkraft"],
  "locations": ["Hamburg"],
  "radiusKm": 25,
  "postedWithinDays": 7,
  "excludeTemporaryAgencies": true,
  "maxResults": 200
}
```

This returns up to 200 nursing jobs within 25 km of Hamburg posted in the last week, without temporary staffing agencies, each with salary, contract, full description, the hiring company's profile and any email or phone in the ad: a ready-to-call list of employers hiring right now.

***

### Input

Everything can be set in the visual editor or passed as JSON through the API. There are **40 inputs**, grouped as in the editor. Leave everything empty to get the 25 newest jobs from all of Germany.

#### 🔎 Search

| Field | Type | What it does |
|---|---|---|
| `searchTerms` | array | Job titles, skills or occupations in German or English. Each term runs as its own search. Empty = every job matching your filters. |
| `locations` | array | German cities, towns, postcodes or federal states (`Berlin`, `10115`, `Bayern`). Each runs as its own search. Empty = all of Germany. |
| `radiusKm` | integer | Distance around each location, 0–200 km (site default 25). |
| `startUrls` | array | arbeitsagentur.de search URLs (with any filters set on the site) or single job URLs. |
| `maxResults` | integer | Cap on jobs across all searches (default 25; 0 = every matching job). |
| `sortBy` | enum | `relevance` (default), `newest`, `recentlyModified` or `distance` (needs a city or postcode with a radius). |

#### 🎚️ Filters

Several values inside one filter widen the search (OR); different filters narrow it (AND).

| Field | Type | What it does |
|---|---|---|
| `jobTypes` | array | `job`, `apprenticeship` (Ausbildung + dual study), `internship`, `selfEmployment`. |
| `workingTime` | array | `fullTime`, `partTime`, `shiftNightWeekend`, `miniJob`. |
| `remoteOnly` | boolean | Only jobs where home office is possible. |
| `contractDuration` | array | `permanent`, `fixedTerm`, `notStated`. |
| `postedWithinDays` | integer | Only jobs published in the last N days (1–100). |
| `employers` | array | Only these employers. A partial name matches every registered company name containing it. |
| `occupationFields` | array | The site's occupation fields (Berufsfelder), e.g. `Informatik`, `Altenpflege`. Partial names allowed. |
| `excludeTemporaryAgencies` | boolean | Hide temporary staffing agencies (Zeitarbeit). |
| `excludePrivatePlacement` | boolean | Hide private recruiters. |
| `excludeExternalBoards` | boolean | Keep only jobs posted on arbeitsagentur.de itself, not ones copied from partner job boards. |
| `disabilityFriendlyOnly` | boolean | Only jobs marked suitable for applicants with a severe disability. |
| `careerChangersOnly` | boolean | Only jobs open to career changers (Quereinstieg). |

#### 📄 Output

| Field | Type | What it does |
|---|---|---|
| `includeDetails` | boolean | Fetch each job's full page: description, education, agency flags, partner board (default on). |
| `includeEmployerProfile` | boolean | Add the employer's company profile and its contacts (default on). |
| `descriptionFormat` | enum | `all`, `text`, `html` or `markdown`. |
| `descriptionMaxLength` | integer | Cut descriptions to N characters (0 = full length). |
| `compact` | boolean | 19 core fields only, for AI agents and MCP clients. |
| `excludeEmptyFields` | boolean | Drop null and empty fields. |

**♻️ Incremental monitoring** and **🔔 Notifications** inputs are described in their own sections below. **⚙️ Advanced**: `proxyConfiguration` (optional, off by default), `ignoreUrlFailures` (skip unreadable start URLs) and `maxRequestRetries` (0–10).

#### More example inputs

Every apprenticeship and dual study place in Bavaria:

```json
{ "jobTypes": ["apprenticeship"], "locations": ["Bayern"], "maxResults": 0 }
```

One employer's newest IT openings in three cities, with a daily Telegram alert:

```json
{
  "searchTerms": ["Informatiker", "Softwareentwickler"],
  "locations": ["Berlin", "München", "Hamburg"],
  "employers": ["Deutsche Bahn"],
  "sortBy": "newest",
  "maxResults": 0,
  "incrementalMode": true,
  "notifyOnlyChanges": true,
  "telegramToken": "<your bot token>",
  "telegramChatId": "@yourchannel"
}
```

A search you already built on the site:

```json
{
  "startUrls": [{ "url": "https://www.arbeitsagentur.de/jobsuche/suche?was=Elektriker&wo=Köln&umkreis=25" }],
  "maxResults": 500
}
```

***

### Output

Each dataset item is one job. A real record (description shortened):

```json
{
  "id": "10001-1003806153-S",
  "title": "Kaufmännischer Mitarbeiter (w/m/d)",
  "company": "SCHNOOR Industrieelektronik GmbH",
  "url": "https://www.arbeitsagentur.de/jobsuche/jobdetail/10001-1003806153-S",
  "jobType": "job",
  "occupation": "Kaufmann/-frau - Büromanagement",
  "occupations": ["Kaufmann/-frau - Büromanagement", "Projektassistent/in"],
  "location": "Büdelsdorf",
  "postalCode": "24782",
  "street": "Fehmarnstr. 6",
  "region": "Schleswig-Holstein",
  "country": "Germany",
  "countryCode": "DE",
  "latitude": 54.323388,
  "longitude": 9.698409,
  "workingTime": ["fullTime"],
  "isFullTime": true,
  "startDate": "2026-10-06",
  "postedAt": "2026-10-06",
  "modifiedAt": "2026-10-06T16:44:57.524",
  "salaryMin": 36000.0,
  "salaryMax": 42000.0,
  "salaryCurrency": "EUR",
  "salaryPeriod": "year",
  "salaryText": "36,000–42,000 EUR per year",
  "contractDuration": "permanent",
  "isRemotePossible": true,
  "description": "Du hast Freude an organisatorischen und kaufmännischen Aufgaben und gleichzeitig ein Interesse an technischen Themen? …",
  "extractedEmails": ["bewerbung@schnoor-ins.com"],
  "extractedPhones": ["+49 4331 34 76 - 0"],
  "employerWebsite": "http://www.schnoor-ins.com",
  "employerDescription": "Wir bei SCHNOOR Industrieelektronik sorgen als eines der führenden Unternehmen im Bereich der professionellen Funktechnik …",
  "employerSize": "mittelständisch",
  "employerFoundedYear": 1990,
  "employerHeadquarters": "Büdelsdorf",
  "employerBenefits": ["Flexible Arbeitszeiten", "Homeoffice / Mobiles Arbeiten", "Betriebliche Altersvorsorge", "Jobrad", "Weiterbildungen"],
  "employerKeywords": ["Elektrotechnik", "Funk", "Nachrichtentechnik", "Industrieelektronik", "Systemtechnik"],
  "socialProfiles": {
    "instagram": "https://www.instagram.com/schnoor_industrieelektronik/",
    "linkedin": "https://de.linkedin.com/company/schnoor-industrieelektronik-gmbh-&-co-kg"
  },
  "source": "arbeitsagentur.de",
  "scrapedAt": "2026-10-11T10:08:39.095955+00:00",
  "detailFetched": true
}
```

What each setting adds:

- **Search results alone** (details and employer profile off) already carry title, employer, place, dates, working time, salary, contract, home office and the partner-board link. Fastest and leanest.
- **Full details** (on by default) add the description, education and apprenticeship data, agency and recruiter flags, the partner board, and contacts from the ad.
- **Employer profile** (on by default) adds the company data and its published contacts.
- **Incremental mode** adds the monitoring fields.

**Compact mode** returns 19 core fields, and **`excludeEmptyFields`** removes empty ones. The Output tab has two ready-made views: **Overview** (title, employer, place, state, occupation, working time, contract, salary, posting date, link) and **Contacts & company** (employer, website, emails, phones, company size, temp-agency flag, link).

***

### ♻️ How to monitor Arbeitsagentur with incremental mode

Schedule the Actor and turn on **incremental mode**. Each run compares against the previous one and returns only **NEW / UPDATED / REAPPEARED** jobs. Unchanged jobs are recognised *before* their details are fetched, so they cost neither time nor money.

| | First run (baseline) | Next run (nothing changed) |
|---|---|---|
| Jobs found | all | all |
| Detail pages fetched | all | **none** |
| Records returned & billed | all | **none** |

After the baseline, your cost depends on how much the job board changes, not on how many jobs you watch:

| Daily churn | of 1,000 tracked | billable records | you save |
|---|---|---|---|
| 5 % | 1,000 | 50 | **95 %** |
| 15 % | 1,000 | 150 | **85 %** |
| 30 % | 1,000 | 300 | **70 %** |

| Field | Type | What it does |
|---|---|---|
| `incrementalMode` | boolean | Track jobs between runs and only return what changed. |
| `stateKey` | string | Name for the tracked search (derived from your search settings if empty). |
| `emitUnchanged` | boolean | Also return unchanged jobs. |
| `emitExpired` | boolean | Also return jobs that were open last run and are gone now. |
| `skipReposts` | boolean | Leave out jobs an employer took down and posted again under a new link (same title, company and place). Not charged. |

#### Setting up scheduled monitoring

1. Configure search terms, locations and filters.
2. Turn on **Incremental mode** and set **Max results** to 0 so the whole search is read (or keep a cap and sort by **newest**).
3. Run it once to create the baseline.
4. Open the **Schedules** tab and add a recurring run (e.g. every morning).
5. Add an alert channel (next section) with **Alert only on changes** on.

***

### 🔔 How to set up Arbeitsagentur alerts

Get a message as soon as a matching job is posted. Fill in only the channels you want. Credentials are secret inputs: encrypted at rest, masked in the UI and never written to the run log.

| Field | What to configure |
|---|---|
| ✈️ `telegramToken` + `telegramChatId` | Bot token from @BotFather + chat or channel ID |
| 💬 `slackWebhookUrl` | Slack Incoming Webhook URL |
| 🎮 `discordWebhookUrl` | Discord channel webhook URL |
| 🪝 `webhookUrl` + `webhookHeaders` | Structured JSON to n8n, Make, Zapier or your own backend |
| `notificationLimit` | Jobs per message (1–20) |
| `notifyOnlyChanges` | Alert only on new, updated and reappeared jobs |

Each message lists title, employer, salary, change type and link. Channels work independently, so one failing can't stop the scrape.

***

### 💡 What can you do with Arbeitsagentur data?

#### Recruitment and staffing lead generation

Every job is a company hiring right now, often with an email or phone and the company website. Exclude temporary agencies and private recruiters for a clean list of direct employers.

#### B2B sales prospecting with company profiles

Segment hiring companies by size, founding year, headquarters and industry keywords, and enrich your CRM with their LinkedIn and Instagram links.

#### Salary benchmarking in Germany

Compare structured pay bands by occupation, federal state and contract type, and track them over time.

#### Labour market research

Count openings by occupation field, region, working time or home-office share, with complete nationwide totals.

#### Apprenticeship and early-career tracking

Collect every Ausbildung, dual study and internship place with education requirements and apprenticeship pay, for schools, career services and education platforms.

#### Feed AI agents and LLM pipelines

Send compact JSON straight into an LLM context, an MCP tool or a vector store.

***

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

This Actor uses Apify's **pay-per-event** model: a small fee when a run starts, plus a fee per job returned. The **Pricing** tab shows the current numbers. Full details and employer profiles are included at no extra cost per job.

Three things lower the bill: **site-side filters** (filtered-out jobs are never fetched or billed), **incremental mode** (after the baseline you pay only for changes) and **skip re-posts**. A maximum cost per run set in the Console is respected: the run stops cleanly at it.

***

### 🔌 Integrations & export

Export to **JSON, CSV, Excel** or an HTML table, or use the **REST API** and the **JavaScript / Python** clients. Run it on a **schedule**, connect it to **Google Sheets, Slack, Make, Zapier and n8n**, or use it as an **MCP tool** for AI agents.

Also covering the German job market: [StepStone Job Scraper](https://apify.com/corvuslab/stepstone-jobs-scraper) for DE + AT jobs, and [kununu Company Profile Scraper](https://apify.com/corvuslab/kununu-scraper) for employer ratings that pair with this Actor's company profiles.

***

### 🔗 Using the API

Example with the Apify Python client:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")

run_input = {
    "searchTerms": ["Elektriker"],
    "locations": ["Köln"],
    "radiusKm": 30,
    "sortBy": "newest",
    "maxResults": 100,
}

run = client.actor("corvuslab/arbeitsagentur-jobs-scraper").call(run_input=run_input)

for job in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(job["title"], job["company"], job.get("employerWebsite"), job.get("extractedEmails"))
```

***

### ❓ FAQ

**Can it really get more than 10,000 jobs from one search?** Yes. arbeitsagentur.de only lists the first 10,000 results of a search, so bigger searches are split into parts that fit and merged. One run returns up to 100,000 jobs; to cover the whole board (about 1 million listings), split it across runs, for example by federal state or occupation field.

**Do I need an account for arbeitsagentur.de?** No. The Actor reads the public job board.

**Why is the salary empty on most jobs?** Employers don't have to publish pay, and only about 28 % give a structured salary. Sometimes the pay is mentioned in the description instead. Salary figures are shown as the employer entered them, so an occasional wrong period (a monthly amount marked as yearly) comes from the ad itself.

**Why do some jobs have no company website or description?** These come from the employer's public profile, and not every company has filled one in. Jobs posted anonymously under a box number (`cipherNumber`) usually have no profile.

**Why is there no email or phone on many jobs?** Many employers ask you to apply through their own website. The application link is then in `extractedUrls` or `externalUrl`.

**What are jobs from partner job boards?** Part of the listings are copied from partner job boards. They have `isExternal: true`, `externalUrl` (the original ad) and `sourcePartner`. Use `excludeExternalBoards` to keep only jobs posted directly on the site.

**Why are `educationRequired` and `apprenticeshipPay` empty?** They apply only to apprenticeships and dual study places, and few of those state the pay. Use `jobTypes: ["apprenticeship"]` to focus on them.

**Does it cover jobs outside Germany?** The board also lists some jobs in Austria, Switzerland and other countries. `country` and `countryCode` let you keep or drop them.

**Will I get EXPIRED jobs on every run?** Only when a run reads your whole search: Max results 0 and fewer than 10,000 matches (narrow by location if needed). A run that stopped early can't tell which unread jobs are gone, so it never marks them expired by mistake.

***

### ⚖️ Is it legal to scrape Arbeitsagentur?

This Actor only collects **publicly available** job ads and public employer profiles from arbeitsagentur.de. You are responsible for how you use the data, especially personal information such as a named HR contact, email address or phone number, and for complying with the site's terms and applicable law, including the GDPR and the German Federal Data Protection Act (BDSG) for outreach. This Actor is not affiliated with, endorsed by or sponsored by the Bundesagentur für Arbeit.

***

**Keywords:** arbeitsagentur scraper · arbeitsagentur.de scraper · arbeitsagentur api · bundesagentur für arbeit scraper · jobbörse scraper · german job scraper · germany jobs data · ausbildung scraper · apprenticeships germany · german employer contacts · company profiles germany · salary data germany · job monitoring · recruitment lead generation · export to CSV · export to Excel · no-code scraper · MCP tool for AI agents

# Changelog

This Actor's version history is a separate document: https://apify.com/corvuslab/arbeitsagentur-jobs-scraper/changelog.md

# Actor input Schema

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

Job titles, skills or occupations, in German or English, e.g. <code>Softwareentwickler</code>, <code>Pflegefachkraft</code>, <code>Elektriker</code>, <code>Lagerhelfer</code>. Leave empty for every job matching your filters.

## `locations` (type: `array`):

German cities, towns, postcodes or federal states, e.g. <code>Berlin</code>, <code>München</code>, <code>10115</code>, <code>Bayern</code>. Each location runs as its own search. Leave empty for the whole country.

## `radiusKm` (type: `integer`):

Distance around each location. The site uses 25 km when this is left empty; 0 = the place itself only. Maximum 200.

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

Paste arbeitsagentur.de job search URLs (with all the filters you set on the site) or single job URLs. When search URLs are given, the search terms and filters above are not used.

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

Maximum number of jobs to return across all searches. Set 0 for every matching job — searches bigger than the site lists at once are read in slices automatically.

## `sortBy` (type: `string`):

Order in which jobs are read — it decides which jobs you get when Max results stops the run early. Newest first is the best fit for scheduled monitoring. Distance needs a city or postcode with a radius.

## `jobTypes` (type: `array`):

Regular jobs, apprenticeships and dual study programmes, internships/trainee programmes, or self-employment. Empty = all types.

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

Full-time, part-time, shift/night/weekend work or mini-jobs. Empty = any.

## `remoteOnly` (type: `boolean`):

Only jobs where the employer offers working from home.

## `contractDuration` (type: `array`):

Permanent, fixed-term, or not stated. Empty = any.

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

Only jobs published in the last N days (1–100). Empty or 0 = any time.

## `employers` (type: `array`):

Only jobs from these employers, e.g. <code>Deutsche Bahn</code>, <code>ALDI SÜD</code>. A partial name matches every registered company name containing it.

## `occupationFields` (type: `array`):

The site's occupation fields (Berufsfelder), e.g. <code>Informatik</code>, <code>Altenpflege</code>, <code>Elektrotechnik</code>, <code>Gastronomie</code>. A partial name matches every field containing it.

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

Hide jobs from temporary staffing agencies.

## `excludePrivatePlacement` (type: `boolean`):

Hide jobs posted by private placement agencies (private Arbeitsvermittlung).

## `excludeExternalBoards` (type: `boolean`):

Keep only jobs posted on arbeitsagentur.de itself, not ones mirrored from partner job boards.

## `disabilityFriendlyOnly` (type: `boolean`):

Only jobs the employer marked as suitable for applicants with a severe disability.

## `careerChangersOnly` (type: `boolean`):

Only jobs the employer marked as open to career changers.

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

Fetch each job's full page: description, salary, education required, contract details, home-office option and the employer's partner-board link. Turn off for fast, lighter listing-only results.

## `includeEmployerProfile` (type: `boolean`):

Add the employer's public company profile where it has one: website, description, size, founding year, headquarters, benefits, social media and the published HR contact.

## `descriptionFormat` (type: `string`):

Which representation(s) of the job description to include.

## `descriptionMaxLength` (type: `integer`):

Cut descriptions to this many characters. 0 = full length.

## `compact` (type: `boolean`):

Emit only the core fields (title, company, location, occupation, salary, contract, link). Ideal for AI agents and MCP clients.

## `excludeEmptyFields` (type: `boolean`):

Remove null, empty-string and empty-list fields from each record.

## `incrementalMode` (type: `boolean`):

Track jobs between runs and tag every record NEW / UPDATED / UNCHANGED / EXPIRED. Unchanged jobs are skipped and not charged.

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

Stable name for the tracked search. Leave empty to derive one automatically from your search settings.

## `emitUnchanged` (type: `boolean`):

Also emit jobs that have not changed since the previous run.

## `emitExpired` (type: `boolean`):

Emit jobs that were open last run but are gone now. Needs a run that reads the whole search (Max results 0 or above the number of matches).

## `skipReposts` (type: `boolean`):

Leave out jobs that an employer took down and posted again under a new link (same title, company and location as a job already tracked). They are not charged. Every new job still carries isRepost either way.

## `telegramToken` (type: `string`):

Bot token from @BotFather.

## `telegramChatId` (type: `string`):

Chat or channel ID, e.g. "-100123456789" or "@yourchannel".

## `slackWebhookUrl` (type: `string`):

Slack incoming-webhook URL.

## `discordWebhookUrl` (type: `string`):

Discord incoming-webhook URL.

## `webhookUrl` (type: `string`):

Any HTTPS endpoint. Receives a JSON POST with the matched jobs — works with n8n, Make and Zapier.

## `webhookHeaders` (type: `object`):

Extra headers for the webhook request, e.g. {"Authorization": "Bearer xyz"}.

## `notificationLimit` (type: `integer`):

How many jobs to include in each notification message.

## `notifyOnlyChanges` (type: `boolean`):

In incremental mode, alerts list only new, updated and reappeared jobs, even when Include unchanged jobs is on.

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

Optional. Not needed — the actor works without a proxy. Enable it only if your runs get refused.

## `ignoreUrlFailures` (type: `boolean`):

Skip start URLs that cannot be interpreted instead of failing the whole run.

## `maxRequestRetries` (type: `integer`):

How many times to retry a failed request before giving up on it.

## Actor input object example

```json
{
  "searchTerms": [
    "Softwareentwickler"
  ],
  "maxResults": 25,
  "sortBy": "relevance",
  "remoteOnly": false,
  "excludeTemporaryAgencies": false,
  "excludePrivatePlacement": false,
  "excludeExternalBoards": false,
  "disabilityFriendlyOnly": false,
  "careerChangersOnly": false,
  "includeDetails": true,
  "includeEmployerProfile": true,
  "descriptionFormat": "all",
  "descriptionMaxLength": 0,
  "compact": false,
  "excludeEmptyFields": false,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "skipReposts": false,
  "notificationLimit": 5,
  "notifyOnlyChanges": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "ignoreUrlFailures": true,
  "maxRequestRetries": 3
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `leads` (type: `string`):

No description

## `allItems` (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"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("corvuslab/arbeitsagentur-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 = { "searchTerms": ["Softwareentwickler"] }

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

```

## MCP server setup

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