Arbeitsagentur Scraper · German Federal Job Board Listings
Pricing
from $1.10 / 1,000 job returneds
Arbeitsagentur Scraper · German Federal Job Board Listings
Arbeitsagentur jobs scraper for Germany's federal employment agency (arbeitsagentur.de / Bundesagentur für Arbeit). Scrape German job listings with employer, salary, location, and contact details.
Pricing
from $1.10 / 1,000 job returneds
Rating
0.0
(0)
Developer
Tarek Etman
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 hours ago
Last modified
Categories
Share

Arbeitsagentur Scraper · German Federal Job Board Listings
Arbeitsagentur jobs scraper for Germany's federal job board (arbeitsagentur.de / Bundesagentur für Arbeit). Search and scrape German job listings by keyword, location, radius, employer, contract type, or publication date.
Maintained by reapX. Every row cites the Apify run that produced it — nothing is inferred, modelled or filled in, and a field absent from the source is absent from the row. The extracted archive for this source is browsable at reapx.dev/data/arbeitsagentur-scraper/ and mirrored as an open dataset on Hugging Face and Kaggle. Questions: reapxdev@proton.me
Just under a million postings are live on the board at any time. This Arbeitsagentur scraper reads the agency's own public search service, returning structured job listings from arbeitsagentur.de without a browser.
Search German jobs by keyword and location
Set Job title or keyword in German - Pflegefachkraft, Softwareentwickler, LKW-Fahrer - and optionally a city or postal code with a radius. A radius search also fills in the distance from your search point on every row, which is what you want for catchment analysis.
Leave every field empty and you get the most recent listings nationwide.
Filter by working time and contract type
Working time covers Vollzeit, Teilzeit, shift work, Heimarbeit and Minijob. Contract type separates permanent (unbefristet) from fixed-term (befristet). Exclude temp agencies drops Zeitarbeit staffing firms and leaves only direct employers, which is usually what a hiring-market analysis wants.
Monitor new German job postings
Set Published within the last N days to 1 and schedule the Actor daily. Deduplicate on referenceNumber, which is permanent per posting. modifiedAt moves when an employer edits a live posting, so you can catch changes as well as new listings.
Track a single employer's hiring
Set Employer name to a company - SAP, Siemens, Charité - and you get that employer's open roles across Germany. Every row also carries employerHash, a stable pseudonymous key that groups postings from one employer even when the displayed name varies between them.
What data you get
Every row contains the reference number, job title, standardised occupation, employer, city, postal code, region, country, street where published, latitude and longitude, distance from your search point, publication date, start date, last-modified timestamp, the stable employer key, and a direct posting URL.
Three views are provided: Jobs, Locations and Employers. Export as JSON, CSV, Excel or XML.
Input configuration
Every field is optional. The prefilled values below are what runs if you press Start without changing anything.
What and where
Both are optional. Leave them empty for the newest listings nationwide.
| Field | Type | Accepts | What it does |
|---|---|---|---|
what | string | free text | What to search for, in German. For example Pflege, Softwareentwickler, Verkäufer, LKW-Fahrer. Leave empty to search every occupation. Prefilled with "Softwareentwickler". |
where | string | free text | Where to search, for example Berlin, München, or 10115. Combine with a radius to cover the surrounding area. Prefilled with "Berlin". |
radiusKm | integer | 0 to 200 | How far around the city or postal code to search. Only applies when a location is set. Prefilled with 25. |
Filters
Narrow the result set. Every filter is optional.
| Field | Type | Accepts | What it does |
|---|---|---|---|
workingTime | string | one of 6: ``, vollzeit, teilzeit, schicht, ... | Restrict to one working-time model. Prefilled with "". |
contractType | string | ``, permanent, fixed-term | Permanent (unbefristet) or fixed-term (befristet). Prefilled with "". |
employer | string | free text | Restrict to one employer, for example SAP, Siemens, or Charité. |
publishedWithinDays | integer | 0 to 100 | Only postings published this recently. Use 1 for a daily monitor, 7 for a weekly one. |
excludeTempAgencies | true/false | checkbox | Drop postings from Zeitarbeit staffing agencies and keep only direct employers. |
Output
How many rows you get and how politely they are fetched.
| Field | Type | Accepts | What it does |
|---|---|---|---|
maxJobs | integer | 1 to 10000 | Hard ceiling on the rows this run produces, and therefore on what it costs. You are charged per job returned. Prefilled with 100. |
requestsPerSecond | integer | 1 to 8 | Politeness against the federal API. Lower this if you see the source refusing requests. Prefilled with 4. |
Pricing
Pay per event. The primary event is Job returned (job-returned), charged at $0.002 per event on the free plan, falling to $0.001 on the highest tier.
One job posting delivered as a complete row. Blocked sources and empty result sets are never charged.
Minimum charge cap per run: $0.02.
Tiered discounts apply automatically on every paid Apify plan. Platform usage is absorbed by the Actor, so the per-event price is the whole price.
Usage examples
The prefilled run, which is what Start does with nothing changed
{"what": "Softwareentwickler","where": "Berlin","radiusKm": 25,"maxJobs": 100,"requestsPerSecond": 4}
Filter by job title or keyword
{"what": "Pflegefachkraft","where": "Berlin","radiusKm": 25,"maxJobs": 100,"requestsPerSecond": 4}
Filter by city or postal code
{"what": "Softwareentwickler","where": "Hamburg","radiusKm": 25,"maxJobs": 100,"requestsPerSecond": 4}
Filter by working time
{"what": "Softwareentwickler","where": "Berlin","radiusKm": 25,"maxJobs": 100,"requestsPerSecond": 4,"workingTime": "vollzeit"}
Filter by contract type
{"what": "Softwareentwickler","where": "Berlin","radiusKm": 25,"maxJobs": 100,"requestsPerSecond": 4,"contractType": "permanent"}
Output example
One row, exactly as the actor wrote it to the dataset:
{"referenceNumber": "12322-YCXCE37Z5GDLME7F-S","jobTitle": "Softwareentwickler (m/w/d)","occupation": "Softwareentwickler/in","employer": "Walter-Fach-Kraft GmbH & Co. KG","city": "Frankfurt am Main","postalCode": "60386","region": "Hessen","country": "Deutschland","street": null,"latitude": 50.127193732,"longitude": 8.75386232,"distanceKm": "9","publishedAt": "2026-07-10","startsAt": "2026-07-10","modifiedAt": "2026-07-10T15:28:34.9","employerHash": "tGz4mt1QwIt4WuSPD3XLAf5n-JOVpy-PwfmLTcfuMp0=","jobUrl": "https://www.arbeitsagentur.de/jobsuche/jobdetail/12322-YCXCE37Z5GDLME7F-S","retrievedAt": "2026-08-03T00:37:23Z"}
Fields on every row
| Field | Type | What it is |
|---|---|---|
referenceNumber | string | The job board's own permanent identifier for this posting. Deduplicate on this across runs. |
jobTitle | string | Posting title exactly as the employer wrote it. |
occupation | string | Standardised occupation the federal agency classified the posting under. |
employer | string | Hiring organisation. Null on the small number of postings that withhold it. |
city | string | Place of work. |
postalCode | string | German postal code of the workplace. |
region | string | Federal state or region. |
country | string | Country of the workplace. Mostly Deutschland, occasionally a neighbouring country. |
street | string | Street address where the employer publishes one. About a third of postings do. |
latitude | number | Workplace latitude, for mapping and distance work. |
longitude | number | Workplace longitude. |
distanceKm | string | Kilometres from the searched location. Present only on runs that set a search radius. |
publishedAt | string | Date the posting was published, as YYYY-MM-DD. |
startsAt | string | Earliest start date the employer will accept, as YYYY-MM-DD. |
modifiedAt | string | Timestamp the posting was last changed. Use this to detect edits between runs. |
employerHash | string | Stable pseudonymous employer key. Groups postings from one employer even when the displayed name varies. |
jobUrl | string | Direct link to the posting on arbeitsagentur.de. |
retrievedAt | string | UTC timestamp this row was collected. |
3 named dataset views ship with it: Jobs, Locations, Employers. They drive the Output tab in Console and the Output block on the Actor's .md page.
FAQ
Do I need an API key or an account?
No. The Bundesagentur für Arbeit publishes this search service for public use and it needs no user credential.
Does the search work in English?
The job board's content is German, so German search terms return far more. nurse returns a handful; Pflegefachkraft returns tens of thousands.
How many jobs can one run return?
As many as you ask for. The service pages 100 at a time and this Actor follows the pages, so the practical limit is your Maximum jobs to return and your budget.
Why is the street address empty on some rows?
Because the employer did not publish one. About a third of postings include a street; all of them include a city and coordinates.
Can I get the full job description?
Not currently. The agency's posting-detail service rejects the public search key, so this Actor returns the search record only - which still carries title, occupation, employer, location, dates and the posting URL.
How do I detect new postings between runs?
Deduplicate on referenceNumber. It is permanent per posting and never reused.
Unofficial - not affiliated with Bundesagentur für Arbeit. Collects public data only. reapx. Contact reapxdev@proton.me.
The full published archive
- arbeitsagentur scraper archive — every entity this Actor has observed
- All reapx datasets — 20 sources, tens of thousands of pages
- llms.txt · feed.json · feed.xml — the machine-readable index, for agents
Each archive page carries Dataset JSON-LD, a canonical URL and the identifiers used, so an agent can resolve an entity without running anything. Nothing on those pages is estimated or modelled.
🧪 Example input
A real, runnable configuration — this is an actual input this Actor has run with.
{"what": "Softwareentwickler","where": "Frankfurt am Main","radiusKm": 25,"maxJobs": 500,"requestsPerSecond": 4}
📄 Sample output
One real row from a real run of this Actor, unedited.
{"referenceNumber": "12322-YCXCE37Z5GDLME7F-S","jobTitle": "Softwareentwickler (m/w/d)","occupation": "Softwareentwickler/in","employer": "Walter-Fach-Kraft GmbH & Co. KG","city": "Frankfurt am Main","postalCode": "60386","region": "Hessen","country": "Deutschland","street": null,"latitude": 50.127193732,"longitude": 8.75386232,"distanceKm": "9","publishedAt": "2026-07-10","startsAt": "2026-07-10","modifiedAt": "2026-07-10T15:28:34.9","employerHash": "tGz4mt1QwIt4WuSPD3XLAf5n-JOVpy-PwfmLTcfuMp0=","jobUrl": "https://www.arbeitsagentur.de/jobsuche/jobdetail/12322-YCXCE37Z5GDLME7F-S","retrievedAt": "2026-08-03T00:37:23Z"}
How it works
- You set the filters below, or none at all - every field is optional.
- The Actor calls the public rest.arbeitsagentur.de API directly over HTTP. There is no key to obtain, no login and no headless browser, so a run is fast and cannot break on a UI change.
- It pages through the results until your maximum is reached or the source runs out of matches.
- Every row is pushed to the dataset as it is built - never buffered to the end. A run that hits its time limit still returns everything it collected.
- You are charged
job-returnedat $0.002 per row, and nothing for Apify platform usage. The maximum-results field is therefore your cost cap, and Apify Store discounts apply on top.
💬 Your feedback
Found a bug, or need a field this does not return yet? Open an issue on the Actor's Issues tab, or write to reapxdev@proton.me. Bugs get fixed and reasonable field requests get added.
⚠️ Run outcomes and error handling
This Actor reports what happened in the run's status message, and it always keeps whatever it collected. These are the outcomes you can get and what each one means.
| Outcome | What it means |
|---|---|
| Success | Rows were returned and you were charged job-returned at $0.002 per row. |
| No matches | The source returned nothing for your filters. Nothing is charged. Widen the date window or drop a filter. |
| Partial - source refused | The source rate-limited or refused some requests. The affected items are skipped and named in the log, and everything already collected is still pushed. A block never discards a run's work. |
What is guaranteed either way
- Every row is pushed as it is built, not buffered to the end of the run. Anything that buffers output loses everything to a timeout, a block or a migration; this does not.
- A field absent from the source is absent from the row. Nothing is inferred, modelled or filled in to make a row look complete.
🧭 Ready-made configurations
These are saved, published configurations of this exact Actor. Open one and run it as it is, or copy its input as a starting point - each link is a live page with the full input and its output schema.
There are 50 of these in total, all listed on the Actor's Examples tab.