Germany Job Finder & Data Normalizer (BA API + ATS Feeds)
Pricing
Pay per usage
Germany Job Finder & Data Normalizer (BA API + ATS Feeds)
Multi-source job search actor for Germany. Extracts structured listings from the Bundesagentur für Arbeit API, Personio, Greenhouse, Lever, and SmartRecruiters. Normalizes salaries, seniority, skills, and locations.
Pricing
Pay per usage
Rating
0.0
(0)
Developer
Zaher el siddik
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
12 days ago
Last modified
Categories
Share
Germany Job Finder & Data Normalizer

Search the entire German job market from a single API. This Actor aggregates live job listings from the official Bundesagentur für Arbeit REST API and the public feeds of four major applicant tracking systems (Personio, Greenhouse, Lever, and SmartRecruiters), then normalizes every listing into one consistent JSON schema with enriched fields for salary, seniority, skills, contract type, and location.
Because it consumes structured API and XML streams rather than scraping fragile HTML pages, it runs without headless browsers, CAPTCHAs, or anti-bot blocking, and it does not break when career sites change their layout.
Contents
- What it does
- Data sources
- Key features
- Use cases
- Input parameters
- Output schema
- Performance and cost
- Running locally
- Integrations and API access
- FAQ
- Compliance
What it does
- Queries all selected sources concurrently with your keywords, location, and filters.
- Normalizes each raw listing into a single schema: parsed salary, resolved Bundesland and postal code, classified contract type, seniority level, workplace arrangement, and extracted tech skills.
- Filters out staffing agencies (Zeitarbeit), enforces recency and contract filters, and removes duplicates across sources.
- Pushes clean, deduplicated job objects to the dataset, ready for export as JSON, CSV, or Excel.
Data sources
| Source | Type | Coverage |
|---|---|---|
arbeitsagentur | Official REST API of the German Federal Employment Agency (Bundesagentur für Arbeit) | Nationwide, all industries; the largest job index in Germany |
personio | Personio ATS XML feeds | German SMEs, startups, and scaleups |
greenhouse | Greenhouse Job Board API | German tech scaleups and unicorns (HelloFresh, N26, SumUp, Celonis, Flix, and others) |
lever | Lever Postings API | Companies with German offices; results are restricted to postings located in Germany |
smartrecruiters | SmartRecruiters Postings API | Large German enterprises (Bosch, Delivery Hero, Sixt, Vattenfall); queried with country=de |
All company boards are verified as live. Boards that go offline are skipped gracefully without failing the run. All sources run concurrently for fast execution.
Key features
- Official API ingestion. No headless browsers, no CAPTCHAs, no anti-bot rate limiting. Direct JSON and XML streams keep runs fast, cheap, and reliable.
- Salary normalization. German salary expressions such as
50.000 EUR - 75.000 EUR pro Jahr,4.500 EUR / Monat, or60k - 80k EURare parsed into structured{ min, max, currency, interval }objects. Extraction is currency-anchored and context-validated, so arbitrary numbers or benefit amounts in long descriptions are never misread as salaries. - Seniority classification. Each listing is classified as
INTERN,JUNIOR,MID,SENIOR,LEAD, orUNKNOWNbased on German and English title conventions (Werkstudent, Praktikum, Berufseinsteiger, Senior, Head of, Leiter, and more). - Staffing agency filter. Listings from recruiters, headhunters, and Zeitarbeit agencies (Randstad, Adecco, Hays, Ferchau, Akkodis, GULP, and dozens more) are identified and excluded on request. For the Arbeitsagentur source this filter is additionally applied server-side.
- Skill and tech stack extraction. Over 60 technologies, frameworks, certifications, and enterprise tools (TypeScript, AWS, Kubernetes, SAP, DATEV, ISO 27001, GDPR/DSGVO, and others) are extracted into a clean array.
- Location resolution. German cities are mapped to their federal states (Bundesländer), 5-digit postal codes are extracted, and workplace arrangements are classified as
REMOTE,HYBRID, orON_SITE. - Umlaut-insensitive matching. Keyword and location filters treat
München/Muenchen/MunichandKöln/Cologneas equivalent, so no listings are missed due to spelling variants. - Cross-source deduplication. Identical positions appearing on multiple boards are removed using both source IDs and normalized company/title/city fingerprints.
Use cases
- Job seekers: monitor the German market for roles matching your skills, salary expectations, and preferred work arrangement, without checking a dozen portals.
- Recruiters and HR analysts: benchmark salaries, track hiring activity by company, region, or technology, and build talent market reports.
- Job boards and aggregators: feed a normalized, deduplicated stream of German listings directly into your product.
- Market researchers: analyze demand for technologies and skills across Bundesländer, industries, and seniority levels.
- Lead generation: identify companies that are actively hiring in a specific region or technology niche.
Input parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
keywords | Array | ["Softwareentwickler", "Cloud Engineer"] | Job titles or search terms in German or English. |
location | String | "Berlin" | Target city or region. Leave empty to search all of Germany. |
radiusKm | Integer | 50 | Search radius in kilometers around the target city (Arbeitsagentur only). |
sources | Array | all five | Data sources to query: arbeitsagentur, personio, greenhouse, lever, smartrecruiters. |
workplaceType | String | "ALL" | Filter: ALL, REMOTE, HYBRID, ON_SITE. Remote is also applied server-side on the Arbeitsagentur API. |
contractType | String | "ALL" | Filter: ALL, FULL_TIME, PART_TIME, MINIJOB, CONTRACT, DUAL_STUDY. |
excludeAgencies | Boolean | true | Exclude Zeitarbeit and recruiting agencies. |
extractSkills | Boolean | true | Extract technologies and tools into the skills array. |
postedWithinDays | Integer | 14 | Only return jobs published within the last N days (0 = any time). |
maxItems | Integer | 100 | Maximum number of jobs to return across all sources. |
Example input:
{"keywords": ["Softwareentwickler", "Cloud Engineer"],"location": "Berlin","radiusKm": 50,"sources": ["arbeitsagentur", "personio", "greenhouse", "lever", "smartrecruiters"],"workplaceType": "ALL","contractType": "ALL","excludeAgencies": true,"extractSkills": true,"postedWithinDays": 14,"maxItems": 200}
Tip: ATS boards (Personio, Greenhouse, Lever, SmartRecruiters) often carry postings older than two weeks. Set postedWithinDays to 0 and leave location empty to see their full volume.
Output schema
Each dataset item follows this structure:
{"id": "ba-10000-1189324501-S","title": "Senior Cloud Security Engineer (m/w/d)","company": {"name": "FinTech AG","domain": "fintech-example.de","isAgency": false},"location": {"city": "10115 Berlin","state": "Berlin","country": "DE","postalCode": "10115","workplaceType": "HYBRID"},"compensation": {"min": 75000,"max": 90000,"currency": "EUR","interval": "yearly","rawText": "75.000 EUR - 90.000 EUR pro Jahr"},"contractType": "FULL_TIME","experienceLevel": "SENIOR","skills": ["AWS", "Terraform", "Kubernetes", "SOC 2", "TypeScript"],"applyUrl": "https://www.arbeitsagentur.de/jobsuche/jobdetail/10000-1189324501-S","sourceUrl": "https://www.arbeitsagentur.de/jobsuche/jobdetail/10000-1189324501-S","source": "arbeitsagentur","postedAt": "2026-08-20T14:30:00Z","refNumber": "10000-1189324501-S","descriptionSnippet": "Beruf: Ingenieur/in - IT-Sicherheit"}
Field notes:
compensationisnullwhen the source provides no salary information. Most German listings do not publish salaries; expect salary data on a minority of records.experienceLevelis one ofINTERN,JUNIOR,MID,SENIOR,LEAD, orUNKNOWN.location.workplaceTypeisUNKNOWNwhen the listing does not state a work arrangement; such listings are kept when a workplace filter is active to avoid false negatives.
Performance and cost
The Actor uses plain HTTP requests against JSON and XML endpoints rather than headless browsers, so compute consumption is minimal:
- Approximately 0.02 compute units per 1,000 ingested jobs
- Typical execution time of 10 to 30 seconds for several hundred jobs, since all sources are queried concurrently
Running locally
npm installnpm run buildnpm start
Provide input in storage/key_value_stores/default/INPUT.json. Run the test suite with:
$npm test
Integrations and API access
Like any Apify Actor, results can be:
- Exported from the dataset as JSON, CSV, Excel, or XML
- Fetched programmatically via the Apify API or the JavaScript and Python clients
- Scheduled to run periodically and connected to Slack, email, Google Sheets, Zapier, or Make for automated job alerts
- Used as a data source in a larger Actor workflow
FAQ
Why do some sources return zero results for my query?
Each source is filtered by your keywords, location, contract, and recency settings. Narrow keywords with a city filter and a short postedWithinDays window can legitimately produce zero matches on the smaller ATS boards while the Arbeitsagentur source still returns hundreds.
Does it scrape LinkedIn, Indeed, or StepStone? No. Those platforms prohibit scraping and employ aggressive anti-bot measures. This Actor intentionally relies on the official federal API and public ATS feeds, which keeps it stable, legal, and fast.
How current are the listings?
Every run queries the sources live. Use postedWithinDays to restrict results to fresh postings.
Can more companies be added? Yes. The ATS company lists are curated constants in the source code and can be extended with any company slug that exposes a public Personio, Greenhouse, Lever, or SmartRecruiters board.
Compliance
This Actor queries public, documented endpoints only: the Bundesagentur für Arbeit open data API and the public postings APIs and feeds that applicant tracking systems expose for job distribution. It does not bypass authentication, does not collect personal data, and respects rate limits with retry backoff and per-feed request delays.
License
Apache-2.0