0

Create a Time-Off

by
Published Oct 17, 2025

Adds absence data for absence types with **time unit** set to **days**.

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 Time-Off
8
 * Adds absence data for absence types with **time unit** set to **days**.
9
 */
10
export async function main(
11
	auth: Personio,
12
	body: {
13
		employee_id: number
14
		time_off_type_id: number
15
		start_date: string
16
		end_date: string
17
		half_day_start: false | true
18
		half_day_end: false | true
19
		comment?: string
20
		skip_approval?: false | true
21
	},
22
	X_Personio_Partner_ID?: string,
23
	X_Personio_App_ID?: string
24
) {
25
	const url = new URL(`https://api.personio.de/v1/company/time-offs`)
26

27
	const response = await fetch(url, {
28
		method: 'POST',
29
		headers: {
30
			...(X_Personio_Partner_ID ? { 'X-Personio-Partner-ID': X_Personio_Partner_ID } : {}),
31
			...(X_Personio_App_ID ? { 'X-Personio-App-ID': X_Personio_App_ID } : {}),
32
			'Content-Type': 'application/x-www-form-urlencoded',
33
			Authorization: 'Bearer ' + (await getOAuthToken(auth, 'https://api.personio.de/oauth2/token'))
34
		},
35
		body: new URLSearchParams(
36
			Object.entries(body).reduce((acc, [key, value]) => {
37
				acc[key] = String(value)
38
				return acc
39
			}, {} as Record<string, string>)
40
		)
41
	})
42
	if (!response.ok) {
43
		const text = await response.text()
44
		throw new Error(`${response.status} ${text}`)
45
	}
46
	return await response.json()
47
}
48

49
async function getOAuthToken(auth: Personio, tokenUrl: string): Promise<string> {
50
	const params = new URLSearchParams({
51
		grant_type: 'client_credentials',
52
		client_id: auth.clientId,
53
		client_secret: auth.clientSecret
54
	})
55

56
	const response = await fetch(tokenUrl, {
57
		method: 'POST',
58
		headers: {
59
			Authorization: 'Basic ' + btoa(`${auth.clientId}:${auth.clientSecret}`),
60
			'Content-Type': 'application/x-www-form-urlencoded'
61
		},
62
		body: params.toString()
63
	})
64

65
	if (!response.ok) {
66
		const text = await response.text()
67
		throw new Error(`OAuth token request failed: ${response.status} ${text}`)
68
	}
69

70
	const data = await response.json()
71
	return data.access_token
72
}
73