# Xing Jobs Scraper (`nice_dev/xing-jobs-scraper`) Actor

Scrape Xing job ads (DE, AT, CH) by keyword, location or search URL: full description, salary, postcode, keywords, company. Export to JSON, CSV or Excel.

- **URL**: https://apify.com/nice\_dev/xing-jobs-scraper.md
- **Developed by:** [Nice Dev](https://apify.com/nice_dev) (community)
- **Categories:** Jobs, Lead generation, MCP servers
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.24 / 1,000 job ads

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### 💼 What is Xing Jobs Scraper?

**Xing Jobs Scraper** extracts **job ads from [Xing](https://www.xing.com/jobs)**, the leading professional network in Germany, Austria and Switzerland: **job title, company, city and postcode, salary, the full job description and the application link**, for any keyword, location or search URL.

Type a **keyword** (`developer`) and a **location** (`Berlin`), click **Start**, and download the ads in JSON, CSV or Excel. No login, nothing to set up, and it is **fast: about 300 job ads a minute on the Apify platform, full descriptions included**, from **$0.30 per 1,000 ads** (less on paid Apify plans).

### 📋 What data can you extract from Xing?

One item per job ad, 60 fields, every one of them filled from the same request — nothing costs an extra page:

| Field                                                                 | Example                                                                                      |
| --------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| `id`, `globalId`, `url`, `slug`, `title`, `jobCode`, `language`        | `157931744.b9b172`, `https://www.xing.com/jobs/berlin-abap-developer-157931744`, `SAP ABAP Developer (m/w/d)` |
| `publishedAt`, `refreshedAt`, `activeUntil`                            | `2026-09-16T04:12:33.000Z` (`publishedAt` is what the date filters read; the "Posted N days ago" of xing.com follows `refreshedAt`), expiry date |
| `employmentType`, `careerLevel`, `discipline`, `industry`              | `Full-time`, `Professional/Experienced`, `IT and software development`, `Software` — Xing's English labels, whatever the language of the ad |
| `remoteOptions`, `isRemote`, `isHybrid`, `isOnsite`                    | `["PARTLY_REMOTE"]`, `false`, `true`, `false`                                                  |
| `keywords`                                                             | `["sap", "abap", "developer"]` — up to 10 skills Xing attaches to the ad                       |
| `salaryMin`, `salaryMax`, `salaryMedian`, `salaryCurrency`, `salaryIsEstimate`, `salaryText` | `55000`, `75000`, `null`, `EUR`, `false` (`true` = estimated by Xing, `null` = no salary), `55,000 – 75,000 EUR` |
| `city`, `postalCode`, `street`, `region`, `countryCode`, `country`, `additionalLocations` | `Berlin`, `10963`, `Ritterstraße 12`, `Land Berlin`, `DE`, `Germany`, the OTHER places of a multi-city ad (`[]` for a single-city one) |
| `companyName`, `companyId`, `companyUrl`, `companyLogoUrl`, `companySize`, `companySizeMin`, `companySizeMax`, `companyIndustry`, `companyRating`, `companyWebsite`, `companySocialLinks` | `nexvysion GmbH`, `923667.9f72df`, company page, `51-200 employees`, `51`, `200`, kununu rating (always `null` today, see Known limitations) |
| `applyUrl`, `applicationType`, `redirectsToThirdPartyUrl`              | external application link, `UrlApplication`, `false`                                           |
| `isPaid`, `isTopJob`, `isPrioritized`                                  | `true`, `false`, `true` — paid placement on the results page                                   |
| `description`, `descriptionHtml`, `descriptionSections`                | the WHOLE ad as text and as HTML, plus its blocks: company, responsibilities, requirements, benefits, contact |
| `summary`, `headerImage`, `footerImage`, `videoUrls`                   | Xing's own summary (introduction, responsibilities, qualifications), the ad's images and videos |
| `searchQuery`, `searchLocation`, `searchUrl`, `scrapedAt`              | where the ad came from, ISO timestamp                                                          |

There is no "extract details" option to tick: the description, the salary and the postcode come with every ad.

### ✅ Why use Xing Jobs Scraper?

- 🚀 **Fast and cheap**: about 300 job ads a minute with their full description (1,189 in 3.5 minutes, measured on the Apify platform), from $0.30 per 1,000.
- 📄 **The whole ad, always**: description as text AND as HTML, split into the blocks the employer wrote (company, tasks, profile, benefits, contact). Other scrapers open a second page for it; here it comes with the ad.
- 📮 **What the results page does not show**: postcode, street, region, up to 10 skill keywords, `jobCode`, the expiry date, and whether the salary is the employer's or Xing's estimate.
- 🧱 **Past the site's 1,000-result wall**: Xing serves at most 1,000 ads per search. A wider search is split automatically by contract type, career level and remote option, so a whole-country run keeps going.
- 🗂️ **Several searches in one run**: keywords × locations, with a cap per search so that one big city cannot eat the whole budget.
- 🔔 **Monitoring built in**: tick **Only new job ads**, schedule the Actor, and each run returns (and charges) only what it has never delivered before.
- 🔌 API, scheduling, monitoring, integrations (Make, Zapier, n8n, Google Sheets…), proxy rotation and JSON/CSV/Excel export via the Apify platform.

### 🚀 How to scrape Xing

1. Create a free Apify account.
2. Open **Xing Jobs Scraper** and type a **Search keyword** (e.g. `developer`) and a **Location** (e.g. `Berlin`, `Wien`, or a whole country such as `Deutschland`).
3. Or paste your own Xing URLs into **Start URLs**: any job-search page (all filters set on the site are kept, pagination is automatic) or single job pages.
4. Set **Max listings** (100 by default, 0 = no limit) — and **Max job ads per search** when you run several searches — then click **Start**.
5. Download the dataset in JSON, CSV, Excel or via API.

### 💰 How much does it cost to scrape Xing?

This Actor uses **pay per event** pricing — a launch price, full descriptions included:

| Apify plan | Price per 1,000 job ads |
| --- | --- |
| Free | **$0.30** |
| Bronze | $0.28 |
| Silver | $0.26 |
| Gold | $0.24 |

Plus **$0.001 per run start** (10 cents per 100 runs). The filters Xing does not apply itself (`postedAfter` / `postedBefore`, `excludeKeywords`, `salaryMin` / `salaryMax`, `onlyWithSalary`, `disciplines`, `industries`) are checked by the Actor on every ad it reads: an ad you keep costs its normal price, an ad a filter drops costs **$0.04 per 1,000** (`filter-check`; $0.038 on Bronze, $0.036 on Silver, $0.034 on Gold) — filtering never costs more than taking everything. Platform usage (compute, proxy) is included in the price.

- A whole-Germany scrape of 20,000 job ads ≈ **$6**.
- A daily monitor of 300 new job ads ≈ **$0.09** a day.
- The $5 of free credits every Apify account starts with already cover about **16,000 job ads**.

An ad your filters drop is never saved nor charged as an ad (only its small filter check), and you never pay twice for the same ad (`onlyNew`).

### ⚙️ Input

```json
{
    "query": "developer",
    "location": "Berlin",
    "maxItems": 200
}
```

Several searches, a cap per search, only recent ads, only the ones not delivered before:

```json
{
    "searchQueries": ["developer", "controller"],
    "locations": ["Berlin", "Hamburg"],
    "maxItemsPerQuery": 50,
    "postedAfter": "7 days",
    "onlyNew": true,
    "stateKey": "dach-developers"
}
```

Filtered by the site itself (a filtered-out ad is never downloaded, so it costs nothing; an ad Xing returns outside these filters anyway is dropped and not charged either):

```json
{
    "query": "developer",
    "location": "Deutschland",
    "employmentType": ["FULL_TIME"],
    "careerLevel": ["PROFESSIONAL_EXPERIENCED"],
    "remoteOption": ["FULL_REMOTE"],
    "maxItems": 1000
}
```

Or with your own URLs:

```json
{
    "startUrls": [
        { "url": "https://www.xing.com/jobs/search?keywords=developer&location=Berlin" },
        { "url": "https://www.xing.com/jobs/berlin-professional-abap-developer-157931744" }
    ],
    "maxItems": 500
}
```

| Field                                                | Notes                                                                                                                                             |
| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `query`, `searchQueries`                             | Free-text search, exactly as typed on xing.com; `searchQueries` adds more keywords (one search each). Ignored when `startUrls` is set.              |
| `location`, `locations`                              | City, region or country: `Berlin`, `Wien`, `Deutschland`. `locations` adds more places; every keyword is searched in every location (max 500 searches per run). |
| `radius`                                             | Kilometres around the location (50 for instance); 0 = the site's own default, about 5 km. |
| `startUrls`                                          | Xing job-search pages (filters kept, pagination automatic) or single job pages.                                                                     |
| `employmentType`                                     | Contract types, applied by Xing itself: `FULL_TIME`, `PART_TIME`, `CONTRACTOR`, `INTERN`, `SEASONAL`, `TEMPORARY`, `VOLUNTARY`. |
| `careerLevel`                                        | Seniority: `STUDENT_INTERN`, `ENTRY_LEVEL`, `PROFESSIONAL_EXPERIENCED`, `MANAGER_SUPERVISOR`, `EXECUTIVE`, `SENIOR_EXECUTIVE`. Xing sometimes returns ads of another level anyway (see Known limitations): the Actor drops them, unpaid. |
| `remoteOption`                                       | Work arrangement: `FULL_REMOTE`, `PARTLY_REMOTE`, `NON_REMOTE`. |
| `salaryMin`, `salaryMax`                             | Gross salary range, compared with the figures Xing publishes or estimates for the ad, as they are — in EUR for most ads, in CHF for Swiss ones, yearly for most, monthly for some internships (the item says the currency). Checked after reading the ad (Xing's own salary filter has no effect): each ad dropped costs the filter fee, lower than an ad (see Pricing); an ad you keep costs its normal price; an ad without any salary is dropped. |
| `companyIds`                                         | Watch given employers, by the Xing company id every run returns: `923667.9f72df`. |
| `benefitIds`                                         | Keep only the ads offering given benefits, by the Xing benefit id read in a search URL: `10.161507`. |
| `disciplines`                                        | Keep only the ads whose job field contains one of these words: `IT and software development`. Case and accents ignored. |
| `industries`                                         | Keep only the ads whose industry contains one of these words: `Software`. Case and accents ignored. |
| `descriptionFormat`                                  | How the full description is saved: `both` (default), `html` or `text`. |
| `maxItems`                                           | Stop after this many ads for the whole run (0 = unlimited).                                                                                        |
| `maxItemsPerQuery`                                   | Cap for EACH search (keyword × location, or search URL). 0 = no per-search cap.                                                                    |
| `postedAfter`, `postedBefore`                        | Publication date range: `2026-09-01`, or a period before now: `7 days`, `2 weeks`, `1 month`, `24 hours`. |
| `excludeKeywords`                                    | Drop the ads whose title or company contains one of these words (case and accents ignored).                                                        |
| `onlyWithSalary`                                     | Keep only the ads carrying a salary, published or estimated.                                                                                       |
| `onlyNew`, `stateKey`, `resetState`                  | Monitoring: only the ads never delivered under this memory key; `resetState` forgets the memory.                                                    |
| Advanced                                             | `proxyConfiguration` (Apify proxy by default, included in the price; the residential proxy is not available), `maxConcurrency`, `maxRequestsPerMinute`, `maxRequestRetries`, `debugLog`. |

### 📦 Output

One real item, shortened (the description and the blocks are much longer):

```json
{
    "id": "157931744.b9b172",
    "globalId": "job.posting.157931744",
    "url": "https://www.xing.com/jobs/berlin-professional-abap-developer-157931744",
    "slug": "berlin-professional-abap-developer-157931744",
    "title": "Professional ABAP Developer (m/w/d)",
    "jobCode": "REQ-2026-0417",
    "language": "de",
    "publishedAt": "2026-09-16T04:12:33.000Z",
    "refreshedAt": "2026-09-18T06:00:00.000Z",
    "activeUntil": "2026-10-16T04:12:33.000Z",
    "employmentType": "Full-time",
    "careerLevel": "Professional/Experienced",
    "discipline": "IT and software development",
    "industry": "Software",
    "remoteOptions": ["PARTLY_REMOTE"],
    "isRemote": false,
    "isHybrid": true,
    "isOnsite": false,
    "keywords": ["sap", "abap", "developer"],
    "salaryMin": 55000,
    "salaryMax": 75000,
    "salaryMedian": null,
    "salaryCurrency": "EUR",
    "salaryIsEstimate": false,
    "salaryText": "55,000 – 75,000 EUR",
    "city": "Berlin",
    "postalCode": "10963",
    "street": "Ritterstraße 12",
    "region": "Land Berlin",
    "countryCode": "DE",
    "country": "Germany",
    "additionalLocations": [],
    "companyName": "nexvysion GmbH",
    "companyId": "923667.9f72df",
    "companyUrl": "https://www.xing.com/pages/nexvysion",
    "companyLogoUrl": "https://www.xing.com/imagecache/public/scaled_original_image/eyJ1dWlkIjoi...",
    "companySize": "51-200 employees",
    "companySizeMin": 51,
    "companySizeMax": 200,
    "companyIndustry": "Software",
    "companyRating": null,
    "companyWebsite": "https://www.nexvysion.de",
    "companySocialLinks": { "website": "https://www.nexvysion.de", "facebook": null, "twitter": null },
    "applyUrl": "https://jobs.netgroup-beteiligungen.de/de/p/nexvysion/jobs/10115/intro",
    "applicationType": "UrlApplication",
    "redirectsToThirdPartyUrl": false,
    "isPaid": true,
    "isTopJob": false,
    "isPrioritized": true,
    "description": "Intro\nWe are looking for an experienced ABAP developer...",
    "descriptionHtml": "<p><b>Intro</b><br>We are looking for an experienced ABAP developer...</p>",
    "descriptionSections": {
        "companyDescription": { "title": "About us", "html": "<p>...</p>", "text": "..." },
        "responsibilities": { "title": "Your tasks", "html": "<p>...</p>", "text": "..." },
        "benefits": { "title": "We offer", "html": "<p>...</p>", "text": "..." }
    },
    "summary": {
        "introduction": "Join a small ABAP team in Berlin",
        "keyResponsibilities": ["Develop and maintain SAP modules"],
        "qualifications": ["3 years of ABAP"]
    },
    "headerImage": null,
    "footerImage": null,
    "videoUrls": [],
    "searchQuery": "developer",
    "searchLocation": "Berlin",
    "searchUrl": "https://www.xing.com/jobs/search?keywords=developer&location=Berlin&page=1",
    "scrapedAt": "2026-09-20T12:00:00.000Z"
}
```

You can download the dataset in various formats such as JSON, HTML, CSV or Excel.

### 💡 Tips

#### How to get more results

Xing serves at most 1,000 ads per search. Above that, this Actor splits the search by contract type, then career level, then remote option — each part has its own 1,000-ad window — so `maxItems: 0` on a country-wide keyword keeps going far past the wall. You can also give several narrower searches (`searchQueries` × `locations`), which is faster still.

#### How to reduce costs

The price is per ad, so the levers are `maxItems`, `maxItemsPerQuery`, the site filters (`employmentType`, `careerLevel`, `remoteOption` — a filtered-out ad is never downloaded, and one the site returns outside them anyway is dropped unpaid), the post-filters (`postedAfter`, `excludeKeywords`, `disciplines`, `onlyWithSalary`, `salaryMin` / `salaryMax` — a filtered-out ad costs only its small filter check; a narrow filter on a wide search checks many ads to keep few) and `onlyNew` for recurring runs (you never pay twice for the same ad).

#### Several searches in one run

Fill `searchQueries` and / or `locations`: the Actor runs one search per keyword × location (3 keywords × 4 cities = 12 searches, up to 500 per run). The single `query` and `location` fields still work and are added to the lists. An ad found by several searches is saved — and charged — once. Set `maxItemsPerQuery` to give every search its own cap: without it the first searches can use up the whole `maxItems` budget. You can also paste several search URLs into `startUrls`: each one is a search of its own, with the same cap.

#### Monitoring: only the new job ads

Tick **Only new job ads** (`onlyNew`) and schedule the Actor. The first run returns everything; each later run skips the ads already delivered: they are not saved and not charged. The memory lives in a named key-value store of your account (`xing-jobs-scraper-seen`, up to 150,000 listings per key) and is only updated with ads that really reached the dataset, so a failed run never hides anything. Give each schedule its own `stateKey` (two schedules sharing a key would hide each other's ads), and tick `resetState` once to start over.

#### Filter by publication date

`postedAfter` and `postedBefore` take a date (`2026-09-01`, the whole day is included, in Germany/Austria/Switzerland's local calendar day — CET/CEST, not UTC) or a period before now (`7 days`, `2 weeks`, `1 month`; via the API also `24 hours` or a full ISO date-time, which is read exactly as given). The filter reads `publishedAt` — the day the ad went live, not the day the employer last refreshed it. Xing itself offers no date filter and no date sort, so the ads are read first and filtered afterwards: filtered-out ads are not saved and do not count in `maxItems` (each ad dropped costs the filter fee, see Pricing), and the run summary tells how many were dropped.

### 🔌 Integrations and API

Call the Actor via the Apify API, the JavaScript or Python clients, or connect it with integrations and webhooks (Make, Zapier, n8n, Google Sheets, Slack, Airtable…). The dataset can be fetched as JSON or CSV from any tool.

### 🤖 Use with AI agents (MCP)

AI agents (Claude, ChatGPT, Cursor…) can find and run this Actor through the [Apify MCP server](https://mcp.apify.com), billed to their Apify account like any run. It returns one item per Xing job ad. Actor id: `nice_dev/xing-jobs-scraper`; MCP server with this Actor only: `https://mcp.apify.com/?tools=fetch-actor-details,nice_dev/xing-jobs-scraper`.

Smallest input, for a cheap first call:

```json
{
    "query": "developer",
    "location": "Berlin",
    "maxItems": 10
}
```

Key output fields: `url`, `title`, `companyName`, `city`, `salaryText`, `employmentType`, `description`, `publishedAt`.

Cost: $0.30 per 1,000 job ads plus $0.001 per run start ($0.24 per 1,000 on the Gold plan); an ad a filter of the Actor drops costs $0.04 per 1,000, see the pricing section above. Cap each call with `maxItems` and, through the API, with the run option `maxTotalChargeUsd`.

### ❓ FAQ

#### Is it legal to scrape Xing?

The Actor only reads what Xing shows publicly to any anonymous visitor: job ads published by employers. It logs in to nothing, and it collects no member profiles. A job ad can still contain personal data (a contact name in the description), which is protected by GDPR: do not store it without a legitimate reason. You are responsible for using the data in compliance with Xing's Terms of Use and applicable law. This Actor is not affiliated with Xing.

#### Does it need a login or a proxy?

No login. The proxy is included in the price: leave the default setting (the residential proxy is not available). A request the site turns away is retried at once on a new proxy session (without a proxy, after a pause of 5 seconds, doubled at each retry up to 150 seconds).

#### Is the data safe to open in Excel or to show on a web page?

Job titles and descriptions are the employers' own words, copied as they are. A text can begin with `-`, `+`, `=` or `@` (a title such as `-20% Reisezeit`, a phone number in the contact block): Excel and Google Sheets may read such a cell of a CSV file as a formula or as a number. The Actor leaves the text as it is, so that the JSON and the API give the real value: when you open a CSV, import these columns as text. Every URL field holds an http(s) URL or `null`. `descriptionHtml` and the `descriptionSections` blocks are the employer's own HTML and are **not** sanitized: escape them like any text written by a stranger before showing them on a web page. The only HTML the Actor writes itself (the `<h2>` title above each block) is escaped. Text and HTML fields are cut at 32,000 characters (what one Excel cell holds), an HTML field never inside a tag, and control characters (other than tabs and line breaks) are removed from every field, whether written raw or as an HTML entity.

#### Known limitations

- The site serves at most 1,000 ads per search; above that the Actor splits the search by contract type, career level and remote option. A search still above 1,000 after those three is read up to 1,000 ads, and the log says so.
- `companyRating` (kununu's average) is a members-only field: the public API this Actor reads (no login) never fills it — it comes back `null` on every ad, whatever the company.
- Xing has no date sort and no date filter of its own: `postedAfter` / `postedBefore` are applied after the ads are read, so a narrow date range on a wide search reads many ads to keep few — each ad dropped at the filter fee. Narrow the search itself (keywords, location, site filters) rather than the dates.
- Xing accepts `salaryMin` / `salaryMax` without an error but does not apply them either: like the date range, this Actor reads every ad and drops the ones outside the range afterward, each one dropped at the filter fee — a narrow salary range on a wide search reads many ads to keep few, exactly as a narrow date range does. The bounds are compared with the figures as Xing gives them, without converting: a Swiss ad is in CHF (24 of the 776 salaried ads of a DACH-wide search, all of them on a Swiss search), and some internships are paid monthly (`€900 – €1,100`), so a yearly floor drops them.
- `disciplines` and `industries` match the names Xing prints; the site publishes no list of them, so type them as they appear in the data (`IT and software development`).
- `employmentType`, `careerLevel`, `discipline`, `industry`, `country` and `companySize` are Xing's **English** labels on every ad, whatever the language of the ad itself (`Full-time`, not `Vollzeit`): the Actor asks the site for them in English, so that the same value always reads the same and the `disciplines` / `industries` filters can be typed once.
- Xing's own `careerLevel` filter is not always honoured by the site: on some searches the same ads come back under every level asked for (measured 2026-09-22: 11 ads in 20 of another level on a small search). The Actor checks every ad against the `employmentType`, `careerLevel` and `remoteOption` you set and drops the ones outside them — they are counted as filtered and never charged.
- `publishedAt` is the day the ad first went live. The "Posted N days ago" shown on xing.com follows `refreshedAt` (the employer's last refresh), so it can read newer than `publishedAt`; both dates are in the item.
- A place Xing does not recognize is not an error and does not return zero ads: the site silently drops the location and searches the whole DACH region instead (measured 2026-09-22: `developer` with no location, with an empty location and with a misspelled one all return the exact same, much larger figure that a real city does not). Type the place as it autocompletes on xing.com, and check that the ad count looks right for the size of the place you asked for — a `location` that does nothing can turn a small, cheap search into a large, unexpectedly priced one.
- `onlyNew` remembers ad ids, not their content: an ad whose description changed is not returned again.
- Two runs sharing the same `stateKey` at the same time may both return the same new ad.
- Member profiles, company pages and employee lists are out of scope: this Actor returns job ads.

**A run the platform stops without warning** (out of memory, run timeout)

- Resurrect it: it goes on from where it stood at most a minute before the stop. What it had read since is read again, and the ads already saved are skipped: none is delivered or charged twice, and `maxItems` still counts them.
- With `onlyNew`, the memory is saved once a minute: resurrect the stopped run and the ads it had saved meanwhile join the memory; leave it stopped for good, and the next run may return up to a minute of them once more.

#### Something doesn't work?

The last line of the log counts the ads saved, filtered out and no longer on Xing (taken down while the run was reading them), and the requests that failed after every retry. Those requests and the removed ads are listed, with the reason, in the `FAILED_REQUESTS` record of the run's key-value store. A run that saved nothing and had failed requests fails, and its last message gives the cause (a search URL that does not exist says so, instead of "run it again"). A run that saved some ads fails too when at least as many requests failed for good as were read: a green run with a short dataset would hide an outage. One failed request among many is only a warning.

If Xing changes its pages, you are told instead of paying for blank rows. A results page that counts ads but gives none the Actor can read is an error (listed in `FAILED_REQUESTS`), never a quiet "No job ads found". If the first 20 listings read all lack their title, publication date, contract type, career level, company, city or description, the run saves nothing more, stops and fails, and its last message names the missing field: at most those first ads are charged. An ad that `postedAfter` / `postedBefore` drops because it has no date at all counts among those 20.

### 🛟 Support

Open an issue in the **Issues** tab with a link to your run: the run log and the `FAILED_REQUESTS` record of the key-value store show exactly which URLs failed and why.

# Actor input Schema

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

Xing search-result URLs (`https://www.xing.com/jobs/search?keywords=...&location=...`, the filters set on the site are kept) or single job URLs (`https://www.xing.com/jobs/<slug>`). When this list is not empty, the search fields below (keywords, locations) are ignored; filters, caps and monitoring still apply. Max 1 000 URLs.

## `query` (type: `string`):

Free-text search, exactly as typed on xing.com (e.g. `developer`, `Buchhalter`). Empty = every job ad matching the other filters.

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

Several keywords in one run: one search per keyword (times each location below). Added to **Search keyword**; ads found by several searches are saved once.

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

City, region or country as typed on the site (e.g. `Berlin`, `Wien`, `Deutschland`). Empty = the whole DACH region. A place Xing does not recognize is silently ignored (same as empty), never an error and never zero ads — type it as it autocompletes on xing.com.

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

Several locations in one run: every keyword is searched in every location (3 keywords × 4 locations = 12 searches, max 500). Added to **Location**.

## `radius` (type: `integer`):

Distance around the location, in kilometres. 0 = the site default (about 5 km). Measured on `developer` / Berlin: 533 ads at the default, 574 with 100 km.

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

Maximum number of job ads to save for the whole run (after deduplication and filters). 0 = no limit.

## `maxItemsPerQuery` (type: `integer`):

Cap for EACH search (keyword × location, or search URL), so that the first search cannot use up the whole **Max job ads** budget. 0 = no per-search cap. Xing itself never returns more than 1 000 ads per search; above that the Actor splits the search by employment type, career level and remote option to reach the rest.

## `employmentType` (type: `array`):

Keep only these contract types. Empty = all of them.

## `careerLevel` (type: `array`):

Keep only these seniority levels. Empty = all of them.

## `remoteOption` (type: `array`):

Keep only these work arrangements. Empty = all of them.

## `companyIds` (type: `array`):

Only the ads of these companies. A company ID looks like `923667.9f72df`; every run returns it, so you can copy one from a first run and then watch that employer.

## `benefitIds` (type: `array`):

Only the ads offering these benefits (company car, home office, canteen…). Xing identifies them by ID only, such as `10.161507`: copy one from a Xing search URL that has the benefit ticked.

## `disciplines` (type: `array`):

Keep only the ads whose job field contains one of these words, e.g. `IT and software development`, `Sales`. Case and accents are ignored. Empty = all fields.

## `industries` (type: `array`):

Keep only the ads whose industry contains one of these words, e.g. `Software`, `Consulting`. Case and accents are ignored. Empty = all industries.

## `descriptionFormat` (type: `string`):

How the full job description is saved: HTML as published, plain text, or both (default). The description always comes with the ad — it never costs an extra request.

## `postedAfter` (type: `string`):

Only ads published on or after this date: `2026-09-01` (a plain date is read in Germany/Austria/Switzerland's local day, not UTC), or a period before now such as `7 days`, `2 weeks`, `1 month` (API: `24 hours` and full ISO date-times work too). The date read is the day the ad went live, not the day it was last refreshed. Xing offers no date filter of its own, so the ads are filtered after download.

## `postedBefore` (type: `string`):

Only ads published on or before this date (the whole day is included), or older than a period such as `30 days`.

## `excludeKeywords` (type: `array`):

Drop the ads whose title contains one of these words (case and accents ignored).

## `onlyWithSalary` (type: `boolean`):

Keep only the ads that carry a salary — either published by the company or estimated by Xing (`salaryIsEstimate` tells which).

## `salaryMin` (type: `integer`):

Gross salary floor, compared with the figure Xing publishes or estimates for the ad, as it is: in EUR for most ads, in CHF for Swiss ones, yearly for most, monthly for some internships (no conversion). Checked after the ad is read (Xing's own salary filter has no effect). Ads without any salary are dropped when this is set.

## `salaryMax` (type: `integer`):

Gross salary ceiling, checked the same way as **Minimum salary** (the ad's own figure, EUR or CHF, yearly or monthly, no conversion).

## `onlyNew` (type: `boolean`):

Skip the ads that a previous run (same **Memory key**) already delivered: they are not saved and not charged. First run = everything is new.

## `stateKey` (type: `string`):

Name of the memory used by **Only new job ads**. Give each schedule / task its own key (e.g. `berlin-developers`) so that they do not share their memory. Letters, digits, `-` and `_`.

## `resetState` (type: `boolean`):

Forget everything remembered under this **Memory key** before the run: this run returns (and charges) every ad again. Untick it afterwards.

## `proxyConfiguration` (type: `object`):

Apify Proxy or your own proxies. Keep the default: it is included in the price. The residential Apify proxy is not available in this Actor.

## `maxConcurrency` (type: `integer`):

Maximum number of requests processed in parallel.

## `maxRequestsPerMinute` (type: `integer`):

Global request rate. Lower it if the site answers HTTP 429 / 403 in the log.

## `maxRequestRetries` (type: `integer`):

Retries per request before it is marked as failed.

## `debugLog` (type: `boolean`):

Include debug messages in the run log.

## Actor input object example

```json
{
  "startUrls": [],
  "query": "developer",
  "searchQueries": [],
  "location": "Berlin",
  "locations": [],
  "radius": 0,
  "maxItems": 100,
  "maxItemsPerQuery": 0,
  "employmentType": [],
  "careerLevel": [],
  "remoteOption": [],
  "companyIds": [],
  "benefitIds": [],
  "disciplines": [],
  "industries": [],
  "descriptionFormat": "both",
  "excludeKeywords": [],
  "onlyWithSalary": false,
  "onlyNew": false,
  "stateKey": "default",
  "resetState": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "maxConcurrency": 8,
  "maxRequestsPerMinute": 120,
  "maxRequestRetries": 5,
  "debugLog": false
}
```

# 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 = {
    "query": "developer",
    "location": "Berlin",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("nice_dev/xing-jobs-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 = {
    "query": "developer",
    "location": "Berlin",
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("nice_dev/xing-jobs-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 '{
  "query": "developer",
  "location": "Berlin",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call nice_dev/xing-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nice_dev/xing-jobs-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/4v3lP2pmuwBejnB9k/builds/Eg2ukwB6kk9j04lj5/openapi.json
