0

Create a new Person and Employment.

by
Published Oct 17, 2025

- This endpoint enables the creation of a Person resource and an associated Employment resource. - The endpoint requires the personio:persons:write scope.

Script personio Verified

The script

Submitted by hugo697 Bun
Verified 235 days ago
1
//native
2
type Personio = {
3
  clientId: string;
4
  clientSecret: string;
5
};
6
/**
7
 * Create a new Person and Employment.
8
 * - This endpoint enables the creation of a Person resource and an associated Employment resource.
9
- The endpoint requires the personio:persons:write scope.
10

11
 */
12
export async function main(
13
  auth: Personio,
14
  body: {
15
    email?: string;
16
    first_name?: string;
17
    preferred_name?: string;
18
    last_name?: string;
19
    gender?: "MALE" | "FEMALE" | "DIVERSE" | "UNKNOWN" | "UNDEFINED";
20
    language_code?: "en" | "de" | "es" | "fr" | "nl" | "it" | "sv" | "fi";
21
    custom_attributes?: { id?: string; value?: string | string[] }[];
22
  } & {
23
    employments?: {
24
      supervisor?: { id: string };
25
      office?: { id: string };
26
      org_units?: { type: string; id: string }[];
27
      subcompany?: { id: string };
28
      legal_entity?: { id: string };
29
      position?: { title: string };
30
      status?: "ACTIVE" | "INACTIVE" | "ONBOARDING" | "LEAVE";
31
      employment_start_date?: string;
32
      type?: "INTERNAL" | "EXTERNAL";
33
      contract_end_date?: string;
34
      probation_end_date?: string;
35
      probation_period_length?: number;
36
      weekly_working_hours?: number;
37
      full_time_weekly_working_hours?: number;
38
      cost_centers?: { id: string; weight: number }[];
39
    }[];
40
  } & {},
41
) {
42
  const url = new URL(`https://api.personio.de/v2/persons`);
43

44
  const response = await fetch(url, {
45
    method: "POST",
46
    headers: {
47
      "Content-Type": "application/json",
48
      Authorization: "Bearer " + await getOAuthToken(auth, "https://api.personio.de/oauth2/token"),
49
    },
50
    body: JSON.stringify(body),
51
  });
52
  if (!response.ok) {
53
    const text = await response.text();
54
    throw new Error(`${response.status} ${text}`);
55
  }
56
  return await response.json();
57
}
58

59
async function getOAuthToken(auth: Personio, tokenUrl: string): Promise<string> {
60
  const params = new URLSearchParams({
61
    grant_type: 'client_credentials',
62
    client_id: auth.clientId,
63
    client_secret: auth.clientSecret,
64
  });
65
  
66
  const response = await fetch(tokenUrl, {
67
    method: 'POST',
68
    headers: {
69
      'Authorization': 'Basic ' + btoa(`${auth.clientId}:${auth.clientSecret}`),
70
      'Content-Type': 'application/x-www-form-urlencoded',
71
    },
72
    body: params.toString(),
73
  });
74

75
  if (!response.ok) {
76
    const text = await response.text();
77
    throw new Error(`OAuth token request failed: ${response.status} ${text}`);
78
  }
79

80
  const data = await response.json();
81
  return data.access_token;
82
}
83