Job boards & ATS · Live on Apify

Personio jobs scraper and vacancy change monitor

Add the Personio board of a company you know. The tool reads its public XML feed. You get job rows, or only the jobs that are new, changed or removed.

About $0.47 for 1,000 jobs$0.00045 per job + $0.018 per run. Apify bills you, not us.One job in a run of its own: about $0.02.Free to try: the Apify free plan gives you $5 of usage every month, no credit card needed.

Run it on Apify Opens apify.com, the website where our tools run. Sign up free with Google or email, no card needed.

Apify links on this page are affiliate links. We may earn a commission. You pay the same price. Affiliate disclosure

What you get, for example

_typejob
_schemaVersion1.0
_sourcepersonio

How to use it: 3 steps

  1. Make a free Apify accountApify is the cloud platform where our tools run. The free plan gives you $5 of usage every month, no credit card needed. You pay Apify, not us.
  2. Paste your input and press StartNo code needed: you fill in a form (the input). It already has a working example. For example: teamative in Personio board names or URLs. Each start is one run.
  3. Download the resultsWhen the run ends, the results are in a table (the dataset). Open Output, press Export and pick Excel or CSV. JSON and the API are there too.

This tool is an Apify Actor: a small program that runs on Apify. You can also run it on a schedule, for example every Monday. New to it? Read how it works, step by step and the 8 words you need first.

What it does

Watch known Personio boards for new, changed and removed jobs. This Personio jobs scraper reads public XML feeds and saves job rows or change events. It keeps the last complete board state when a check fails, so a failed check does not report every old job as removed.

Who uses it

HR tech and job boards

Keep a current list of vacancies from Personio companies.

B2B sales teams

Watch European companies for new roles as a buying signal.

Analysts

Compare locations and published pay across several boards.

Price

Pay per event: you pay for each result the tool saves, plus a small start fee for each run. The price includes Apify platform costs. Apify bills you, not us. Prices below are for the Apify free plan.

What you pay forPriceWhen
Complete board check$0.018One complete successful Personio board check, including a valid empty feed.
Saved current job$0.00045One unique saved baseline, new, changed or requested unchanged job from a complete board. Removed/failed/truncated results have no event fee. Platform usage may be charged separately as shown in Pricing.

Examples

  • One job: about $0.02.
  • 1,000 jobs: about $0.47.
  • Every day 100 jobs, for 30 days: about $1.89 a month.

Free to try: the Apify free plan gives you $5 of usage every month, no credit card needed. That is enough for about 10,000 jobs.

Prices checked on 24 October 2026. See the current price on Apify.

Questions

Do I need a Personio account?

No. The tool reads known public XML boards only. It reads no applicant data.

Can I use a job link or custom domain?

No. Use the board name or the Personio board or XML URL.

Why does my first change run show every job?

There is no saved state yet. That first run becomes the baseline.

What happens when a check fails?

The tool keeps the last complete state. Old jobs are not marked as removed.

Does removed mean the company filled the job?

No. It means the ID disappeared from a complete accepted feed. The employer may have hidden, moved or removed the listing for another reason.

Why is the first delta a baseline?

There is no prior complete board snapshot under this key and language. Later delta runs compare with the saved state. Changing the key starts a new comparison.

Does snapshot mode affect my monitor?

Yes. A complete snapshot updates the selected state record. Use a separate key for an export that should not move your delta baseline.

Is createdAt the job's last change date?

No. It is the source creation value. updatedAt remains null. changed events compare content; they do not supply an employer update timestamp.

Are all fields always filled?

No. Null means the mapped value is absent or not safe to use. Empty arrays mean no values were supplied. Optional event timestamps can be absent. A job row with null source fields is different from a failed board fetch.

Are repeated runs free if no jobs change?

No free-run promise is made. Source checks and state work still use platform resources. Check the Pricing tab and run usage.

Details

Step by step on Apify
  1. Open the Actor you have access to in Apify Console, then open Input.
  2. Switch to JSON input and paste the minimal example below. Use a tenant from the company public Personio careers board, such as teamative. A job title or search word such as mediabuyer is not a verified tenant.
  3. Keep language as en and choose snapshot for this first check.
  4. Click Start. Wait for the run to finish.
  5. Open Output or the run's default Dataset. Check tenant, jobId, title and eventType.
  6. Open the default Key-value store and read RUN_SUMMARY. Check each board's status and complete.
Use cases
Buyer taskInputKey fieldsNext step
Keep a current vacancy listsnapshot on known boardstenant, jobId, title, publicUrlExport JSON or CSV; replace your current list only from complete boards.
Track added or edited jobsdelta with a stable stateKeyeventType, changedFields, contentHashUpsert by tenant + jobId in your database.
Mark a job as no longer listeddelta with complete sourceremovedAt, previousObservedAt, jobIdArchive the saved role; keep its last-known content.
Check locations and published payeither modeallLocations, salaryInformationFilter these values in your own worksheet or application.
Tips for better results
  • A plain board name points to jobs.personio.de. Use a full URL for .com boards.
  • Pick the job text language with the language setting, for example en or de.
  • Use a separate state key for one-off exports. Your monitor baseline stays safe.
Limits and good to know

Input safety caps are 50 boards, 5000 positions per board and 10 MiB per response. Real Cloud checks covered up to 22 current jobs across 3 boards at 256 MB. A local synthetic test accepted 5000 positions on one board. The local test is not a Cloud capacity or throughput guarantee. Start small and inspect the results for your source.

Troubleshooting

SymptomLikely reasonCheckSafe next action
Input error before requestsBad board shape, duplicate board, reserved state key or unknown fieldInput and top-level errorClassUse the exact fields and valid board root URL.
Failed run with redirect_blockedThe tenant redirects away from its XML feedRUN_SUMMARY and the company careers boardUse the actual public company tenant. Redirects stay blocked. Previous state is kept.
Empty delta DatasetNo changes, a valid empty board, or failed checksterminalOutcome, status, domainStatus, completeFor no changes do nothing; for failure fix the input/source and retry.
descriptionText is nullEmployer has no text in the requested languagedescriptionSections and public sourceTry the employer's language with a separate monitor key if desired.
Posted time is null but createdAt is filledNo explicit timezone or invalid source dateOriginal createdAt stringKeep the source value; do not invent a timezone.
Truncated statusFeed exceeds maxJobsPerBoardcap and jobCountRaise the cap within its range; previous complete state stays intact.
body_cap / timeoutResponse is too large or slowmaxBodyBytes, boardTimeoutMs and attemptLogRaise the relevant bound within the input range, then test one board.
not_found / access_block / schema_driftWrong board, denied access or changed XMLsourceUrl and safe errorMessageCheck the public board; report a reproducible source change. Do not treat it as all jobs removed.

For developers

Sample result

One result from a real test run, in JSON. Real values change from run to run. In Excel or CSV each field is a column.

one result · JSON
{
  "_type": "job",
  "_schemaVersion": "1.0",
  "_source": "personio",
  "tenant": "teamative",
  "jobId": "2681315",
  "title": "Junior SAP Funkčný Konsultant – SAP CE / SAP IS-U",
  "publicUrl": "https://teamative.jobs.personio.de/job/2681315",
  "applyUrl": null,
  "subcompany": "teamative Slovakia s.r.o.",
  "office": "SK - Bratislava",
  "additionalOffices": [
    "SK - Košice"
  ],
  "department": "Delivery",
  "recruitingCategory": "SK - application process IT/SAP",
  "employmentType": "permanent",
  "seniority": "entry-level",
  "schedule": "full-time",
  "yearsOfExperience": "1-2",
  "keywords": [
    "SAP IS-U,SAP CE,ISU,CE,Junior"
  ],
  "occupation": "enterprise_software_implementation_consulting",
  "occupationCategory": "it_software",
  "createdAt": "2026-06-22T11:07:27+00:00",
  "descriptionSections": [],
  "descriptionText": null,
  "salaryInformation": {
    "minimum": 2000,
    "maximum": null,
    "currency": "EUR",
    "period": "monthly"
  },
  "company": "teamative",
  "url": "https://teamative.jobs.personio.de/job/2681315",
  "location": "SK - Bratislava",
  "allLocations": [
    "SK - Bratislava",
    "SK - Košice"
  ],
  "postedAt": "2026-06-22T11:07:27.000Z",
  "commitment": "Full-time",
  "team": null,
  "country": null,
  "workplaceType": null,
  "updatedAt": null,
  "observedAt": "2026-10-01T11:43:33.910Z",
  "contentHash": "6b6d47abef37ae0392319d40644adbbefd20f280ac210875376111463339dbfe",
  "_scrapedAt": "2026-10-01T11:43:33.910Z",
  "eventType": "baseline",
  "changedFields": []
}

Use it from code

Actor ID: cliqtomedia/personio-jobs-monitor-scraper. You need your Apify API token from Apify Console → Settings → API & Integrations.

Python · apify-client
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("cliqtomedia/personio-jobs-monitor-scraper").call(run_input={
    "boards": [
        "teamative"
    ],
    "language": "en"
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
cURL
curl -X POST "https://api.apify.com/v2/acts/cliqtomedia~personio-jobs-monitor-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"boards": ["teamative"], "language": "en"}'
LangChain · langchain-apify
# pip install langchain-apify
# set APIFY_TOKEN in your environment
from langchain_apify import ApifyActorsTool

tool = ApifyActorsTool("cliqtomedia/personio-jobs-monitor-scraper")
result = tool.invoke({"run_input": {"boards": ["teamative"], "language": "en"}})
print(result)

The cURL call waits for the results, up to 300 seconds. For longer runs, start a run (/runs) and get the results with a webhook or by checking the run. Apify API docs. LlamaIndex, MCP for AI agents and the JavaScript client: AI agents & MCP.

Data fields (40)
FieldTypeMeaning
_typestringStable record type marker.
_schemaVersionstringJob record schema version.
_sourcestringUpstream source marker.
tenantstringCanonical Personio tenant slug.
jobIdstringStable upstream job identifier.
titlestringPublic job title.
publicUrlstringCanonical public job URL.
applyUrlstringPublic application URL when supplied.
subcompanystringPublic subcompany value when supplied.
officestringPrimary public office value when supplied.
additionalOfficesarrayAdditional public office values.
departmentstringPublic department value when supplied.
recruitingCategorystringPublic recruiting category when supplied.
employmentTypestringPublic employment type when supplied.
senioritystringPublic seniority value when supplied.
schedulestringPublic schedule value when supplied.
yearsOfExperiencestringPublic experience requirement when supplied.
keywordsarrayNormalized public keyword values.
occupationstringPublic occupation value when supplied.
occupationCategorystringPublic occupation category when supplied.
createdAtstringPublic upstream creation timestamp when supplied.
descriptionSectionsarrayStructured public description sections.
descriptionTextstringNormalized public description text when supplied.
salaryInformationobjectPublic salary information when supplied.
eventTypestringDelta event classification.
observedAtstringUTC observation timestamp.
changedFieldsarrayJob fields that changed for a changed event.
contentHashstringDeterministic content hash used for comparisons.
previousObservedAtstringPrevious observation timestamp for a changed event.
removedAtstringRemoval observation timestamp for a removed event.
companystringCanonical tenant alias for existing consumers.
urlstringValidated public job URL alias.
locationstringPrimary source office alias.
allLocationsarrayUnique source offices, primary first; null when absent.
postedAtstringUTC source creation timestamp when timezone is explicit; null otherwise.
commitmentstringSource schedule with initial uppercase, compatible with the leader.
_scrapedAtstringUTC timestamp of this extraction, excluded from content hash.
teamnullNot exposed as a dedicated source field; never inferred.
countrynullNot exposed as a dedicated source field; never inferred.
workplaceTypenullNot exposed as a dedicated source field; never inferred.
Input settings (9)

The main fields of the input form. With the API you send them as JSON.

SettingName in the APITypeExample value
Personio board names or URLs requiredboardsarray["teamative"]
Job text languagelanguagestring"en"
Snapshot or changesmodestring"snapshot"
Jobs allowed per boardmaxJobsPerBoardinteger100
XML size limit (bytes)maxBodyBytesinteger10485760
Time limit per board (ms)boardTimeoutMsinteger30000
Request attempts per boardmaxAttemptsinteger3
Monitor state keystateKeystring"PERSONIO_UI_DEMO_TEAMATIVE_EN"
Show unchanged jobsincludeUnchangedbooleanfalse

Use cases with this tool

Each guide shows all the steps and the other tools.

Start on Apify

Make a free Apify account: you get $5 of free usage every month. Missing a tool? Suggest it. We read every idea, but we do not promise to build it.

Apify links on this page are affiliate links. We may earn a commission. You pay the same price. Affiliate disclosure