# Xing Jobs Scraper (`automation-lab/xing-job-listings-scraper-retry`) Actor

Search public XING jobs by keyword and location and export enriched DACH vacancy records for recruiting and labor-market feeds.

- **URL**: https://apify.com/automation-lab/xing-job-listings-scraper-retry.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.53 / 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

## Xing Jobs Scraper

Search public **XING jobs** by keyword and location and export normalized,
enriched vacancy records for DACH recruiting and labor-market workflows.
The Actor works with anonymous XING job pages: no XING account or login is
required.

Use it to create one-time vacancy exports or scheduled feeds containing job ID,
title, employer, location, work mode, employment type, salary, dates, full
description, qualifications, responsibilities, and application URL.

### What does Xing Jobs Scraper do?

The Actor accepts search phrases such as `software engineer`, optional locations
such as `Berlin` or `Wien`, and existing public XING jobs search URLs.

For every accepted search it:

1. opens the public XING search-results pages;
2. follows XING pagination up to your configured limits;
3. de-duplicates jobs by stable XING identity;
4. optionally opens each job page for the complete description and metadata;
5. saves typed records to the default Apify dataset;
6. makes the results available as JSON, CSV, Excel, XML, RSS, or through the API.

XING uses semantic job search, so a narrow phrase can return related vacancies
rather than only literal keyword matches.

### Who is this XING jobs extractor for?

- **Recruiters** building fresh candidate-sourcing and vacancy intelligence.
- **Staffing agencies** comparing open roles across German, Austrian, and Swiss
  markets.
- **Talent intelligence teams** tracking role, location, salary, and work-mode
  changes.
- **Labor-market analysts** collecting repeatable DACH vacancy samples.
- **Data engineers** feeding job records into warehouses, dashboards, and
  spreadsheets.
- **Sales teams** using active hiring as a public company-growth signal.

### Why use this Actor?

- Searches public pages without requiring XING credentials.
- Supports keyword/location combinations and user-built XING search URLs.
- Extracts both result-list identity and full detail-page content.
- Preserves source keyword, location, page, and position for auditability.
- Stops at explicit item and page limits.
- De-duplicates repeated jobs across searches in the same run.
- Uses lightweight HTTP extraction rather than a full browser.
- Fails clearly when XING returns an unexpected or blocked response instead of
  reporting a misleading empty success.

### What XING job data can I extract?

| Field | Meaning |
| --- | --- |
| `jobId` | Stable numeric XING job ID |
| `title` | Vacancy title |
| `employer` | Hiring company name |
| `location`, `locations` | Primary city and all listed cities |
| `countryCode` | ISO country code when shown |
| `workplaceType` | Remote, hybrid, or on-site value supplied by XING |
| `employmentType` | Full-time, part-time, or another listed type |
| `careerLevel` | Career level when available |
| `discipline`, `industry` | XING classification values |
| `salaryMinimum`, `salaryMaximum` | Salary range when the listing publishes one |
| `salaryCurrency` | Salary currency, typically EUR |
| `publishedAt` | Original activation timestamp when available |
| `refreshedAt` | Latest XING refresh timestamp |
| `activeUntil` | Listing expiration timestamp when available |
| `description` | Plain-text full description from the detail page |
| `responsibilities` | XING summary of responsibilities |
| `qualifications` | XING summary of qualifications |
| `applyUrl` | External application URL or canonical XING job URL |
| `url` | Canonical XING vacancy URL |
| `sourceKeyword`, `sourceLocation` | Search context that produced the row |
| `sourceUrl`, `page`, `position` | Search-page provenance |
| `scrapedAt` | UTC extraction timestamp |

Fields that XING does not publish for a vacancy are returned as `null` or an
empty array. Salary and publication date are not present on every listing.

### How to scrape XING jobs

1. Open the Actor in Apify Console.
2. Add one or more **Keywords**.
3. Optionally add DACH cities or regions under **Locations**.
4. Leave **Enrich job details** enabled when descriptions and extra fields are
   required.
5. Set **Maximum jobs** and, if needed, **Maximum pages per search**.
6. Click **Start**.
7. Open the **Dataset** tab to preview or export the records.

A practical first run is:

```json
{
  "keywords": ["software engineer"],
  "locations": ["Berlin"],
  "maxItems": 10,
  "enrichDetails": true
}
```

### Input parameters

#### `keywords`

An array of job titles, skills, or search phrases. Every keyword is combined
with every supplied location. Required unless `startUrls` is provided.

#### `locations`

Optional city or region text such as `Berlin`, `Hamburg`, `München`, `Wien`, or
`Zürich`. An empty list searches without an explicit location.

#### `startUrls`

Optional public `xing.com/jobs/search` URLs. Use these when filters were already
built on XING. When present, start URLs take precedence over keyword/location
combinations. Other domains and non-search XING URLs are rejected.

#### `enrichDetails`

Defaults to `true`. When enabled, the Actor opens each job page to collect full
description sections, work mode, qualifications, responsibilities, and detail
metadata. Disable it for a faster search-list feed when summary data is enough.

#### `maxItems`

Maximum unique records saved across the entire run. The accepted range is 1 to
1,000 and the default is 50.

#### `maxPages`

Maximum result pages visited per search, from 1 to 50. XING normally provides up
to 20 search results per page.

### Output example

A current enriched run returns records shaped like this:

```json
{
  "jobId": "123456789",
  "title": "Senior Software Engineer",
  "employer": "Example Technology GmbH",
  "location": "Berlin",
  "locations": ["Berlin"],
  "countryCode": "DE",
  "workplaceType": "PARTLY_REMOTE",
  "employmentType": "Full-time",
  "careerLevel": "Experienced professional",
  "salaryMinimum": 70000,
  "salaryMaximum": 90000,
  "salaryCurrency": "EUR",
  "publishedAt": "2026-01-15T09:00:00Z",
  "refreshedAt": "2026-01-18T09:00:00Z",
  "activeUntil": "2026-03-15T09:00:00Z",
  "description": "Join the engineering team to build reliable applications...",
  "responsibilities": ["Develop customer applications", "Review code"],
  "qualifications": ["Professional software development experience"],
  "applyUrl": "https://www.xing.com/jobs/berlin-senior-software-engineer-123456789",
  "url": "https://www.xing.com/jobs/berlin-senior-software-engineer-123456789",
  "sourceKeyword": "software engineer",
  "sourceLocation": "Berlin",
  "sourceUrl": "https://www.xing.com/jobs/search?keywords=software+engineer&location=Berlin",
  "page": 1,
  "position": 0,
  "scrapedAt": "2026-01-20T12:00:00.000Z"
}
```

### How much does it cost to extract XING jobs?

The Actor uses pay-per-event pricing:

- **$0.0005** once per run;
- a tiered price for each saved job, currently **$0.00088 per job on BRONZE**;
- details included in a saved job have no separate event charge.

At the BRONZE tier, the Actor charge is approximately:

| Saved jobs | Estimated Actor charge |
| ---: | ---: |
| 10 | $0.0093 |
| 100 | $0.0885 |
| 1,000 | $0.8805 |

These examples combine the run start and per-job events. Your Apify plan and
applicable pricing tier determine the final amount shown in Console. Failed or
duplicate records are not charged as saved jobs.

### Recurring DACH recruiting feeds

Create an Apify Schedule to rerun the same keyword/location input daily or
weekly. Send each completed dataset to a webhook, cloud storage, Google Sheets,
or a database. Compare rows by `jobId` and use `refreshedAt` or `activeUntil` to
identify changes.

The Actor emits current observations; it does not maintain history or send
alerts by itself. Store earlier datasets in your destination when historical
comparison is required.

### Spreadsheet and data-pipeline exports

From the Dataset tab, export records as CSV or Excel for analysts. For automated
pipelines, request JSON from the dataset API and upsert by `jobId`.

Useful pipeline checks include:

- treat nullable salary fields as unknown rather than zero;
- retain `sourceUrl` for provenance;
- use `scrapedAt` as observation time, not publication time;
- compare `activeUntil` before removing jobs from a current feed.

### Run through the Apify API with cURL

Replace `APIFY_TOKEN` with your token:

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~xing-job-listings-scraper-retry/runs?token=APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "keywords": ["data analyst"],
    "locations": ["Hamburg"],
    "maxItems": 25,
    "enrichDetails": true
  }'
```

### Run with JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/xing-job-listings-scraper-retry').call({
  keywords: ['software engineer'],
  locations: ['Berlin'],
  maxItems: 25,
  enrichDetails: true,
});

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

### Run with Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("automation-lab/xing-job-listings-scraper-retry").call(
    run_input={
        "keywords": ["sales manager"],
        "locations": ["Wien"],
        "maxItems": 25,
        "enrichDetails": True,
    }
)
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)
```

### Use with Apify MCP and AI assistants

#### Claude Code

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

#### Claude Desktop

Add this server to the Claude Desktop MCP configuration:

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

#### Cursor

Add the same `apify` HTTP server URL under Cursor Settings → MCP.

#### VS Code

Add the same `apify` HTTP server URL to your VS Code MCP server configuration.

Example prompts:

- “Find 20 XING software engineering jobs in Berlin and return employer,
  salary, work mode, and apply URL.”
- “Export enriched XING data analyst vacancies in Hamburg as a structured
  recruiting feed.”
- “Collect sales manager jobs in Berlin and Vienna and group the results by
  employer.”

### Limits and reliable use

- Only public anonymous XING job-search and job-detail pages are supported.
- The Actor does not scrape XING profiles, companies, messages, or logged-in
  pages.
- Results follow XING semantic search and may include related roles.
- XING may omit salary, career level, industry, or publication date.
- A job can contain several locations; `location` is the primary city and
  `locations` contains the full list.
- Item limits apply across all keywords, locations, and URLs in one run.
- Transient network and upstream failures are retried twice with bounded
  backoff. Persistent unexpected response shapes fail the run clearly.
- Large enriched runs make one detail request per accepted job and therefore
  take longer than list-only runs.

Start with 10–25 items when testing a new query, then raise the limit after
reviewing relevance and field availability.

### Troubleshooting

#### Why did my narrow keyword return related jobs?

XING's public search uses semantic matching. Try a more specific phrase,
location, or a search URL configured in XING. The Actor returns the source's
ranking rather than applying an undocumented exact-match filter.

#### Why is salary or publication date null?

The listing did not expose that field publicly. The Actor preserves `null`
instead of guessing a salary or date.

#### Why is the description short?

Confirm `enrichDetails` is `true`. List-only mode uses the summary available on
the search page and intentionally skips full detail pages.

#### Why did the run fail instead of returning zero records?

A persistent HTTP error or missing XING data state means the source response was
not a valid empty search. Failing avoids silently delivering an incomplete feed.
Retry later or inspect the run log for the affected URL.

### Responsible and legal use

Use the Actor only for lawful purposes and public data you are entitled to
process. Follow XING's terms, robots guidance, applicable database rights,
copyright, privacy, and employment laws. Do not use vacancy data for unlawful
discrimination, spam, harassment, or attempts to identify private individuals.

You are responsible for establishing a legal basis, limiting collection to what
you need, securing exports, honoring retention requirements, and responding to
data-subject or source requests where applicable. This documentation is not
legal advice.

### Related automation-lab Actors

- [Arbeitnow EU and DACH Jobs Scraper](https://apify.com/automation-lab/arbeitnow-eu-dach-jobs-scraper)
  for a multi-country public job feed.
- [Arbeitsagentur Germany Job Listings](https://apify.com/automation-lab/arbeitsagentur-germany-job-listings)
  for German federal employment-service vacancies.
- [StepStone Group Jobs Feed](https://apify.com/automation-lab/stepstone-group-jobs-feed)
  for supported StepStone Group job portals.

These are separate sources. Combine datasets in your own pipeline when broader
coverage is needed.

### FAQ

#### Does it require a XING login?

No. The supported search and detail workflow uses anonymous public job pages.

#### Can I search Germany, Austria, and Switzerland?

Yes. Supply the DACH city or region text accepted by XING. Availability and
ranking are controlled by the source.

#### Can I use a XING search URL?

Yes. Add one or more public `/jobs/search` URLs to `startUrls`. They take
precedence over `keywords` and `locations`.

#### Are descriptions and application links included?

Yes when XING publishes them. Enable detail enrichment for full description
sections and detail-only fields.

#### Can I schedule runs?

Yes. Use Apify Schedules and connect the resulting dataset to a webhook or
integration. Historical comparison and alerting belong in the destination
workflow.

#### How are duplicate jobs handled?

The Actor de-duplicates by the XING job identity across all searches in one
run. A duplicate is neither saved nor charged as another result.

# Actor input Schema

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

Job titles, skills, or other search phrases, such as software engineer or sales manager.

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

DACH cities or regions to combine with every keyword. Leave empty for all locations.

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

Optional public xing.com/jobs/search URLs. When supplied, these replace keyword searches and preserve the URL filters.

## `enrichDetails` (type: `boolean`):

Fetch each job page for full description, qualifications, responsibilities, work mode, and additional dates.

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

Maximum number of unique job records to save across all searches.

## `maxPages` (type: `integer`):

Safety limit for search-result pagination. Each XING page normally contains up to 20 jobs.

## Actor input object example

```json
{
  "keywords": [
    "software engineer"
  ],
  "locations": [
    "Berlin"
  ],
  "startUrls": [],
  "enrichDetails": true,
  "maxItems": 10,
  "maxPages": 3
}
```

# Actor output Schema

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

All job records produced by this run in the overview dataset view.

# 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 = {
    "keywords": [
        "software engineer"
    ],
    "locations": [
        "Berlin"
    ],
    "startUrls": [],
    "enrichDetails": true,
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/xing-job-listings-scraper-retry").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 = {
    "keywords": ["software engineer"],
    "locations": ["Berlin"],
    "startUrls": [],
    "enrichDetails": True,
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/xing-job-listings-scraper-retry").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 '{
  "keywords": [
    "software engineer"
  ],
  "locations": [
    "Berlin"
  ],
  "startUrls": [],
  "enrichDetails": true,
  "maxItems": 10
}' |
apify call automation-lab/xing-job-listings-scraper-retry --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/xing-job-listings-scraper-retry"
        }
    }
}

```

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/VY74KsekVJxduYCen/builds/aLOVQ23NiZHbzVnMc/openapi.json
