# Karriere.at Jobs Scraper (`automation-lab/karriere-at-austria-job-listings-scraper`) Actor

Search public Karriere.at jobs and export normalized Austrian vacancy records with employer, location, employment type, salary, posting date, description, and canonical URL.

- **URL**: https://apify.com/automation-lab/karriere-at-austria-job-listings-scraper.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.72 / 1,000 item extracteds

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Karriere.at Jobs Scraper

Search public **karriere.at jobs** by keyword and Austrian location, or process exact search and vacancy URLs, then export normalized vacancy records for recruiting feeds and labor-market analysis.

Karriere.at Jobs Scraper returns stable job IDs, titles, employers, locations, employment types, disclosed salary ranges, posting dates, descriptions, home-office signals, and canonical URLs. It uses the site's public structured search response and public job pages; no Karriere.at account is required.

### What can you do with this Karriere.at scraper?

- Search current vacancies by role and Austrian location.
- Export normalized records to JSON, CSV, Excel, XML, or RSS through Apify.
- Capture structured EUR salary bounds and salary periods when disclosed.
- Fetch full public job descriptions and exact posting dates.
- Preserve stable vacancy IDs for comparing scheduled runs downstream.
- Process a real Karriere.at search URL with its existing filters.
- Refresh a known numeric job URL without running a broad search.
- Build recruiting, employer-hiring, and Austrian labor-market datasets.
- Run lighter list-only exports by disabling detail enrichment.

The Actor returns current public source data. It does not submit applications, log in, retain historical snapshots, detect changes by itself, or send alerts. Apify schedules and your downstream storage can provide those surrounding workflows.

### Who is this Actor for?

#### Recruiters and talent teams

Build repeatable role-and-location feeds, identify employers with active vacancies, and review employment and salary information without manually copying listings.

#### Labor-market and salary analysts

Collect consistent vacancy IDs, locations, posting dates, employment types, and disclosed salary bands for Austrian market research.

#### Job-data and HR product teams

Feed structured Karriere.at records into a warehouse, internal search index, matching pipeline, dashboard, or vacancy aggregator.

#### Consultants and researchers

Create reproducible datasets for Wien, Graz, Linz, Salzburg, other Austrian locations, or a supplied source search page.

### Extracted Karriere.at job data

| Field | Meaning |
| --- | --- |
| `jobId` | Stable numeric Karriere.at vacancy ID |
| `title` | Advertised job title |
| `employer` | Hiring employer shown on the vacancy |
| `employerUrl` | Public Karriere.at employer profile when available |
| `location` | Primary Austrian job location |
| `locations` | All disclosed job locations |
| `employmentTypes` | Values such as `FULL_TIME`, `PART_TIME`, Vollzeit, or Teilzeit |
| `salary.text` | Human-readable disclosed salary |
| `salary.min`, `salary.max` | Structured lower and upper salary bounds |
| `salary.currency` | Salary currency, normally `EUR` |
| `salary.unit` | Salary period such as `MONTH` or `YEAR` |
| `postedText` | Human-readable posting-age label from search results |
| `datePosted` | Exact structured posting date in detail mode |
| `description` | Full public plain-text job description in detail mode |
| `summary` | Short search-result summary when supplied |
| `homeOffice` | Source or description signal for home office, hybrid, or remote work |
| `canonicalUrl` | Canonical public vacancy URL |
| `sourceSearchUrl` | Search URL that produced the record |
| `scrapedAt` | ISO timestamp when the record was saved |

Unavailable source values remain `null` or an empty array. The Actor does not invent salary, dates, employment types, or locations.

### How to scrape Karriere.at jobs

1. Open the Actor in Apify Console.
2. Add a row under **Keyword and location searches**.
3. Enter a role such as `software engineer` and a location such as `wien`.
4. Choose the maximum number of unique jobs.
5. Keep **Fetch full job details** enabled for descriptions and structured fields.
6. Click **Start**.
7. Inspect or download the records from the Dataset tab.

A useful first input is:

```json
{
  "searchQueries": [
    { "keyword": "software engineer", "location": "wien" }
  ],
  "maxItems": 10,
  "includeDetails": true
}
```

### Input parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `searchQueries` | object array | — | Keyword/location pairs; either value may be omitted, but not both |
| `keywords` | string array | — | Shortcut for combining every keyword with every `locations` value |
| `locations` | string array | — | Austrian locations combined with `keywords` |
| `startUrls` | URL array | — | Public Karriere.at search pages or numeric job-detail URLs |
| `maxItems` | integer | `50` | Maximum unique vacancy rows across all inputs; 1–10,000 |
| `maxPagesPerSearch` | integer | `10` | Maximum pages requested for each search; 1–100 |
| `includeDetails` | boolean | `true` | Fetch full descriptions, dates, employment types, and structured salary |

Provide at least one valid search, keyword, or start URL. Only HTTPS `karriere.at` and `www.karriere.at` `/jobs` paths are accepted.

### Keyword and location search patterns

Use `searchQueries` when each role needs its own location:

```json
{
  "searchQueries": [
    { "keyword": "data analyst", "location": "wien" },
    { "keyword": "marketing", "location": "linz" }
  ],
  "maxItems": 50,
  "includeDetails": true
}
```

Use `keywords` and `locations` when you need every combination:

```json
{
  "keywords": ["marketing", "sales"],
  "locations": ["wien", "salzburg"],
  "maxItems": 100,
  "includeDetails": true
}
```

Duplicates found across searches are saved once by stable job ID.

### Search URLs and individual vacancy URLs

A real location search URL preserves source-specific search behavior:

```json
{
  "startUrls": [
    { "url": "https://www.karriere.at/jobs/graz" }
  ],
  "maxItems": 25,
  "includeDetails": true
}
```

An individual public job URL refreshes one known vacancy:

```json
{
  "startUrls": [
    { "url": "https://www.karriere.at/jobs/10029847" }
  ],
  "maxItems": 1,
  "includeDetails": true
}
```

The numeric vacancy must still be publicly available. A removed or invalid detail page fails rather than producing a misleading empty record.

### Example output

A current local run for `software engineer` in Wien returned records shaped like this:

```json
{
  "jobId": "7865872",
  "title": "Cloud Infrastructure Engineer (m/w/d)",
  "employer": "Anexia Holding GmbH",
  "employerUrl": "https://www.karriere.at/f/anexia",
  "location": "Wien, Wien, AT",
  "locations": ["Wien, Wien, AT"],
  "employmentTypes": ["FULL_TIME"],
  "salary": {
    "text": "56000 EUR per year",
    "min": 56000,
    "max": null,
    "currency": "EUR",
    "unit": "YEAR"
  },
  "postedText": "vor 5 Tagen veröffentlicht",
  "datePosted": "2026-08-26T15:41:13+02:00",
  "description": "Public job description...",
  "summary": "Public search summary...",
  "homeOffice": true,
  "canonicalUrl": "https://www.karriere.at/jobs/7865872",
  "sourceSearchUrl": "https://www.karriere.at/jobs?keywords=software+engineer&locations=wien",
  "scrapedAt": "2026-08-31T14:10:00.000Z"
}
```

Source records change over time, so the exact vacancy and values in a later run can differ.

### Search-only versus full-detail mode

With `includeDetails: true`, the Actor opens each public job page and adds:

- full plain-text description;
- exact structured posting date;
- structured salary bounds, currency, and period;
- normalized schema.org employment types;
- full structured location values;
- canonical URL confirmation.

With `includeDetails: false`, it returns faster search records with title, employer, search locations, displayed employment type, salary text, posting-age text, summary, home-office flag, and URL. Missing detail-only fields remain `null`.

If one detail request fails after bounded retries, the Actor logs a warning and saves the still-useful search record. A failed or malformed search response fails the run instead of being treated as a legitimate zero-result search.

### How much does it cost to extract Karriere.at jobs?

The Actor uses pay-per-event pricing:

- one `start` event when the run begins;
- one `item` event for each unique useful vacancy record saved.

The price is a **$0.005 start fee** plus the account-tier item rate shown in Apify Console. The per-job rates are strictly decreasing by tier: FREE $0.00138, BRONZE $0.0012, SILVER $0.000936, GOLD $0.00072, PLATINUM $0.00048, and DIAMOND $0.000336. The applicable Console tier is authoritative.

Examples at the BRONZE rate:

| Useful jobs | Start | Items | Total |
| ---: | ---: | ---: | ---: |
| 1 | $0.005 | $0.0012 | $0.0062 |
| 10 | $0.005 | $0.0120 | $0.0170 |
| 100 | $0.005 | $0.1200 | $0.1250 |

Failed, duplicate, and rejected records are not charged as items. Apify may also charge your account for platform compute according to your plan. Check the run's charge summary before scaling a recurring workflow.

### Recurring vacancy-feed workflow

A useful monitoring setup is:

1. Save a keyword/location input as an Apify Task.
2. Schedule it daily or weekly.
3. Export each run dataset to your database or spreadsheet.
4. Compare `jobId` and selected fields with the prior snapshot.
5. Trigger your own downstream action for new, removed, or changed records.

The Actor provides stable IDs and fresh public records. Snapshot retention, change rules, notifications, and historical analysis remain in the downstream system, avoiding hidden state inside extraction runs.

### Integrations and exports

Use the default dataset with:

- Google Sheets for recruiting review queues;
- Make or Zapier for downstream automation;
- webhooks for run-completion processing;
- BigQuery, Snowflake, PostgreSQL, or another warehouse;
- a BI dashboard for vacancy, salary, or employer trends;
- an internal job search, matching, or enrichment pipeline.

Apify datasets can be downloaded as JSON, JSONL, CSV, Excel, XML, or RSS.

### API usage with JavaScript

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/karriere-at-austria-job-listings-scraper').call({
  searchQueries: [{ keyword: 'software engineer', location: 'wien' }],
  maxItems: 25,
  includeDetails: true,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### API usage with Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("automation-lab/karriere-at-austria-job-listings-scraper").call(
    run_input={
        "searchQueries": [{"keyword": "software engineer", "location": "wien"}],
        "maxItems": 25,
        "includeDetails": True,
    }
)
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)
```

### API usage with cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~karriere-at-austria-job-listings-scraper/runs?token=$APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "searchQueries": [{"keyword":"software engineer","location":"wien"}],
    "maxItems": 25,
    "includeDetails": true
  }'
```

Fetch the resulting dataset through the `defaultDatasetId` returned by the run API.

### Use the Actor through MCP

Add the hosted Actor tool to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/karriere-at-austria-job-listings-scraper"
```

#### Setup for Claude Desktop, Cursor, or VS Code

Use this equivalent configuration in **Claude Desktop**, **Cursor**, or **VS Code** MCP settings:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/karriere-at-austria-job-listings-scraper"
    }
  }
}
```

Example prompts:

- “Find five software engineering jobs in Vienna and summarize disclosed salaries.”
- “Export current Karriere.at vacancies in Graz with employers and canonical URLs.”
- “Build a structured marketing vacancy feed for Vienna and Salzburg.”

### Reliability, retries, and limits

- Requests use public Karriere.at search responses and public vacancy pages.
- Pagination stops at the source's end signal, `maxPagesPerSearch`, or `maxItems`.
- Stable numeric job IDs deduplicate overlaps across searches.
- Transient network errors, HTTP 429, temporary 5xx responses, and recognized challenge pages receive at most three total attempts with backoff.
- Deterministic invalid URLs and other non-429 4xx responses are not retried blindly.
- No paid proxy or browser fallback is enabled in the normal product route.
- Site response changes can require an Actor update.

Start with a small `maxItems` value, inspect the output, and then scale the same verified input.

### Troubleshooting

#### Why did I receive fewer jobs than `maxItems`?

The source may have fewer matching public jobs, searches may overlap, a pagination limit may be reached, or some source records may lack the minimum stable identity fields. `maxItems` is a ceiling, not a promised count.

#### Why are description or exact date fields null?

Set `includeDetails` to `true`. If one detail page temporarily fails, the Actor preserves its useful search record and logs the enrichment failure. Some fields can also be absent from the public source.

#### Why was my URL rejected?

Use an HTTPS `karriere.at` or `www.karriere.at` URL under `/jobs`. Company pages, unrelated paths, other domains, malformed URLs, and non-HTTPS URLs fail validation.

#### Why did the whole run fail instead of returning zero items?

A malformed or challenged search response is not evidence of a true empty search. The Actor fails closed so an upstream error is not mistaken for a market result.

### Responsible use and legality

The Actor accesses publicly available job-listing pages. You are responsible for your use of the data and for complying with applicable laws, contractual restrictions, source terms, privacy rules, database rights, and your organization's policies.

Do not use vacancy or contact data for spam, unlawful profiling, discrimination, or intrusive outreach. Collect only the fields required for a legitimate purpose, secure exported datasets, define retention periods, and honor applicable deletion or correction obligations.

This Actor does not bypass login, apply to jobs, access private candidate data, or solve CAPTCHAs.

### Limitations

- Only public Karriere.at `/jobs` search and numeric detail URLs are supported.
- The Actor returns current source state, not historical snapshots.
- Salary and employment fields depend on what each employer discloses.
- Home-office detection uses source signals and public description language; it is not a contractual work-location guarantee.
- Description text reflects employer formatting after HTML is normalized to plain text.
- A source redesign can temporarily affect extraction.
- The Actor does not apply source filters beyond the supplied search URL or keyword/location criteria.

### Related Automation Lab Actors

- [Workday Jobs Scraper](https://apify.com/automation-lab/workday-jobs-scraper) for public employer Workday boards.
- [Remote OK Jobs Scraper](https://apify.com/automation-lab/remoteok-jobs-scraper) for remote vacancy feeds.
- [Welcome to the Jungle Jobs Scraper](https://apify.com/automation-lab/welcome-to-the-jungle-jobs-scraper) for supported company and role searches on that source.

Choose this Actor when the required source is specifically Karriere.at and the buyer job is a normalized Austrian vacancy feed.

### FAQ

#### Does it require a Karriere.at account?

No. It uses public search responses and public job pages only.

#### Can it scrape both search pages and one exact vacancy?

Yes. Supply a public `/jobs` search URL or a numeric `/jobs/<id>` detail URL in `startUrls`.

#### Can I search several Austrian cities in one run?

Yes. Use `keywords` with multiple `locations`, or add several precise `searchQueries` rows.

#### Does it include salary information?

Yes, when Karriere.at discloses it. Detail mode normalizes structured minimum, maximum, currency, and period values where present.

#### Does it monitor changes automatically?

No. Schedule repeated Apify Task runs and compare stable `jobId` values and fields in your downstream storage.

#### Are duplicate vacancies charged twice?

No. The Actor deduplicates by stable job ID within a run and charges the item event only for each unique saved record.

# Actor input Schema

## `searchQueries` (type: `array`):

Search pairs such as software engineer in Wien. A keyword, a location, or both are required in each row.

## `keywords` (type: `array`):

Optional shortcut for searching each keyword across every location in the Locations field.

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

Austrian locations combined with every keyword, for example Wien, Graz, Linz, or Salzburg.

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

Optional public Karriere.at /jobs search pages or individual numeric job-detail URLs.

## `maxItems` (type: `integer`):

Maximum number of unique vacancy records saved across all searches and supplied URLs.

## `maxPagesPerSearch` (type: `integer`):

Maximum Karriere.at result pages requested for each search before moving to the next search.

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

Open each public vacancy page for full description, exact posting date, structured salary, and normalized employment types.

## Actor input object example

```json
{
  "searchQueries": [
    {
      "keyword": "software engineer",
      "location": "wien"
    }
  ],
  "keywords": [],
  "locations": [],
  "startUrls": [],
  "maxItems": 10,
  "maxPagesPerSearch": 10,
  "includeDetails": true
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset containing all normalized Karriere.at vacancy records.

# 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 = {
    "searchQueries": [
        {
            "keyword": "software engineer",
            "location": "wien"
        }
    ],
    "keywords": [],
    "locations": [],
    "startUrls": [],
    "maxItems": 10,
    "includeDetails": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/karriere-at-austria-job-listings-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 = {
    "searchQueries": [{
            "keyword": "software engineer",
            "location": "wien",
        }],
    "keywords": [],
    "locations": [],
    "startUrls": [],
    "maxItems": 10,
    "includeDetails": True,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/karriere-at-austria-job-listings-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 '{
  "searchQueries": [
    {
      "keyword": "software engineer",
      "location": "wien"
    }
  ],
  "keywords": [],
  "locations": [],
  "startUrls": [],
  "maxItems": 10,
  "includeDetails": true
}' |
apify call automation-lab/karriere-at-austria-job-listings-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/karriere-at-austria-job-listings-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/p4Yh4fdgk2FA9cJrs/builds/YcxqVsp50b28GH3rN/openapi.json
