# Personio Jobs Scraper: Open Positions from Career Pages (`bogdiehard/personio-jobs-scraper`) Actor

Extracts every open position from companies that use Personio: title, office, department, employment type, keywords, full job description and published salary ranges, from their public job feed.

- **URL**: https://apify.com/bogdiehard/personio-jobs-scraper.md
- **Developed by:** [Demetrius Greses Jr](https://apify.com/bogdiehard) (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 $0.70 / 1,000 results

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

## Personio Jobs Scraper: Open Positions from Career Pages

Extracts every open position from companies that use Personio, with title, office, department, employment type, keywords, full job description text and published salary ranges, for job boards, recruiters and sales teams that need structured hiring data.

### Use cases

- **Job boards and aggregators** load every open position of a list of Personio employers into one feed, refreshed on a schedule.
- **Recruiters and HR-tech tools** search open roles by department, keyword or office and link candidates to the live job page.
- **B2B sales teams** use new postings as hiring signals to find companies that are growing their teams.
- **Labor-market analysts** compare how many roles each employer opens, by occupation, seniority and city.

### Sample output

| Title | Company | Office | Created |
| --- | --- | --- | --- |
| (Senior) Aktuar (m/w/d) mit Schwerpunkt Solvency II (20h) (m/w/d) | ottonova Krankenversicherung AG - 9698 | München | 2026-03-23 |
| Account Executive (w/m/d) | Everphone GmbH | Berlin Köpenicker Straße 154, 10997 Berlin | 2025-03-17 |
| (Senior) CRM Manager (m/w/d) | CLARK Holding SE | Berlin | 2025-11-04 |

One item as JSON:

```json
{
    "id": "ottonova:2573573",
    "positionId": "2573573",
    "companySlug": "ottonova",
    "company": "ottonova Krankenversicherung AG - 9698",
    "title": "(Senior) Aktuar (m/w/d) mit Schwerpunkt Solvency II (20h) (m/w/d)",
    "office": "München",
    "additionalOffices": ["Köln"],
    "department": "Risk Management & Actuary",
    "recruitingCategory": "Versicherung",
    "employmentType": "permanent",
    "seniority": "experienced",
    "schedule": "full-or-part-time",
    "yearsOfExperience": null,
    "keywords": ["Solvency 2", "Risikomanagemen", "Aktuariat", "Risk Reporting"],
    "occupation": "acturial_analysis",
    "occupationCategory": "accounting_and_finance",
    "description": "DEIN TEAM\nottonova ist eine rein digitale private Krankenversicherung - innovativ, zeitgemäß und anders. An unseren Standorten München und Köln entwickeln wir z…",
    "createdAt": "2026-03-23T15:24:29.000Z",
    "salaryMin": null,
    "salaryMax": null,
    "salaryCurrency": null,
    "salaryPeriod": null,
    "jobUrl": "https://ottonova.jobs.personio.de/job/2573573",
    "sourceUrl": "https://ottonova.jobs.personio.de/job/2573573",
    "scrapedAt": "2026-10-11T01:11:57.844Z"
}
```

### Pricing

**$1 per 1,000 results.** A 500-result run costs about $0.50. You pay only for results saved to your dataset, plus Apify's standard start fee of $0.00005 per run. Apify Silver and Gold plan users get lower per-result prices automatically.

Set **Max results** to cap what a run can cost. The Actor stops cleanly when it reaches your spending limit.

### Input

| Field | Type | Description |
| --- | --- | --- |
| `companies` | array | Required. Personio company slugs or career-page URLs, for example `1komma5grad` or `https://ottonova.jobs.personio.de`. Values that are not Personio career pages are ignored. |
| `language` | string | Optional language code such as `en` or `de`. Leave empty for each company's default-language text. With `en`, positions without an English version have an empty description. |
| `keywords` | array | Keep only positions whose title, department or keywords contain any of these words (case-insensitive). Leave empty to keep every position. |
| `includeDescription` | boolean | Add the full job description as plain text with section headings. Default `true`. Turn off for a smaller dataset. |
| `maxItems` | integer | Maximum number of positions to return. Default 100. You are charged per result. |
| `proxyConfiguration` | object | Personio's public job feed needs no proxy, so none is used by default. |

**How to find a company slug:** open the company's careers page. If the address is `https://ottonova.jobs.personio.de`, the slug is `ottonova`, the part before `.jobs.personio.de`. You can paste the full URL instead.

Example input:

```json
{
    "companies": ["1komma5grad", "ottonova", "everphone"],
    "maxItems": 20
}
```

### Integrations

- **API:** run the Actor and fetch results with the [Apify API](https://docs.apify.com/api/v2) or the JavaScript and Python clients.
- **AI agents:** call it as a tool through the [Apify MCP server](https://mcp.apify.com).
- **No-code:** connect it to Make, Zapier or n8n, or export results straight to Google Sheets.
- **Scheduling:** run it daily or hourly with Apify Schedules and get only fresh data.

### FAQ

**What are the limits?** Each run reads one public XML feed per company, three at a time, and returns what the company publishes in that feed. Descriptions are plain text, capped at 10,000 characters. A slug that is not a Personio career page returns "not found": it is skipped and logged, and the run fails only when it returns no results at all.

**Is this legal?** The Actor collects public data only: each company's public job feed. It needs no login, does not solve CAPTCHAs and crawls at a polite rate. It is not affiliated with, endorsed by or connected to Personio. You are responsible for how you use the data.

**Why are the salary fields often empty?** `salaryMin`, `salaryMax`, `salaryCurrency` and `salaryPeriod` are filled only when the company publishes a salary range in its Personio feed (for example `2410`, `EUR`, `monthly`). Many companies do not, so expect them on a minority of positions.

**Something broke or a field is missing?** Open an issue on the Actor's Issues tab. We answer within one business day and usually ship a fix within 48 hours.

### Related Actors

- [More Husena Actors](https://apify.com/bogdiehard) — the rest of the catalog.

### Changelog

- **0.1** (2026-10-10) — First release.

# Actor input Schema

## `companies` (type: `array`):

Personio company slugs or career-page URLs, for example 1komma5grad or https://ottonova.jobs.personio.de. The slug is the part of the careers URL before .jobs.personio.de. Values that are not Personio career pages are ignored.

## `language` (type: `string`):

Optional language code such as en or de. Leave empty to get each company's default-language text. With en, positions that have no English version come back with an empty description.

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

Keep only positions whose title, department or keywords contain any of these words (case-insensitive). Leave empty to keep every position.

## `includeDescription` (type: `boolean`):

Add the full job description as plain text with section headings. Turn off for a smaller dataset.

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

Maximum number of positions to return. You are charged per result.

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

Personio's public job feed needs no proxy, so none is used by default.

## Actor input object example

```json
{
  "companies": [
    "1komma5grad",
    "ottonova",
    "everphone"
  ],
  "includeDescription": true,
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

No description

## `stats` (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 = {
    "companies": [
        "1komma5grad",
        "ottonova",
        "everphone"
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("bogdiehard/personio-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 = {
    "companies": [
        "1komma5grad",
        "ottonova",
        "everphone",
    ],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("bogdiehard/personio-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 '{
  "companies": [
    "1komma5grad",
    "ottonova",
    "everphone"
  ],
  "maxItems": 20
}' |
apify call bogdiehard/personio-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,bogdiehard/personio-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/YAyK9HSHHgnhTIPnj/builds/hnuejshvUbEgYgJyC/openapi.json
