# Time offs

## Overview

The Time Off API allows you to programmatically manage employee time off periods in Swarmia, enabling you to sync time off data from external systems like HR platforms or leave management systems. The API provides full CRUD operations for managing time off periods.

## Authentication

Authentication works based on a token which you can generate [here](https://app.swarmia.com/settings/api-tokens).

Two options are currently available:

1. Include an HTTP header like `Authorization: Bearer {TOKEN}` in the request. Example request with the curl command line tool: `curl https://app.swarmia.com/api/v0/time-offs -H "Authorization: Bearer {TOKEN}"`
2. Pass the token as a value for the `token` query parameter. Example request: `GET https://app.swarmia.com/api/v0/time-offs/{id}?token={TOKEN}`

   > **Security note:** Even though Swarmia redacts secret tokens from query logs, please bear in mind that some other proxies might log query parameters before reaching Swarmia.

### Create a time off period

`POST /api/v0/time-offs`

Creates a new time off period for a team member.

#### Example query

```bash
curl -H "Content-Type: application/json" \
-H "Authorization: Bearer TOKEN" \
-X POST https://app.swarmia.com/api/v0/time-offs \
-d '{
  "email": "developer@example.com",
  "startDate": "2024-12-20",
  "endDate": "2024-12-27",
  "externalId": "HR-VACATION-12345"
}'
```

#### Parameters

**Body parameters**

**email** `string` *required*

Email address of the team member. Must match an existing author in your organization.

**startDate** `string` *required*

Start date of the time off period in `yyyy-MM-dd` format.

**endDate** `string` *required*

End date of the time off period in `yyyy-MM-dd` format. Must be on or after the start date.

**externalId** `string` *optional*

Identifier for the time off period used in your external system. This allows you to reference and update the period using your own ID system.

* Maximum 128 characters
* Cannot contain whitespace, slashes (`/`, `\`), or quotes (`'`, `"`)
* Must be unique within your organization
* Cannot be changed after creation

#### Response

**Response codes**

| Code | Description                                                                            |
| ---- | -------------------------------------------------------------------------------------- |
| 201  | Created                                                                                |
| 400  | Validation error (invalid email format, date format, date range, or externalId format) |
| 404  | Email not found in organization                                                        |
| 409  | Duplicate time off period or externalId already exists                                 |

**Example response**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "email": "developer@example.com",
  "startDate": "2024-12-20",
  "endDate": "2024-12-27",
  "externalId": "HR-VACATION-12345",
  "createdAt": "2024-12-01T10:00:00.000Z",
  "updatedAt": "2024-12-01T10:00:00.000Z"
}
```

### Get a time off period

`GET /api/v0/time-offs/{id}`

Retrieves a specific time off period by its Swarmia UUID or your external ID.

#### Example queries

**By Swarmia id:**

```bash
curl -H "Authorization: Bearer TOKEN" \
https://app.swarmia.com/api/v0/time-offs/550e8400-e29b-41d4-a716-446655440000
```

**By external id:**

```bash
curl -H "Authorization: Bearer TOKEN" \
https://app.swarmia.com/api/v0/time-offs/HR-VACATION-12345
```

#### Parameters

**Path parameters**

**id** `string` *required*

Either the Swarmia id or your externalId for the time off period.

#### Response

**Response codes**

| Code | Description               |
| ---- | ------------------------- |
| 200  | Ok                        |
| 404  | Time off period not found |

**Example response**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "externalId": "HR-VACATION-12345",
  "email": "developer@example.com",
  "startDate": "2024-12-20",
  "endDate": "2024-12-27",
  "createdAt": "2024-12-01T10:00:00.000Z",
  "updatedAt": "2024-12-01T10:00:00.000Z"
}
```

### Update a time off period

`PUT /api/v0/time-offs/{id}`

Updates an existing time off period. You can update the dates and the associated email. The externalId cannot be changed after creation.

{% hint style="info" %}
When dates are updated, FTE calculations are automatically recalculated for both the old and new date ranges to ensure accuracy.
{% endhint %}

#### Example query

```bash
curl -H "Content-Type: application/json" \
-H "Authorization: Bearer TOKEN" \
-X PUT https://app.swarmia.com/api/v0/time-offs/HR-VACATION-12345 \
-d '{
  "email": "developer@example.com",
  "startDate": "2024-12-20",
  "endDate": "2024-12-28"
}'
```

#### Parameters

**Path parameters**

**id** `string` *required*

Either the Swarmia UUID or your externalId for the time off period.

**Body parameters**

**email** `string` *required*

Email address of the team member. Must match an existing author in your organization.

**startDate** `string` *required*

Start date of the time off period in `yyyy-MM-dd` format.

**endDate** `string` *required*

End date of the time off period in `yyyy-MM-dd` format. Must be on or after the start date.

> **Note:** The `externalId` field is immutable and cannot be changed through the update endpoint.

#### Response

**Response codes**

| Code | Description                                                         |
| ---- | ------------------------------------------------------------------- |
| 200  | Ok                                                                  |
| 400  | Validation error (invalid email format, date format, or date range) |
| 404  | Time off period not found or email not found in organization        |
| 409  | Updated period conflicts with existing time off period              |

**Example response**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "externalId": "HR-VACATION-12345",
  "email": "developer@example.com",
  "startDate": "2024-12-20",
  "endDate": "2024-12-28",
  "createdAt": "2024-12-01T10:00:00.000Z",
  "updatedAt": "2024-12-02T14:30:00.000Z"
}
```

### Delete a time off period

`DELETE /api/v0/time-offs/{id}`

Permanently deletes a time off period. FTE calculations are automatically recalculated for the affected time range.

{% hint style="warning" %}
This is a permanent operation and cannot be undone.
{% endhint %}

#### Example query

```bash
curl -H "Authorization: Bearer TOKEN" \
-X DELETE https://app.swarmia.com/api/v0/time-offs/HR-VACATION-12345
```

#### Parameters

**Path parameters**

**id** `string` *required*

Either the Swarmia id or your externalId for the time off period.

#### Response

**Response codes**

| Code | Description                       |
| ---- | --------------------------------- |
| 204  | No Content - Successfully deleted |
| 404  | Time off period not found         |

**Example response**

No response body is returned on successful deletion (204 status code).

### Using External IDs

The Time Off API supports a dual-identifier system to make integration with external systems easier:

1. **Swarmia UUID** (`id`): Automatically generated by Swarmia when a time off period is created
2. **External ID** (`externalId`): Optional identifier from your HR or leave management system

#### Benefits of using External IDs

* **Simplified integration**: Use your existing HR system's identifiers instead of storing Swarmia ids
* **Idempotent operations**: Prevent duplicate entries by using consistent external IDs
* **System independence**: If you migrate HR systems, you can maintain the same external IDs

#### External ID requirements

* Maximum 128 characters
* Cannot contain whitespace, slashes (`/`, `\`), or quotes (`'`, `"`)
* Must be unique within your organization
* Cannot be changed after creation
* Can be used interchangeably with Swarmia id in `GET`, `PUT`, and `DELETE` operations

#### Example workflow with External IDs

```bash
# 1. Create with external ID
curl -X POST https://app.swarmia.com/api/v0/time-offs \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "developer@example.com",
    "startDate": "2024-12-20",
    "endDate": "2024-12-27",
    "externalId": "HR-LEAVE-2024-001"
  }'

# 2. Update using external ID (no need to store Swarmia UUID)
curl -X PUT https://app.swarmia.com/api/v0/time-offs/HR-LEAVE-2024-001 \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "developer@example.com",
    "startDate": "2024-12-20",
    "endDate": "2024-12-28"
  }'

# 3. Delete using external ID
curl -X DELETE https://app.swarmia.com/api/v0/time-offs/HR-LEAVE-2024-001 \
  -H "Authorization: Bearer TOKEN"
```

### Common validation errors

#### Invalid email format

```json
{
  "message": "Invalid email format"
}
```

#### Invalid date format

```json
{
  "message": "Invalid start date format. Expected yyyy-MM-dd"
}
```

#### Invalid date range

```json
{
  "message": "Start date must be before or equal to end date"
}
```

#### Email not found

```json
{
  "message": "Email not found"
}
```

The specified email address doesn't match any team member in your organization.

#### External ID already exists

```json
{
  "message": "External ID already exists"
}
```

Another time off period in your organization is already using this `externalId`.

#### Time off period already exists

```json
{
  "message": "Time off period already exists"
}
```

A time off period for this team member with these exact dates already exists.

#### Invalid External ID format

```json
{
  "message": "External ID cannot contain whitespace, slashes, or quotes"
}
```

### Best practices

#### Use External IDs for easier integration

If you're integrating with an HR system, always provide `externalId` to:

* Avoid storing and managing Swarmia ids in your system
* Prevent duplicate entries when syncing
* Simplify updates and deletions

#### Handle date changes carefully

When updating dates, keep in mind:

* FTE calculations are automatically recalculated for affected time ranges
* Large date changes may affect multiple months of FTE data
* Consider the impact on reporting and metrics

#### Error handling

Always check response status codes and handle errors appropriately:

* `400` errors indicate validation issues - check your input data
* `404` errors mean the resource wasn't found - verify IDs are correct
* `409` errors indicate conflicts - check for duplicates
* `500` errors are server issues - implement retry logic


---

# 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://help.swarmia.com/settings/integrations/swarmia-apis/time-off-api.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.
