3.6 KiB
3.6 KiB
Data Schemas
Snapshot Structure
{
"last_refreshed": "2026-03-04T19:00:00Z",
"total_records": 755,
"summary": {
"ACTIVE": 177,
"INACTIVE": 574,
"ONBOARDING": 1,
"LEAVE": 3
},
"employees": [
{
"personio_id": "35653993",
"status": "ONBOARDING",
"team_id": "417186",
"department_id": "1291054",
"office_id": "501083",
"start_date": "2026-05-01",
"end_date": null
}
]
}
Team Mapping Structure
Maps Personio team IDs to human-readable names:
{
"total_teams": 65,
"teams": [
{
"team_id": "4400959",
"team_name": "AI & Automation",
"active_headcount": 6,
"total_records": 7
}
]
}
Department Mapping Structure
Groups teams under departments with real names from department-mapping.csv:
{
"total_departments": 19,
"departments": [
{
"department_id": "1291054",
"department_name": "Finance & Business Navigation",
"active_headcount": 11,
"total_records": 45,
"team_ids": ["417186", "417184", "3442693", "3443053", "572110"],
"teams": ["Data", "Finance & Administration", "M&A", "Pricing", "Rev Ops"]
}
]
}
Office Mapping Structure
{
"total_offices": 8,
"offices": [
{
"office_id": "501083",
"active_headcount": 120,
"total_records": 500
}
]
}
MCP Tool Reference
Tool: Call_Personio_Get_Employees_ (full ID: mcp__n8n-personio__Call_Personio_Get_Employees_)
| Parameter | Type | Default | Description |
|---|---|---|---|
| limit | number | 50 | Records per page (use 50 for balance) |
| cursor | string | "" | Pagination cursor from previous page |
Pass parameters as a JSON string in the input field:
- First page:
{"limit": 50} - Subsequent pages:
{"limit": 50, "cursor": "<nextCursor>"}
Employee Record Fields (from API)
Each employee record from the MCP tool contains:
id→ store aspersonio_idstatus→ ACTIVE, INACTIVE, ONBOARDING, or LEAVEteam_id→ Personio team ID (look up name in team_mapping.json)department_id→ Personio department IDoffice_id→ Personio office IDstart_date→ employment startend_date→ contract end date (null if ongoing)first_name,last_name,email→ NEVER STORE THESE — strip before saving
Incremental Refresh (Delta Update)
- Read existing snapshot
- Fetch all pages from Personio (no "modified since" filter available)
- Compare each employee by
personio_id:- ID exists → update the record (status, team_id, etc. may have changed)
- ID is new → add it
- ID in snapshot but not in fresh data → keep (historical)
- Recalculate summary counts
- Update
last_refreshedtimestamp - Rebuild team_mapping.json counts
- Save all files
PDF Report Contents
The PDF report has 6 pages:
- Cover page — KPI cards (active, onboarding, on leave, inactive)
- Headcount by Team — all active teams ranked by headcount with percentages
- Headcount by Department — departments with team listings
- New Joiners — monthly breakdown since Jan 2025, with team attribution
- Departures — monthly breakdown since Jan 2025, with team attribution
- Net Workforce Movement — joiners vs leavers with cumulative net change
XML Escaping
The report uses xml_escape() for special characters in names (e.g., "M&A" → "M&A").
This is required because reportlab's Paragraph class uses an XML parser internally.