# XING Jobs (DACH) Scraper (`zinin/xing-jobs`) Actor

Walk xing.com's own job sitemap and pull public job listings from Germany/Austria/Switzerland: title, company, location, employment type, posted date, industry, and (optionally) the full description — straight from each job's own public page.

- **URL**: https://apify.com/zinin/xing-jobs.md
- **Developed by:** [Tim Zinin](https://apify.com/zinin) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.55 / 1,000 job founds

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/platform/actors/running/actors-in-store#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 (DACH) Scraper

XING is the largest business network and job board across Germany, Austria and Switzerland. This Actor walks XING's own public job sitemap and visits each job's own page to return one row per posting — title, company, location, employment type, posted date, industry and (optionally) the full description. No login, no browser, no search query.

### What you get

- **Live jobs straight from XING's own sitemap**, not a stale export — every run reads the current freshest batch of listed jobs.
- **Full job detail, not a search-result teaser.** Since XING's job search itself needs a browser session, this Actor reads each job's own public page directly — the same structured data XING publishes for search engines.
- **Optional keyword filter.** Keep only jobs whose title contains your term — applied after fetching, since there is no server-side search available here.
- **Honest churn handling.** A meaningful share of freshly-listed postings are already withdrawn by the time this Actor visits them (temp-staffing boards rotate fast) — those are skipped for free, never billed, never treated as a failure.
- Runs on Apify: schedule it, monitor it, call it from the API or the MCP server, export to JSON, CSV or Excel, or push results straight into your own pipeline.

### How to run it

1. Click **Try for free** — no card needed on the free plan.
2. Set **Max jobs to return** (or leave the default).
3. Optionally add a **Keyword filter** to only keep matching titles.
4. Press **Start**. Results appear in the dataset — read them in the UI, pull them from the API, or have a webhook push them onward.

### Pricing

Pay-per-event: **$0.005 per run start + $0.003 per job found**. No monthly seat, no minimum. 100 jobs cost about **$0.31**; 1,000 jobs about **$3.01**.

A withdrawn posting (HTTP 410 — routine on this board), a keyword that matched nothing, or a sitemap that failed to load is still logged with `found: false` and the reason where one exists — and it is **not** charged for. You pay for jobs actually delivered, not for attempts.

### Input

| Field | Required | What it does |
|---|---|---|
| `max_items` | no | Target number of job rows to deliver (default 20, max 200). This is a target, not a guarantee — see the note on withdrawn postings above. |
| `freshness_days` | no | Skip sitemap entries older than this many days (default 14). XING's own sitemap batches are typically only minutes to hours old, so this rarely filters anything in practice. |
| `keyword_filter` | no | Case-insensitive substring match against each job's title, applied on this Actor's side. Leave empty to keep every job found. |
| `fetch_full_description` | no | Include the full description text in the output row (default `true`). The job's own page is fetched either way — this only controls whether the text is kept. |
| `sitemap_override_url` | no | Advanced/diagnostic: override the sitemap URL this Actor walks. Leave empty for normal use. |

```json
{
    "max_items": 3
}
```

### Output

One dataset row per job found. This is a real row from a real run (31.07.2026):

```json
{
    "found": true,
    "url": "https://www.xing.com/jobs/minfeld-steuerfachkraft-minfeld-mindestens-52-000-100-remote-156829244",
    "job_id": "156829244",
    "title": "Steuerfachkraft (m/w/d) in Minfeld mindestens 52.000€ - 100% Remote möglich",
    "company": "Taxtalente.de",
    "company_url": "https://www.xing.com/pages/taxtalente",
    "location": "Minfeld, Rheinland-Pfalz",
    "country": "DE",
    "employment_type": "Vollzeit",
    "posted_date": null,
    "salary_raw": null,
    "description": "TaxTalente ist eine junge Job-Matching Plattform für Jobsuchende und Unternehmen in der Steuerberatung. Unser Anspruch ist es, Bewerbern in der Steuerberatung das Leben zu vereinfachen und ihnen zu ihrem Traumjob zu verhelfen. Auf Basis deiner Wünsche können wir dir deinen passenden Job, aus der Vielzahl von Top-Kanzleien in unserem deutschlandweiten Netzwerk vorschlagen und dir vollumfänglich mit unserer Expertise beratend zur Seite stehen. Derzeit suchen wir nach einer Steuerfachkraft (Steuerfachangestellter, Steuerfachwirt oder Bilanzbuchhalter) für eine unserer Partner-Kanzleien in Minfeld",
    "description_is_teaser": false,
    "source_board": "xing-jobs",
    "scraped_at": "2026-07-31T14:21:25.480Z",
    "industry": "Personaldienstleistungen und -beratung",
    "valid_through": "2027-07-30T06:03:10.000Z",
    "direct_apply": true,
    "listed_at": "2026-07-30T06:03:08.000Z"
}
```

| Field | What it means |
|---|---|
| `found` | Whether this row is a real job (`true`) or a notice/error row (`false`) |
| `url` | Direct link to the job posting — the unique key for this row |
| `job_id` | XING's own numeric job id (read from its own URL — XING's structured data carries no separate identifier field) |
| `title` | Job title |
| `company` | Hiring company name |
| `company_url` | Link to the company's XING page, when the posting has one — `null` otherwise |
| `location` | City and region as XING shows it |
| `country` | Country code (`DE`, `AT` or `CH`) |
| `employment_type` | XING's own label, e.g. `"Vollzeit"` (not translated) |
| `industry` | XING's own industry label for the posting (not translated) |
| `posted_date` | The date the posting's OWN text states, in the exact German phrasing this Actor looks for (`"ausgeschrieben am DD.MM.YYYY"`) — `null` whenever that phrase isn't in the description (common on direct-employer/corporate-template postings, roughly a quarter of samples), never a guess. |
| `listed_at` | XING's own raw `datePosted` from the posting's structured data — this is a relisting/refresh timestamp the source itself can carry for months without it reflecting when the job was really first posted, which is exactly why `posted_date` above is extracted from the text instead of taken from this field. |
| `valid_through` | ISO 8601 timestamp — when the posting expires, per XING |
| `direct_apply` | Whether XING flags this posting for its own one-click "quick apply" |
| `salary_raw` | Always `null` on this board — XING's DACH postings do not publish a salary field at all; this Actor never estimates or invents one |
| `description` | Full job description (HTML tags stripped), up to 600 characters, or `null` when `fetch_full_description` is off |
| `description_is_teaser` | Always `false` when `description` is present — every row comes from the job's own full page, never a search-result snippet |
| `source_board` | Always `"xing-jobs"` |
| `scraped_at` | When this Actor fetched the row |

A run whose keyword filter matched nothing (or whose entire candidate batch turned out withdrawn/filtered) pushes:

```json
{ "found": false, "error": "", "source_board": "xing-jobs", "scraped_at": "..." }
```

A run whose sitemap failed to load pushes an error row with a non-empty `error` (e.g. `"http 404"`) — never the same shape as "no matches".

### API

Start a run with a bearer token and explicit JSON input:

```bash
curl -sS -X POST 'https://api.apify.com/v2/acts/zinin~xing-jobs/runs?waitForFinish=60' \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  --data '{"max_items":3}'
```

Read Dataset rows using the returned `defaultDatasetId`:

```bash
curl -sS "https://api.apify.com/v2/datasets/$DEFAULT_DATASET_ID/items?clean=true&format=json" \
  -H "Authorization: Bearer $APIFY_TOKEN"
```

### MCP

For an Apify MCP client exposing the standard `call-actor` tool, send this exact payload:

```json
{
  "name": "call-actor",
  "arguments": {
    "actor": "zinin/xing-jobs",
    "input": {
      "max_items": 3
    }
  }
}
```

### Other tools we built

#### Need the rest of the picture?

These run on the same account, take the same shape of input and bill the same way, so they slot into an existing pipeline without new plumbing.

| Actor | Use it when |
|---|---|
| [jobs.ch Swiss Jobs Scraper](https://apify.com/zinin/jobs-ch-swiss) | You want the same DACH region's Swiss board covered too, not just Germany/Austria via XING. |
| [Company Hiring Radar](https://apify.com/zinin/company-hiring-radar) | You already know the company and want every open role straight from its own ATS (Greenhouse/Lever/Ashby), not a board listing. |
| [Job Postings Aggregator](https://apify.com/zinin/job-postings-aggregator) | You need one normalized feed pulled across several companies' own ATS pages, beyond a single board. |
| [Layoff Tracker](https://apify.com/zinin/layoff-tracker) | You want a labor-market signal (recent layoffs) on a company that's also posting XING jobs. |

### FAQ

**Does it need an API key / login?** No — it reads XING's public sitemap and public job pages, no session required.

**Why do I sometimes get fewer jobs than `max_items`?** A meaningful share of freshly-listed jobs on this board are withdrawn (HTTP 410) within hours of being listed — this Actor automatically tries extra candidates to compensate, but on a small `max_items` value it can still occasionally return less than asked if the board's live churn that moment is unusually high.

**Why is `salary_raw` always `null`?** Because XING's DACH job postings do not publish a salary field at all. This Actor never estimates or guesses a number.

**Can I filter by keyword?** Yes, via `keyword_filter` — a case-insensitive match against the job title, applied after this Actor fetches each candidate page (XING's own job search needs a browser session and is not used here).

**How fresh is the data?** Live at run time — XING regenerates its job sitemap on the order of every few tens of minutes.

**Can I call it from an AI agent?** Yes — standard Apify Actor, callable from the Apify API, the SDK, or the Apify MCP server.

**What this is NOT.** It does not apply to jobs on your behalf, does not cover job boards outside xing.com, and does not invent a salary figure when the source has none.

Found a wrong result, or need a check we don't run? Open an issue on this Actor's page.

***

Built by [zinin](https://apify.com/zinin). Questions? Telegram [@timzinin](https://t.me/timzinin).

# Actor input Schema

## `max_items` (type: `integer`):

How many job rows to deliver, at most. This Actor walks xing.com's own job sitemap and visits each candidate job page individually — a meaningful share of freshly-listed jobs are already withdrawn (HTTP 410) by the time they're visited, which is normal churn, not a fault. Extra candidates are attempted automatically to compensate, so this number is a target, not a guarantee.

## `freshness_days` (type: `integer`):

Skip sitemap entries older than this many days. In practice xing.com's own sitemap entries are typically only minutes to hours old at any given time, so this rarely filters anything out.

## `keyword_filter` (type: `string`):

Optional case-insensitive substring match against each job's title, applied on this Actor's side after fetching the job's own page. xing.com's job search itself needs a browser session and is not used here — there is no server-side keyword search on this Actor. Leave empty to keep every job found.

## `fetch_full_description` (type: `boolean`):

Include the job's full description text in the output row. This Actor already fetches each job's own page to get any data at all (title, company, location...), so the description costs no extra request either way — this setting only controls whether it's kept in the row.

## `sitemap_override_url` (type: `string`):

Advanced: override the internal xing.com jobs sitemap URL this Actor walks. Leave empty to use the live xing.com jobs sitemap index. Mainly useful for diagnostics.

## Actor input object example

```json
{
  "max_items": 3,
  "freshness_days": 14,
  "fetch_full_description": true
}
```

# Actor output Schema

## `results` (type: `string`):

API URL for the default dataset items produced by this run.

# 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 = {
    "max_items": 3
};

// Run the Actor and wait for it to finish
const run = await client.actor("zinin/xing-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 = { "max_items": 3 }

# Run the Actor and wait for it to finish
run = client.actor("zinin/xing-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 '{
  "max_items": 3
}' |
apify call zinin/xing-jobs --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/Y9pG03jNzswG0bhOx/builds/KIRkb2OhEEalxvBnG/openapi.json
