# Personio

## Overview

The Veza integration for Personio discovers employees, organizational groups, and reporting relationships from Personio HRIS. Veza creates graph entities for employees, departments, teams, and cost centers, with edges representing group memberships, manager relationships, and IdP identity mappings.

The integration enables:

* Employee data synchronization from Personio for identity governance workflows.
* Visibility into organizational structure (departments, teams, cost centers, offices).
* Mapping Personio employees to external IdP identities for query enrichment and access reviews.
* Automated tracking of reporting relationships, employment status, and termination events.

See [Notes and supported entities](#notes-and-supported-entities) for details on discovered data.

## Prerequisites

Before configuring the integration:

* **Personio administrator access** with permissions to create custom API credentials.
* **Personio API client ID and secret** (see [Configuring Personio](#configuring-personio) below).
* **Network connectivity**: Connection from Veza to Personio's API (`api.personio.de`) via the default data plane or a deployed [Insight Point](/4yItIzMvkpAvMVFAamTf/integrations/connectivity/insight-point.md).

## Configuring Personio

### Creating API credentials

Veza authenticates to Personio using **OAuth 2.0 client credentials**. The credentials are issued from the Personio admin UI and grant access to the employee data endpoints.

For detailed instructions on creating custom API integrations in Personio, see the [official Personio API documentation](https://developer.personio.de/docs/getting-started-with-the-personio-api).

1. In Personio, go to **Settings** > **Integrations** > **API credentials**.
2. Click **Generate new credentials**.
3. Enter a descriptive name (for example, `Veza`).
4. Under **Readable employee attributes**, select at minimum the following attributes:
   * `first_name`, `last_name`, `preferred_name`, `email`
   * `status`, `position`, `employment_type`
   * `hire_date`, `termination_date`, `contract_end_date`, `probation_period_end`
   * `termination_type`, `termination_reason`
   * `created_at`, `last_modified_at`, `profile_picture`
   * `department`, `team`, `office`, `subcompany`, `cost_centers`, `supervisor`
   * Any custom (`dynamic_*`) attributes you want surfaced on Veza employees.
5. Click **Generate**. Personio displays a **Client ID** and **Client Secret**.

{% hint style="info" %}
The **Client Secret** is shown only once. Copy it to a secure location before closing the dialog — it cannot be retrieved later.
{% endhint %}

## Configuring Personio on the Veza platform

1. In Veza, go to the **Integrations** page.
2. Click **Add Integration** and search for **Personio**.
3. Click **Next** to begin configuration.
4. Enter the required information (see table below).
5. Click **Create Integration** to save and start the first extraction.

### Configuration options

| Field             | Required | Notes                                                                                                                                                        |
| ----------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Insight Point** | Yes      | Choose the default data plane or a deployed Insight Point.                                                                                                   |
| **Name**          | Yes      | Friendly name to identify this integration.                                                                                                                  |
| **Client ID**     | Yes      | Personio API client ID from the credentials dialog.                                                                                                          |
| **Client Secret** | Yes      | Personio API client secret — stored encrypted.                                                                                                               |
| **IdP Types**     | No       | Comma-separated list of IdP types for identity mapping. Supported values: `okta`, `azure_ad`, `active_directory`, `google_workspace`, `one_login`, `custom`. |

### Advanced options

<details>

<summary>Custom properties</summary>

Personio surfaces the `dynamic_*` custom attributes configured on your Personio tenant as Veza custom properties (named `customprop_dynamic_<id>`). Empty values are skipped to keep the graph clean — only attributes with non-empty values appear on employees.

To extend the schema with additional provider-agnostic custom properties:

1. On **Edit Integration** > **Custom Properties**, click **Add Custom Property**.
2. Enter the property name and select the data type (String, Number, Boolean, RFC3339 Timestamp, or String List).
3. Save the configuration.

Custom properties appear on entities after the next extraction and can be used in queries, rules, and access reviews.

</details>

## Notes and supported entities

Personio is surfaced as an HRIS integration. Veza ingests the employee directory along with organizational groupings (departments, teams, cost centers) and reporting relationships. Employees are linked to external IdP accounts (for example Okta, Azure AD) when **IdP Types** is configured, enabling cross-integration access queries and access reviews.

### Discovered entities

* **HRIS System** (`OAA.Personio.HRISSystem`): A single node representing the Personio tenant.
* **HRIS Employees** (`OAA.Personio.HRISEmployee`): One node per employee, including active, inactive (terminated), onboarding, and on-leave statuses. Carries all core attributes, supervisor edges, and custom properties.
* **HRIS Groups** (`OAA.Personio.HRISGroup`): Departments, teams, and cost centers. Each group has a `group_type` attribute of `Department`, `Team`, or `Cost Center`. Employees are linked to every group they belong to.

### Key attributes

#### Employee

| Veza attribute                                                    | Personio attribute                                                                                                       | Notes                                                               |
| ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------- |
| `id` / `employee_number`                                          | `id`                                                                                                                     | Personio numeric employee ID, stringified.                          |
| `name`                                                            | `first_name` + `last_name`                                                                                               | Trimmed.                                                            |
| `first_name`, `last_name`, `preferred_name`                       | `first_name`, `last_name`, `preferred_name`                                                                              |                                                                     |
| `email`                                                           | `email`                                                                                                                  | Primary work email.                                                 |
| `is_active`                                                       | `status`                                                                                                                 | `true` when status is `active`, `onboarding`, or `leave`.           |
| `employment_status`                                               | `status`                                                                                                                 | Raw Personio status string.                                         |
| `job_title`                                                       | `position`                                                                                                               |                                                                     |
| `start_date`                                                      | `hire_date`                                                                                                              |                                                                     |
| `termination_date`                                                | `termination_date`                                                                                                       |                                                                     |
| `company`                                                         | `subcompany.attributes.name`                                                                                             | Legal entity name.                                                  |
| `department`                                                      | `department.attributes.id` (set as group ref), `department.attributes.name` (as custom property `customprop_department`) |                                                                     |
| `cost_center`                                                     | First entry of `cost_centers[]`; remaining entries surfaced as `customprop_cost_centers` string list.                    |                                                                     |
| `managers`                                                        | `supervisor.attributes.id`                                                                                               | Resolved in a second pass so manager nodes are guaranteed to exist. |
| `customprop_gender`                                               | `gender`                                                                                                                 | Employee gender.                                                    |
| `customprop_office`                                               | `office.attributes.name`                                                                                                 |                                                                     |
| `customprop_team`                                                 | `team.attributes.name`                                                                                                   | Team name.                                                          |
| `customprop_employment_type`                                      | `employment_type`                                                                                                        |                                                                     |
| `customprop_created_at`, `customprop_last_modified_at`            | `created_at`, `last_modified_at`                                                                                         | Date-only (YYYY-MM-DD).                                             |
| `customprop_contract_end_date`, `customprop_probation_period_end` | `contract_end_date`, `probation_period_end`                                                                              | Date-only.                                                          |
| `customprop_termination_type`, `customprop_termination_reason`    | `termination_type`, `termination_reason`                                                                                 |                                                                     |
| `customprop_profile_picture`                                      | `profile_picture`                                                                                                        | URL.                                                                |
| `customprop_dynamic_<id>`                                         | `dynamic_<id>`                                                                                                           | Non-empty values only.                                              |

#### Group (Department / Team / Cost Center)

| Veza attribute | Personio source                                                                     | Notes                                            |
| -------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------ |
| `id`           | `department.attributes.id`, `team.attributes.id`, or `cost_centers[].attributes.id` |                                                  |
| `name`         | `*.attributes.name`                                                                 |                                                  |
| `group_type`   | —                                                                                   | Derived: `Department`, `Team`, or `Cost Center`. |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.veza.com/4yItIzMvkpAvMVFAamTf/integrations/integrations/personio.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
