Personio Jobs & Careers Scraper avatar

Personio Jobs & Careers Scraper

Pricing

from $6.15 / 1,000 results

Go to Apify Store
Personio Jobs & Careers Scraper

Personio Jobs & Careers Scraper

Scrape Personio career page job listings by company. Extract job title, location, department, employment type, seniority, schedule, apply URL and full description. Filter by keyword. Export JSON, CSV or Excel. No login or API key.

Pricing

from $6.15 / 1,000 results

Rating

5.0

(1)

Developer

Scrapers Lat

Scrapers Lat

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

10 days ago

Last modified

Share

Personio Jobs & Careers Scraper

Personio Jobs & Careers Scraper

Here is one real result, with every field the actor returns (long description and section HTML trimmed for readability; the actor returns the full text):

{
"title": "(Senior) Accountant (m/w/d)",
"company": "ottonova Holding AG - 9680",
"location": "München",
"offices": [
"München"
],
"department": "Finance",
"recruitingCategory": "Corporate Functions",
"occupation": "corporate_finance",
"occupationCategory": "accounting_and_finance",
"employmentType": "permanent",
"seniority": "experienced",
"schedule": "full-time",
"yearsOfExperience": null,
"keywords": [
"Accounting",
"Finanzbuchhaltung",
"Buchhaltung",
"HGB",
"IFRS"
],
"url": "https://ottonova.jobs.personio.com/job/2656243",
"jobId": "2656243",
"subcompany": "ottonova Holding AG - 9680",
"company_subdomain": "ottonova",
"createdAt": "2026-06-03T14:10:30+00:00",
"sections": [
{ "name": "DEIN TEAM", "html": "ottonova ist eine digitale private Krankenversicherung [trimmed]" },
{ "name": "DEIN WIRKUNGSBEREICH", "html": "Im Accounting erwartet dich ein abwechslungsreicher Wirkungsbereich [trimmed]" },
{ "name": "DEIN PROFIL", "html": "Grundlage deines Profils bildet eine abgeschlossene kaufmännische Ausbildung [trimmed]" },
{ "name": "WORAUF DU DICH FREUEN DARFST", "html": "Bei ottonova hast du die Möglichkeit [trimmed]" },
{ "name": "URL", "html": "accounting" }
],
"descriptionHtml": "<h3>DEIN TEAM</h3>ottonova ist eine digitale private Krankenversicherung [trimmed]",
"descriptionText": "DEIN TEAM\nottonova ist eine digitale private Krankenversicherung [trimmed]",
"observedAt": "2026-08-10T14:17:34.889Z",
"error": null
}

The most complete Personio jobs scraper available. It returns every field a Personio career page exposes for each open role, plus the full structured description sections as HTML and clean text, and an optional contact-enrichment add-on, and gives you six filters to target exactly the jobs you need.

📥 Input · 📤 Output · 💰 Pricing · ▶️ Examples

Apify Coverage Output Billing

Table of contents

What it does

The actor loads one or more Personio company career pages, reads every open job, optionally fetches each job's full description, applies the filters you pass as input, and writes one normalized record per role to the run's dataset. The description is returned three ways: the raw descriptionHtml, a clean descriptionText, and the structured sections array with each named block kept separate, so you can index or display it however you need.

You point it at a company by its Personio subdomain (for example ottonova or optiply), the career page host (optiply.jobs.personio.com) or the full career page URL. Add one entry per company to scrape several boards in a single run. Missing source values are returned as null, never invented.

Quickstart

Open the actor, paste this into the input, and press Run. It returns up to 10 jobs across four Personio companies with full descriptions.

{
"maxJobs": 10,
"withDetails": true,
"companies": ["ottonova", "optiply", "everphone", "clark"],
"remoteOnly": false,
"enrichContacts": false,
"enrichContactsMax": 50
}

companies is required; every other field is optional. Turn withDetails off for a faster, lighter run that returns only the listing fields (title, location, department, employment type, seniority, schedule, apply URL, dates).

Input reference

FieldTypeRequiredDefaultDescription
companiesstring[]yes["ottonova","optiply","everphone","clark"]Personio companies to scrape. Enter the subdomain (for example optiply), the career page host (optiply.jobs.personio.com) or the full career page URL. Add one entry per company.
maxJobsintegerno10Maximum number of job listings to collect across all companies.
withDetailsbooleannotrueFetch each job's full description as HTML, clean text, and structured sections. Turn off for listing fields only.
searchQuerystringno(empty)Keyword filter applied after fetch. Matches title, department, location, category and description (case-insensitive).
remoteOnlybooleannofalseKeep only jobs whose location or office mentions remote.
employmentTypestringno(empty)Keep only jobs whose employment type contains this text, for example full, part, intern.
departmentstringno(empty)Keep only jobs whose department contains this text.
locationstringno(empty)Keep only jobs whose location or office contains this text.
postedAfterstringno(empty)Keep only jobs created on or after this ISO date, for example 2026-01-31.
enrichContactsbooleannofalseOptional paid add-on. For each result without an email, attempt to find a public business contact email and a contact person's name. Billed per attempt, plus an extra charge only when an email is found.
enrichContactsMaxintegerno50Cap how many results the add-on tries to enrich. Free Apify accounts are capped at 3.

Filters combine with logical AND.

Output reference

One dataset item per job. Types: string, string[], object[], or null when the source value is absent.

FieldTypeDescription
titlestringJob title.
companystringHiring company or subcompany name.
locationstringPrimary job location.
officesstring[]All offices or locations listed.
departmentstringDepartment.
recruitingCategorystringPersonio recruiting category.
occupationstringOccupation code.
occupationCategorystringOccupation category code.
employmentTypestringEmployment type, for example permanent, intern.
senioritystringSeniority, for example experienced, entry_level.
schedulestringWork schedule, for example full-time, part-time.
yearsOfExperiencestringRequired years of experience, or null.
keywordsstring[]Keywords or skills tagged on the job.
urlstringJob posting URL.
jobIdstringPersonio job id.
subcompanystringSubcompany the job belongs to.
company_subdomainstringPersonio subdomain of the company.
createdAtstringJob creation timestamp (ISO 8601).
sectionsobject[]Structured description blocks, each with a name and html. Present when withDetails is on.
descriptionHtmlstringFull description as HTML. Present when withDetails is on.
descriptionTextstringFull description as clean text. Present when withDetails is on.
observedAtstringISO 8601 timestamp of when the record was collected.
enrichedEmailstringContact enrichment add-on only: found public business email, or null.
enrichedContactNamestringContact enrichment add-on only: contact person name, or null.
enrichedEmailStatusstringContact enrichment add-on only: verified, likely, guessed, or not_found.
errorstringnull on success. On a failed company, a single item with a populated error field is written instead.

Enrichment fields (enriched*) appear only when you turn on the paid enrichContacts add-on.

Example output record

Real record from a live run (input {"companies": ["ottonova","optiply","everphone","clark"], "maxJobs": 10, "withDetails": true}), listing fields shown with the description trimmed:

{
"title": "(Senior) Accountant (m/w/d)",
"company": "ottonova Holding AG - 9680",
"location": "München",
"offices": ["München"],
"department": "Finance",
"recruitingCategory": "Corporate Functions",
"occupation": "corporate_finance",
"occupationCategory": "accounting_and_finance",
"employmentType": "permanent",
"seniority": "experienced",
"schedule": "full-time",
"yearsOfExperience": null,
"keywords": ["Accounting", "Finanzbuchhaltung", "Buchhaltung", "HGB", "IFRS"],
"url": "https://ottonova.jobs.personio.com/job/2656243",
"jobId": "2656243",
"subcompany": "ottonova Holding AG - 9680",
"company_subdomain": "ottonova",
"createdAt": "2026-06-03T14:10:30+00:00",
"observedAt": "2026-08-10T14:17:34.889Z",
"error": null
}

Run via API and CLI

Start a run and wait for it to finish, then read the dataset. Replace <TOKEN> with your Apify API token.

Run synchronously and get dataset items in one call:

curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~personio-jobs-scraper/run-sync-get-dataset-items?token=<TOKEN>" \
-H "Content-Type: application/json" \
-d '{"companies":["ottonova"],"maxJobs":25,"withDetails":true}'

Start a run asynchronously:

curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~personio-jobs-scraper/runs?token=<TOKEN>" \
-H "Content-Type: application/json" \
-d '{"companies":["optiply","everphone"],"searchQuery":"engineer","maxJobs":100}'

Apify CLI:

apify call scrapers_lat/personio-jobs-scraper \
--input '{"companies":["clark"],"remoteOnly":true}'

Fetch results

Every run writes to a dataset. Fetch items as JSON, CSV, or Excel by changing format:

# JSON
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=json"
# CSV
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=csv"
# Paginate large datasets
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&offset=1000&limit=1000"

<DATASET_ID> is returned as defaultDatasetId in the run object. Use offset and limit to page through large result sets. clean=true drops empty and internal fields.

Billing and limits

  • Pay per result. You are charged per job returned (result event). See the pricing tab for the current per-result price.
  • Contact enrichment add-on. When enrichContacts is on, each attempted row is billed once (contact-search-attempt) plus an extra charge only when an email is found (contact-email-found). Off by default.
  • No charge on failure. If a company errors, the actor writes an item with a populated error field and does not charge for it. Empty runs cost nothing.
  • Spend cap respected. Set maxTotalChargeUsd on the run; once reached, the actor stops emitting and charging further billable results.
  • Free Apify plans are capped at 10 jobs per run, and the enrichment add-on at 3 rows. Upgrade for higher maxJobs.

FAQ and troubleshooting

A run returned 0 records. Why? The company subdomain was wrong, the company has no open roles, or your filters matched nothing. Confirm the subdomain from the *.jobs.personio.com URL and loosen the filters. Zero-result runs are not charged.

Where do I find the company subdomain? Open the company's Personio career page. The subdomain is the first label of the host, for example ottonova in ottonova.jobs.personio.com. Paste that, the host, or the full URL into companies.

Can I scrape several companies at once? Yes. Add one entry per company to the companies array. maxJobs caps the total across all companies.

How do I get only the listing fields, faster? Turn withDetails off. The actor then skips each job's detail fetch and returns the lightweight fields only.

Why is descriptionHtml missing? You ran with withDetails off. Turn it on to include the full description and structured sections.

Is this an official Personio tool? No. This actor is independent and has no affiliation with Personio. It reads only data that is publicly available on company career pages.

More scrapers at scrapers.lat

Built and maintained by scrapers.lat, where we publish scrapers for US and Latin American public platforms: company registries, government data, finance, e-commerce and more. Browse the catalog or request a custom scraper at scrapers.lat.


Independent tool, not affiliated with Personio. Accesses only publicly available company career page data.