Adderley Data Apify Store

Adderley Data / Guides

Personio job board API: the XML feed, its two hosts and the language it answers in

A company's Personio job page, {company}.jobs.personio.de, publishes every open position as one XML document at /xml. Personio documents it for companies that list their jobs on their own website ("Integration via code" on developer.personio.de), and its help centre says the feed needs no credentials and changes as soon as a job is edited in Personio (both read 26 October 2026). This page covers the feed as we measured it.

The request

curl "https://acme.jobs.personio.de/xml?language=en"

The answer is text/xml: a <workzag-jobs> root with one <position> per published job, its text included, in a single response. There is no paging. Checked against the live feed on 26 October 2026:

  • Two hosts, one feed. The same board answers on {company}.jobs.personio.com; Personio's own board returned the same bytes on both.
  • Send the language. language picks the text. Without it, both boards we read answered exactly as they did with language=de. A code Personio does not have, xx, answered 200 with the same positions and no text, not an error. A position with no text in the language asked for keeps its other fields and has an empty <jobDescriptions>.
  • A name with no board answered HTTP 404 with an HTML "Page Not Found" page on both hosts. On 25 September 2026 the same request was redirected to personio.com instead, so test for both.

The company name is the part before .jobs.personio.de in any of its job links. {company}.personio.de, without jobs, is the company's own Personio sign-in, not its job page.

What a position holds

The children of <position>, in the order the feed writes them: id, subcompany, office, additionalOffices, department, recruitingCategory, name, jobDescriptions, employmentType, seniority, schedule, yearsOfExperience, keywords, occupation, occupationCategory and createdAt, with salaryInformation where the company has set it. A company can leave several of them out.

  • id is a number, and the job's public page is /job/{id} on the board's host. name is the title.
  • subcompany names the legal entity advertising the job. office is the company's own label for the first place, a city or something like "Head Office - Dublin" or "Mobil" (German for mobile working), with any others under additionalOffices.
  • jobDescriptions holds one <jobDescription> per section of the text: <name> is the heading and <value> its HTML, in a CDATA block.
  • employmentType is a code (permanent, intern, freelance, working_student and temporary on the boards we have read) and schedule is full-time, part-time or full-or-part-time.
  • createdAt is ISO 8601 with an offset, such as 2026-06-10T15:41:00+00:00.
  • salaryInformation carries a minimum, a currency code and a period. It is rare: none of the 27 positions measured below has it, and 2 of the 104 we read across twelve boards on 25 September 2026 did, each with a minimum only.

Three things the feed never says: whether a job is remote (only the office label hints at it), when a position was last edited, and when it closes. And one thing to leave alone: some companies add a section to the text that names the recruiter, with an email address and a phone number, under a heading such as "Contact". We found such sections on boards read on 25 September; neither board measured below has one.

Measured on two boards

Personio's own job page listed 1 position on Monday 26 October 2026, and the board in the Actor's example input listed 27. Reading both took 2 requests, one feed each, both answered at the first attempt, in 2 seconds, and gave 28 rows (run oJKJf1TI1tDKnlGov). The 27-position feed was 113,249 bytes in English.

One public Personio board, 27 positions, 26 October 2026
FactPositions with itNotes
Text in English19 of 27The other 8 have text in German only; asked in German, 15 of the 27 have none
Legal entity26 of 27From subcompany
Office27 of 27"Mobil" on 24, Berlin on 2 and one other city; 6 positions list further offices
Department19 of 27Five departments
Employment type27 of 27Permanent 25, intern 2; full-time 25, full or part time 2
Pay0 of 27No salaryInformation on any position
Created date27 of 274 created in October 2026 and 8 in September; the oldest still open dates from April 2025

A board name with nothing behind it, read in the same way, came back as a 404 and was reported as not found while the other board was read (run ZjzEwPZs0y7MOifDT).

Where it stops

The feed is cheap: a whole board, text and all, in one request. What it does not give you is change. Nothing in it records an edit, so watching a board means keeping the last read, comparing, and deciding what counts as new, changed or gone. Then the language: a reader that does not send it gets German text, or none, and a job written in one language is empty in the other. Remote work has to be read from free-text office labels, and pay is almost never there.

Personio Jobs Scraper reads one feed per board in the language you choose, and filters by title words, office, department and posting date. In incremental mode it compares each position with the last run, its text included, because the text arrives in the same response: an edit to any word of it is reported as a change at no extra request, and an unchanged position is skipped and not charged. It never reads a section that names a contact person, its description text is opt-in with contact details redacted, and a missing board is named in the run's summary while the others are read. Its page has the price and every field. To read Personio with fourteen other systems in one run, see the measured run of the Career Site Jobs Scraper.

The same reference for other systems

Published 2026-10-26.