Skip to content

Day Off Types

MC0RE edited this page Aug 18, 2026 · 3 revisions

Day Off Types

Manage day off type definitions in Teamleader Focus.

Overview

The Day Off Types resource lets you create, update, delete, and list the leave categories used in your account β€” vacation, sick leave, parental leave, and so on. Each type has a name, an optional color, and an optional date validity window.

Access via Teamleader::dayOffTypes().

dayOffTypes.list takes no request body. The specification declares no filter, page or sort parameter. Passing arguments throws since v2.2.0; before that they were silently discarded.

list() returns only id and name. The colour and validity window you set on create are not returned β€” see Response Structure. This is a real asymmetry in the API, not an SDK limitation.

There is no info() endpoint. The API exposes only list, create, update and delete.

Endpoint

dayOffTypes

Capabilities

Capability Supported
Pagination ❌ Not supported
Filtering ❌ Not supported
Sorting ❌ Not supported
Sideloading ❌ Not supported
Creation βœ… Supported
Update βœ… Supported
Deletion βœ… Supported

Methods

list()

Returns all day off types. Takes no arguments.

use McoreServices\TeamleaderSDK\Facades\Teamleader;

$types = Teamleader::dayOffTypes()->list();

Any argument throws before the request is sent:

Teamleader::dayOffTypes()->list([], ['page_size' => 10]);
// InvalidArgumentException: dayOffTypes.list does not support pagination.
// Passed: page_size. The endpoint returns every record in a single response,
// so there are no pages to request.

info()

Not available. dayOffTypes.info does not exist in the API, and this class does not define an info() method β€” calling it raises Error: Call to undefined method.

Earlier versions of this page stated that info() "falls through to the base class behaviour". There is no info() on the base Resource class either, so that was never true. Resolve a single type from list() instead.


create(array $data)

Creates a new day off type. name is the only required field. color and date_validity are optional but validated if provided.

Required:

Field Type Description
name string Display name of the leave type β€” max 255 characters

Optional:

Field Type Description
color string Hex color code β€” must match #RRGGBB format
date_validity array Validity window β€” see below
date_validity.from string Start date in YYYY-MM-DD format
date_validity.until string End date in YYYY-MM-DD format β€” must be after from
// Name only
$type = Teamleader::dayOffTypes()->create([
    'name' => 'Sick Leave',
]);

// With color
$type = Teamleader::dayOffTypes()->create([
    'name'  => 'Vacation',
    'color' => '#00B2B2',
]);

// With validity window
$type = Teamleader::dayOffTypes()->create([
    'name'          => 'Summer Leave',
    'color'         => '#FFB600',
    'date_validity' => [
        'from'  => '2025-06-01',
        'until' => '2025-08-31',
    ],
]);

update(mixed $id, array $data)

Updates a day off type. The id is injected into the request body before posting. Any field can be updated β€” all are optional.

Teamleader::dayOffTypes()->update('type-uuid', [
    'name'  => 'Annual Leave',
    'color' => '#0055FF',
]);

// Update validity only
Teamleader::dayOffTypes()->update('type-uuid', [
    'date_validity' => [
        'from'  => '2025-07-01',
        'until' => '2025-09-30',
    ],
]);

Clearing the validity window. date_validity is declared nullable on update, so passing null removes it:

Teamleader::dayOffTypes()->update('type-uuid', ['date_validity' => null]);

This only works from v2.2.0. Before that, validateData() stripped null along with empty strings and empty arrays, so the clear never reached the API β€” no error, the validity window simply stayed as it was. The same defect was fixed for Contacts and Companies in v1.2.6 and had gone unnoticed here.


delete(mixed $id)

Deletes a day off type by UUID.

Teamleader::dayOffTypes()->delete('type-uuid');

Helper Methods

createWithValidity(string $name, ?string $color, ?string $fromDate, ?string $untilDate)

Convenience wrapper for creating a type with a validity window in a single call.

$type = Teamleader::dayOffTypes()->createWithValidity(
    'Summer Friday',
    '#FFA500',
    '2025-06-01',
    '2025-08-31'
);

updateValidity(string $id, string $fromDate, ?string $untilDate = null)

Updates only the validity window of an existing type.

Teamleader::dayOffTypes()->updateValidity('type-uuid', '2025-07-01', '2025-09-30');

updateColor(string $id, string $color)

Updates only the colour.

Teamleader::dayOffTypes()->updateColor('type-uuid', '#BB8FCE');

bulkCreate(array $dayOffTypes)

Creates multiple types in a loop. Failures are caught per-entry and returned as error objects β€” they do not throw.

$results = Teamleader::dayOffTypes()->bulkCreate([
    ['name' => 'Vacation',   'color' => '#00B2B2'],
    ['name' => 'Sick Leave', 'color' => '#FF6B6B'],
    ['name' => 'Personal',   'color' => '#FFB600'],
]);

// Each entry: ['index' => 0, 'success' => true, 'data' => [...]]
// or:         ['index' => 1, 'success' => false, 'error' => '...', 'data' => [...]]

One API request per entry, so a bulk create of twenty types costs twenty requests against your rate limit budget.

getCommonColors()

Returns a curated map of hex codes to colour names β€” no API call. Useful for building UI colour pickers.

$colors = Teamleader::dayOffTypes()->getCommonColors();
// ['#00B2B2' => 'Teal', '#FF6B6B' => 'Red', ...]

getValidationRules()

Returns Laravel validation rules matching the SDK's own checks β€” no API call. Useful for validating a form before you get as far as calling the SDK.

$rules = Teamleader::dayOffTypes()->getValidationRules();

$validated = $request->validate($rules);
Teamleader::dayOffTypes()->create($validated);

Validation

create() and update() run validateData() before the request:

  • name is required on create, and max 255 characters
  • color must match /^#[0-9A-Fa-f]{6}$/ if provided
  • date_validity.from must match YYYY-MM-DD if provided
  • date_validity.until must match YYYY-MM-DD if provided, and must be after from
  • Empty strings and empty arrays are stripped before sending
  • null is preserved, so it reaches the API as a field clear

An InvalidArgumentException is thrown for any violation.


Response Structure

list() response

[
    'data' => [
        ['id' => 'type-uuid', 'name' => 'Vacation'],
        ['id' => 'type-uuid', 'name' => 'Sick Leave'],
    ],
    'headers' => ['X-RateLimit-Remaining' => ['199'], /* ... */],
]

Only id and name are returned. Earlier versions of this page showed color and date_validity in the list response; the specification declares each item as {id, name} and nothing more. You can write both fields, but you cannot read them back through the API β€” the Teamleader web interface is the only place to see them.

If you need colours in your own UI, store them alongside the type id on your side, or use getCommonColors() as a fixed palette.

create() / update() response

[
    'data'    => ['type' => 'dayOffType', 'id' => 'type-uuid'],
    'headers' => [/* ... */],
]

Usage Examples

Build a leave type select list

$types = Teamleader::dayOffTypes()->list();

$options = array_column($types['data'], 'name', 'id');
// ['uuid-1' => 'Vacation', 'uuid-2' => 'Sick Leave', ...]

Initialise standard leave types for a new account

Teamleader::dayOffTypes()->bulkCreate([
    ['name' => 'Annual Leave',   'color' => '#00B2B2'],
    ['name' => 'Sick Leave',     'color' => '#FF6B6B'],
    ['name' => 'Personal Day',   'color' => '#FFB600'],
    ['name' => 'Parental Leave', 'color' => '#BB8FCE'],
    ['name' => 'Unpaid Leave',   'color' => '#808080'],
]);

Cache leave types

$types = Cache::remember('tl_day_off_types', 3600, fn () =>
    Teamleader::dayOffTypes()->list()['data']
);

Retire a seasonal type

// Close the window rather than deleting, so historic leave keeps its type
Teamleader::dayOffTypes()->updateValidity('type-uuid', '2025-06-01', '2025-08-31');

// Or remove the window entirely, making it always valid again
Teamleader::dayOffTypes()->update('type-uuid', ['date_validity' => null]);

Error Handling

use InvalidArgumentException;
use McoreServices\TeamleaderSDK\Exceptions\TeamleaderException;

// Arguments the endpoint cannot honour
try {
    Teamleader::dayOffTypes()->list([], ['page_size' => 10]);
} catch (InvalidArgumentException $e) {
    // 'dayOffTypes.list does not support pagination. ...'
}

// Invalid color format β€” thrown before the request
try {
    Teamleader::dayOffTypes()->create([
        'name'  => 'Test',
        'color' => 'red', // must be #RRGGBB
    ]);
} catch (InvalidArgumentException $e) {
    // 'Color must be a valid hex color code (e.g., #00B2B2)'
}

// Missing name β€” thrown before the request
try {
    Teamleader::dayOffTypes()->create(['color' => '#00B2B2']);
} catch (InvalidArgumentException $e) {
    // 'Name is required for creating a day off type'
}

// until before from
try {
    Teamleader::dayOffTypes()->create([
        'name'          => 'Test',
        'date_validity' => ['from' => '2025-08-01', 'until' => '2025-06-01'],
    ]);
} catch (InvalidArgumentException $e) {
    // 'Date validity "until" must be after "from" date'
}

// API-level errors
try {
    Teamleader::dayOffTypes()->delete('type-uuid');
} catch (TeamleaderException $e) {
    Log::error('Teamleader error', ['message' => $e->getMessage()]);
}

Related Resources

  • Days Off β€” Applies these types when importing user leave
  • Users β€” listDaysOff() returns leave records that reference these types
  • Closing Days β€” Company-wide closures (not per-user leave)
  • Units of Measure β€” Another endpoint that takes no arguments and returns everything
  • Payment Terms β€” Same shape
  • Webhooks β€” Same shape

Clone this wiki locally