# Germany Visa-Sponsored Jobs (`cg_nguyen/germany-visa-jobs`) Actor

Find Germany jobs that sponsor work visas (Blue Card, Skilled Worker, ICT). Pulls the federal Bundesagentur Jobboerse, enriches with full descriptions, classifies visa-sponsorship likelihood (regex + opt-in LLM tie-breaker), and dedupes across runs. For relocation services and intl. job seekers.

- **URL**: https://apify.com/cg\_nguyen/germany-visa-jobs.md
- **Developed by:** [CG Nguyễn](https://apify.com/cg_nguyen) (community)
- **Categories:** Jobs, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 enriched job results

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## germany-visa-jobs — German jobs that actually sponsor work visas, as a JSON feed

> **The Bundesagentur federal job board, filtered for visa sponsorship.** For relocation consultants, expat engineers, and AI agents who can't ask candidates "but will they sponsor?" one more time.

Searches Germany's federal job board (Bundesagentur für Arbeit Jobboerse, ~1.6M live listings) and emits structured JSON with a **visa-sponsorship classifier** stamped on every row: `confirmed | likely | unlikely | unknown`. Pay-per-result.

---

### Why this exists

The federal Bundesagentur board has every German job opening worth looking at — but it has no "sponsors visa" filter, no salary band, and no English search. So every Tier-3 country candidate, every relocation consultant, every AI job-search agent ends up doing the same thing: fetch a listing, eyeball the description for "visa sponsorship" / "Aufenthaltstitel" / "Blue Card", repeat 200 times.

This actor closes that gap. One API call, structured JSON, visa status pre-classified.

It is **not** a job board. There's no UI. You bring the automation; we bring the typed, deduplicated, classified data.

---

### Who it's for

| Persona | Use case |
|---|---|
| **Relocation consultancy** | Daily pull of `confirmed` + `likely` Berlin SWE roles into a Notion DB. Replace ~3 hrs/week per junior consultant. |
| **Expat job-mover** | Pipe new `confirmed`-status Blue Card roles for your stack into a personal Telegram bot. Apply within hours of listing. |
| **AI job-search agent (MCP)** | Apify Actors are auto-exposed as MCP tools. Claude /  / Codex agents call this when a user asks about visa-sponsoring German jobs. Zero integration work. |
| **Recruitment SaaS** | Source side of a visa-aware ATS. License via Apify Enterprise. |
| **Researcher / labour-market analyst** | Time-series of sponsorship signals across regions and professions. The federal API doesn't expose this — we synthesize it. |

---

### The moat: visa-sponsorship classifier

Every dataset row carries a `visaStatus` plus the evidence we used to label it.

| `visaStatus` | What it means | How we decide |
|---|---|---|
| `confirmed` | Multiple hard-positive sponsorship phrases. Apply with confidence. | ≥2 hard-positive signals AND no hard-negatives |
| `likely` | One explicit sponsorship phrase ("visa sponsorship", "Blue Card", "relocation support", "Aufenthaltstitel"). | ≥1 hard-positive AND no hard-negatives |
| `unlikely` | Hard-negative phrase or known citizenship-restricted employer (e.g. BWI GmbH = Bundeswehr IT). | ≥1 hard-negative |
| `unknown` | Description doesn't mention visa either way. Default majority. | Neither side fires |

**Reality check from production runs:** ~93% of German listings fall to `unknown` because most employers simply don't state sponsorship in text. This is the actual market signal, not a bug. For agencies who only want safe bets, filter to `confirmed + likely`. For aggressive sourcers, filter to `confirmed + likely + unknown` and assume "unknown = ask the recruiter."

Optional **LLM tie-breaker** (`useLlmTiebreaker: true`) escalates the bottom 30% of ambiguous cases to Claude Haiku 4.5 for a final read. Costs $0.001 per escalation, capped at a configurable fraction of the run. Default off.

---

### Output — real, unredacted

One verified dataset row from a Berlin "visa sponsorship" search:

```json
{
  "refnr": "15170-448146640-S",
  "title": "Quality Engineer (f/m/d) Investment Castings",
  "employer": "Siemens Energy Global GmbH & Co. KG",
  "profession": "Ingenieur/in - Maschinenbau",
  "city": "Berlin",
  "postalCode": "13629",
  "region": "BERLIN",
  "country": "DEUTSCHLAND",
  "fullTime": true,
  "isStaffingAgency": false,
  "url": "https://www.arbeitsagentur.de/jobsuche/jobdetail/15170-448146640-S",
  "visaStatus": "likely",
  "visaClassifier": "regex-v1",
  "visaReason": "1 hard-positive: visa sponsorship",
  "visaSignals": {
    "hardPositive": ["visa sponsorship"],
    "hardNegative": [],
    "soft": ["global organization"]
  },
  "descriptionPreview": "A Snapshot of Your Day — This position combines Project, Quality, and Supplier Management...",
  "fetchedAt": "2026-05-17T11:19:45.990Z"
}
````

And a hard-negative example (correctly filtered as `unlikely`):

```json
{
  "title": "Software Engineer Full Stack (m/w/d)",
  "employer": "BWI GmbH",
  "city": "München",
  "visaStatus": "unlikely",
  "visaReason": "Hard-negative signal(s): BWI GmbH (Bundeswehr IT — citizenship typically required)",
  "visaSignals": {
    "hardPositive": [],
    "hardNegative": ["BWI GmbH (Bundeswehr IT — citizenship typically required)"],
    "soft": ["remote / mobile work"]
  }
}
```

Full field list: `refnr, title, employer, profession, city, postalCode, region, country, coordinates, salaryFromEUR, salaryToEUR, salaryKind, salaryRange, fullTime, partTime, shiftWork, isStaffingAgency, isPrivatePlacement, employerHomepage, publishedAt, modifiedAt, description, descriptionPreview, descriptionLength, allLocations, url, visaStatus, visaClassifier, visaReason, visaSignals, fetchedAt`.

Three dataset views are exposed (`overview`, `confirmed-only`, `full-details`) — pick from the Apify console.

***

### Input

Full schema with descriptions: see the **Input** tab in the Apify console.

| Field | Type | Default | Notes |
|---|---|---|---|
| `searchTerm` | `string` | **required** | Role keyword, EN or DE. E.g. `"Software Engineer"`, `"Data Scientist"`, `"Pflegefachkraft"`. |
| `location` | `string` | `""` | German city or postal area. Empty = all Germany. |
| `radiusKm` | `integer` | `25` | Search radius around `location`. |
| `salaryMinEUR` | `integer` | `0` | Minimum yearly salary filter (federal API field). |
| `remoteAllowed` | `boolean` | `false` | Filter to remote-allowed listings only. |
| `publishedDaysAgo` | `integer` | `7` | Skip listings older than N days. |
| `offerTypes` | `array<enum>` | `["1"]` | `1`=permanent, `2`=temp, `4`=apprenticeship, etc. |
| `includeTemporaryAgency` | `boolean` | `false` | Include staffing agencies (often visa-unfriendly). |
| `visaStatusFilter` | `array<enum>` | `["confirmed","likely","unknown"]` | Drop everything else from the dataset. |
| `useLlmTiebreaker` | `boolean` | `false` | Escalate ambiguous cases to Claude Haiku 4.5. Requires `anthropicApiKey`. |
| `anthropicApiKey` | `string` (secret) | `""` | Your Anthropic API key. Only needed if tie-breaker is on. |
| `llmTiebreakerMaxFraction` | `number` | `0.3` | Cap LLM calls at this fraction of the run. |
| `dedupAcrossRuns` | `boolean` | `true` | Persistent KV store of seen `refnr`s; skip on repeat. |
| `dedupHorizonDays` | `integer` | `7` | Prune dedup cache entries older than N days. |
| `maxResults` | `integer` | `100` | Hard cap per run. |
| `includeRawDescription` | `boolean` | `false` | Emit full description in addition to the preview. |

***

### Pricing — Pay Per Event

| Event | Price | Fires when |
|---|---|---|
| `actor-start-gb` | **$0.00005 / GB** | At run start. First 5 seconds waived. |
| `enriched-result` | **$0.005** | A job that passes classifier + filter + dedup and lands in the dataset. |
| `llm-tiebreaker-call` | **$0.001** | One Anthropic Haiku 4.5 escalation. Only if `useLlmTiebreaker: true`. |

**≈ $5 per 1,000 enriched results.** You pay for results, not for cycles. Repeated runs skip already-seen jobs and cost nothing.

| You are... | Cadence | Enriched/mo | Monthly cost |
|---|---|---|---|
| Solo job-mover (one role, one city) | Daily | ~150 | **~$0.75** |
| Active consultancy (5 roles × Berlin/Munich/Hamburg) | Daily | ~1,500 | **~$7.50** |
| Recruitment SaaS (50 client searches) | Daily | ~15,000 | **~$75** |

***

### How it stays clean

- **Federal API direct** — `bundesagentur-jobsuche` upstream, no scraping fragile HTML, no Cloudflare challenges, no proxy needed.
- **Deduplication across runs** — refnrs persisted in an Apify KV store. Poll daily without paying twice for the same job.
- **Stale-prune** — refnr cache older than 7 days (configurable) is dropped to keep the store light.
- **Classifier transparency** — every row exposes `visaReason` + `visaSignals`. You can override our judgement; we don't hide the evidence.
- **Cost ceiling** — LLM tie-breaker is opt-in and capped at a fraction of the run. Worst-case cost is bounded before you press Start.

***

### Limits & legal

- Reads only the **public** Bundesagentur Jobboerse API via client `jobboerse-jobsuche` (no OAuth, no scraping). De-facto public, no formal commercial-use restriction documented — verify before running at scale.
- The visa classifier is heuristic, not legal advice. `confirmed` does not guarantee sponsorship will be offered; `unlikely` does not guarantee it won't. Always confirm with the employer.
- We don't store personal data beyond what the federal API itself publishes.

***

### Frequently asked

**Q: Why not just grep "visa sponsorship" yourself?**
You can. But the federal API only returns 25 listings per page, requires base64 keys for detail fetches, has German-only category codes, and returns no sponsorship signal of its own. Doing this once is fine. Doing it on a cadence for 5 roles across 3 cities is a part-time job.

**Q: What's the false-positive rate on `confirmed`?**
The classifier is rule-based and conservative: `confirmed` requires multiple hard-positive phrases AND no hard-negatives, so false positives are rare in practice (we have not yet published a hand-graded benchmark). False negatives in `unknown` are the dominant error class — most German employers simply don't state sponsorship policy in text. The LLM tie-breaker is the lever for catching those.

**Q: Can I add my own classifier rules?**
Not in v0.2. Patch list / employer hard-negatives are coming in v0.3 — open a request via the Apify console issues tab.

**Q: Is there an MCP endpoint?**
Yes — automatically. Every Apify Actor with an input schema is exposed as an MCP tool. Point your Claude /  / Codex client at the Apify MCP  and this actor appears as `germany-visa-jobs`.

**Q: Why "pay-per-event" and not subscription?**
Because most users only need a few hundred fresh listings per month. PPE means you pay for results, not for cycles. Sleeping users cost nothing.

***

### Roadmap

- **v0.2** *(current)* — federal API, regex-v1 classifier, optional Haiku 4.5 tie-breaker, persistent dedup.
- **v0.3** — user-supplied hard-negative employer patches; per-row salary inference from text; German-language `Aufenthaltstitel` / `Blaue Karte` synonym set.
- **v0.4** — Stepstone + LinkedIn Jobs sibling actor wired into the same classifier.
- **v1.0** — calibrated probability output instead of bucket labels.

***

### Sister actor

Need somewhere to live in the same city? [`cg_nguyen/wg-gesucht-de`](https://apify.com/cg_nguyen/wg-gesucht-de) emits new WG-Zimmer listings minutes after they're posted. Same author, same pricing model.

***

### Author

Built by [@cg\_nguyen](https://apify.com/cg_nguyen). Senior Backend Engineer at SOA (Source of Asia), Hanoi. Working with European clients; lived the Tier-3 visa search myself. Bugs and feature requests via the Apify console issues tab.

# Actor input Schema

## `searchTerm` (type: `string`):

Free-text search on job title. Example: 'software engineer', 'data scientist', 'pflegefachkraft'.

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

City, postal code, or state in Germany. Leave empty for nationwide search.

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

Only applied when location is set. Defaults to 25 km on the federal API.

## `salaryMinEUR` (type: `integer`):

Hard filter — drops jobs whose advertised upper salary is below this. 0 means no filter.

## `remoteAllowed` (type: `boolean`):

Soft filter — currently keyword-based on the description ('remote', 'homeoffice', 'mobile working'). Improves Day 2 with the classifier.

## `publishedDaysAgo` (type: `integer`):

0 = no time filter. Federal API caps at 100.

## `offerTypes` (type: `array`):

1 = Job, 2 = Self-employment, 4 = Training/Dual studies, 34 = Internship/Trainee.

## `includeTemporaryAgency` (type: `boolean`):

Off by default — staffing-agency listings are usually thin (no description, no salary, often re-postings). Set true to include them anyway.

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

Hard cap on jobs fetched + detail-enriched. Each result fires one PPE event.

## `includeRawDescription` (type: `boolean`):

If false (default), output keeps the first 500 characters of the description. Set true for downstream NLP.

## `visaStatusFilter` (type: `array`):

Only emit jobs whose classifier verdict matches one of these. Default: confirmed + likely + unknown (drops only explicit no-sponsorship). Set to \['confirmed'] for the strictest list.

## `useLlmTiebreaker` (type: `boolean`):

Escalate 'unknown' verdicts to Claude Haiku for a final classification. Requires an Anthropic API key below. Rate-limited per run by llmTiebreakerMaxFraction.

## `anthropicApiKey` (type: `string`):

Optional, only used when 'useLlmTiebreaker' is on. Format: sk-ant-…. Stored as a per-run secret — not retained on the actor.

## `llmTiebreakerMaxFraction` (type: `integer`):

Hard cap on tie-breaker calls per run as a percentage of fetched jobs (0–100). Default 30. Prevents runaway cost on ambiguous result sets.

## `dedupAcrossRuns` (type: `boolean`):

On by default. The Bundesagentur API surfaces the same listing for ~14 days, so daily runs would otherwise emit massive duplicates. We cache emitted refnrs in the actor's key-value store and skip them on subsequent runs. Turn this off if you want every run to be a full snapshot.

## `dedupHorizonDays` (type: `integer`):

How long a refnr stays in the dedup cache before it can re-emit. Default 7 days — matches the typical churn rate of new listings.

## Actor input object example

```json
{
  "searchTerm": "software engineer",
  "location": "Berlin",
  "radiusKm": 25,
  "salaryMinEUR": 0,
  "remoteAllowed": false,
  "publishedDaysAgo": 30,
  "offerTypes": [
    "1"
  ],
  "includeTemporaryAgency": false,
  "maxResults": 5,
  "includeRawDescription": false,
  "visaStatusFilter": [
    "confirmed",
    "likely",
    "unknown"
  ],
  "useLlmTiebreaker": false,
  "llmTiebreakerMaxFraction": 30,
  "dedupAcrossRuns": true,
  "dedupHorizonDays": 7
}
```

# Actor output Schema

## `results` (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 = {
    "searchTerm": "software engineer",
    "location": "Berlin",
    "maxResults": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("cg_nguyen/germany-visa-jobs").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 = {
    "searchTerm": "software engineer",
    "location": "Berlin",
    "maxResults": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("cg_nguyen/germany-visa-jobs").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchTerm": "software engineer",
  "location": "Berlin",
  "maxResults": 5
}' |
apify call cg_nguyen/germany-visa-jobs --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=cg_nguyen/germany-visa-jobs",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Germany Visa-Sponsored Jobs",
        "description": "Find Germany jobs that sponsor work visas (Blue Card, Skilled Worker, ICT). Pulls the federal Bundesagentur Jobboerse, enriches with full descriptions, classifies visa-sponsorship likelihood (regex + opt-in LLM tie-breaker), and dedupes across runs. For relocation services and intl. job seekers.",
        "version": "0.2",
        "x-build-id": "Sdd84vwUAI1RQPLia"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/cg_nguyen~germany-visa-jobs/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-cg_nguyen-germany-visa-jobs",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/cg_nguyen~germany-visa-jobs/runs": {
            "post": {
                "operationId": "runs-sync-cg_nguyen-germany-visa-jobs",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/cg_nguyen~germany-visa-jobs/run-sync": {
            "post": {
                "operationId": "run-sync-cg_nguyen-germany-visa-jobs",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "searchTerm"
                ],
                "properties": {
                    "searchTerm": {
                        "title": "Job title / keywords (was)",
                        "type": "string",
                        "description": "Free-text search on job title. Example: 'software engineer', 'data scientist', 'pflegefachkraft'.",
                        "default": "software engineer"
                    },
                    "location": {
                        "title": "Location (wo)",
                        "type": "string",
                        "description": "City, postal code, or state in Germany. Leave empty for nationwide search.",
                        "default": ""
                    },
                    "radiusKm": {
                        "title": "Search radius around location (km)",
                        "minimum": 0,
                        "maximum": 200,
                        "type": "integer",
                        "description": "Only applied when location is set. Defaults to 25 km on the federal API.",
                        "default": 25
                    },
                    "salaryMinEUR": {
                        "title": "Minimum annual salary (EUR)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Hard filter — drops jobs whose advertised upper salary is below this. 0 means no filter.",
                        "default": 0
                    },
                    "remoteAllowed": {
                        "title": "Include remote-friendly jobs only",
                        "type": "boolean",
                        "description": "Soft filter — currently keyword-based on the description ('remote', 'homeoffice', 'mobile working'). Improves Day 2 with the classifier.",
                        "default": false
                    },
                    "publishedDaysAgo": {
                        "title": "Only jobs published in the last N days",
                        "minimum": 0,
                        "maximum": 100,
                        "type": "integer",
                        "description": "0 = no time filter. Federal API caps at 100.",
                        "default": 30
                    },
                    "offerTypes": {
                        "title": "Offer type filter (angebotsart)",
                        "type": "array",
                        "description": "1 = Job, 2 = Self-employment, 4 = Training/Dual studies, 34 = Internship/Trainee.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "1",
                                "2",
                                "4",
                                "34"
                            ],
                            "enumTitles": [
                                "Job (Arbeit)",
                                "Self-employment",
                                "Training / dual studies",
                                "Internship / trainee"
                            ]
                        },
                        "default": [
                            "1"
                        ]
                    },
                    "includeTemporaryAgency": {
                        "title": "Include staffing-agency listings (Zeitarbeit)",
                        "type": "boolean",
                        "description": "Off by default — staffing-agency listings are usually thin (no description, no salary, often re-postings). Set true to include them anyway.",
                        "default": false
                    },
                    "maxResults": {
                        "title": "Max results to enrich",
                        "minimum": 1,
                        "maximum": 2000,
                        "type": "integer",
                        "description": "Hard cap on jobs fetched + detail-enriched. Each result fires one PPE event.",
                        "default": 50
                    },
                    "includeRawDescription": {
                        "title": "Include full job description in output",
                        "type": "boolean",
                        "description": "If false (default), output keeps the first 500 characters of the description. Set true for downstream NLP.",
                        "default": false
                    },
                    "visaStatusFilter": {
                        "title": "Visa-sponsorship filter",
                        "type": "array",
                        "description": "Only emit jobs whose classifier verdict matches one of these. Default: confirmed + likely + unknown (drops only explicit no-sponsorship). Set to ['confirmed'] for the strictest list.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "confirmed",
                                "likely",
                                "unlikely",
                                "unknown"
                            ],
                            "enumTitles": [
                                "Confirmed (explicit sponsorship)",
                                "Likely (strong indirect signals)",
                                "Unlikely (citizenship/permit required)",
                                "Unknown (no clear signal)"
                            ]
                        },
                        "default": [
                            "confirmed",
                            "likely",
                            "unknown"
                        ]
                    },
                    "useLlmTiebreaker": {
                        "title": "Use LLM tie-breaker for ambiguous jobs",
                        "type": "boolean",
                        "description": "Escalate 'unknown' verdicts to Claude Haiku for a final classification. Requires an Anthropic API key below. Rate-limited per run by llmTiebreakerMaxFraction.",
                        "default": false
                    },
                    "anthropicApiKey": {
                        "title": "Anthropic API key",
                        "type": "string",
                        "description": "Optional, only used when 'useLlmTiebreaker' is on. Format: sk-ant-…. Stored as a per-run secret — not retained on the actor."
                    },
                    "llmTiebreakerMaxFraction": {
                        "title": "Max fraction of jobs sent to LLM tie-breaker",
                        "minimum": 0,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Hard cap on tie-breaker calls per run as a percentage of fetched jobs (0–100). Default 30. Prevents runaway cost on ambiguous result sets.",
                        "default": 30
                    },
                    "dedupAcrossRuns": {
                        "title": "Skip jobs seen in earlier runs",
                        "type": "boolean",
                        "description": "On by default. The Bundesagentur API surfaces the same listing for ~14 days, so daily runs would otherwise emit massive duplicates. We cache emitted refnrs in the actor's key-value store and skip them on subsequent runs. Turn this off if you want every run to be a full snapshot.",
                        "default": true
                    },
                    "dedupHorizonDays": {
                        "title": "Dedup memory horizon (days)",
                        "minimum": 1,
                        "maximum": 60,
                        "type": "integer",
                        "description": "How long a refnr stays in the dedup cache before it can re-emit. Default 7 days — matches the typical churn rate of new listings.",
                        "default": 7
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
