Create an automation
This API method creates an automation of the type in the path. Requires `automations:write`. The acting user is the key owner, or the `X-On-Behalf-Of` user, and becomes the automation's owner (`ownerId`). It waits for the automation to be created and returns it with `201`; if that takes longer than the wait window it returns `202 Accepted` with an operation to poll. - Send `name` plus the fields of the type. `CreateAutomationRequest` lists one request schema per type (for example `CreateBlackoutPeriodAutomationRequest` for `blackout-period`). Fields of another type, `id`, `type`, `isActive`, `ownerId` and other unknown fields fail validation. - The automation is created active (`isActive: true`); pause it with `PATCH /v2/automations/{type}/{id}` and `isActive: false`. - `locationIds`, `departmentIds` and `labelIds` limit the users the automation applies to; omitted or empty means everyone. `entitlement-by-role` does not accept them: it applies to the users with the label in `labelId`. - `name`, `reason` and `autoRejectResponse` fail validation when they look like HTML or script. - The acting user must be an approver or an admin; `seniority-entitlement` and `entitlement-by-role` automations can be created only by admins. - The company must have the automation's add-on active; otherwise the request fails with `403 AUTOMATION_ADDON_NOT_ACTIVE`. When the request returns `202`, the same error is reported on the operation. Errors: `400 VALIDATION_ERROR` (`details.fields`), `400 INVALID_REQUEST_BODY`, `403 ON_BEHALF_OF_NOT_ALLOWED`, `403 FORBIDDEN` and `403 AUTOMATION_ADMIN_REQUIRED` (the acting user may not create this automation), `403 AUTOMATION_ADDON_NOT_ACTIVE`, `404 AUTOMATION_TYPE_NOT_FOUND` (`type` is not one of the automation types), `409 DUPLICATE_NAME` (another automation already uses the name), and the `Idempotency-Key` codes.
Authorization
bearerAuth automations:writeAPI key sent as Authorization: Bearer vt_live_<secret>. See the Authentication and Scopes sections at the top of this document for how keys are created, which scopes exist and how the key owner's role limits them.
In: header
Scope: automations:write
Path Parameters
automation type. Any other value returns 404 AUTOMATION_TYPE_NOT_FOUND.
"blackout-period" | "seniority-entitlement" | "entitlement-by-role" | "maximum-users-away" | "probation-period" | "leave-duration-limit" | "leave-request-notice-period"Header Parameters
optional key (1 to 255 printable ASCII characters) that makes a write request safe to retry. Keys are retained for 24 hours per API key. Retrying with the same key and the same request within those 24 hours replays the original response (with the Idempotent-Replayed header). Reusing the key with a different request returns 422 IDEMPOTENCY_KEY_REUSED; retrying while the first request is still running returns 409 IDEMPOTENCY_REQUEST_IN_PROGRESS; an invalid key returns 400 INVALID_IDEMPOTENCY_KEY.
1 <= length <= 255ID of the user the write is performed for. Requires the users:act-on-behalf scope, and the key owner must manage the target user; otherwise the request fails with 403 ON_BEHALF_OF_NOT_ALLOWED. Ignored on GET requests.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v2/automations/blackout-period" \ -H "Content-Type: application/json" \ -d '{ "name": "End of year freeze", "leaveTypeIds": [ "leaveType-fcc1e5c5-ba93-479d-bd58-8f860ba10615" ], "startDate": "2026-12-20", "endDate": "2026-12-31", "recurring": true, "reason": "Year-end closing", "locationIds": [ "location-79c77ac8-e5bf-479f-9488-648a58379ff1" ] }'{
"data": {
"id": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"type": "blackout-period",
"name": "End of year freeze",
"isActive": true,
"ownerId": "user-63b17e97-d38b-4586-8498-bb4f5d2e2c14",
"createdAt": "2026-09-23T10:00:00.000Z",
"locationIds": [
"location-79c77ac8-e5bf-479f-9488-648a58379ff1"
],
"departmentIds": [],
"labelIds": [],
"leaveTypeIds": [
"leaveType-fcc1e5c5-ba93-479d-bd58-8f860ba10615"
],
"startDate": "2026-12-20",
"endDate": "2026-12-31",
"recurring": true,
"reason": "Year-end closing"
}
}{
"operation": {
"id": "pa_3f1c2b9e-8a47-4d5e-9c61-2b7f0e4a1d93",
"status": "PENDING",
"url": "/v2/operations/pa_3f1c2b9e-8a47-4d5e-9c61-2b7f0e4a1d93"
}
}{
"error": {
"code": "VALIDATION_ERROR",
"name": "ValidationError",
"description": "A query parameter, body field or header failed validation.",
"resolution": "Fix the fields listed in details.fields and send the request again.",
"requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
"details": {
"fields": [
{
"path": "startDate",
"message": "\"startDate\" is required"
}
]
}
}
}{
"error": {
"code": "UNAUTHORIZED",
"name": "Unauthorized",
"description": "The API key is missing, malformed or not recognized.",
"resolution": "Send a valid API key in the Authorization header as Bearer followed by the full vt_live_ key.",
"requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef"
}
}{
"error": {
"code": "INSUFFICIENT_SCOPE",
"name": "InsufficientScope",
"description": "The API key does not have the scopes this request needs.",
"resolution": "Add the scopes listed in details.requiredScopes to the key in the Vacation Tracker dashboard.",
"requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
"details": {
"requiredScopes": [
"leaves:write"
]
}
}
}{
"error": {
"code": "AUTOMATION_TYPE_NOT_FOUND",
"name": "Automation type not found",
"description": "The automation type was not found.",
"resolution": "Use one of the automation types listed in the API reference.",
"requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef"
}
}{
"error": {
"code": "CONFLICT",
"name": "Conflict",
"description": "The request conflicts with the current state of the resource.",
"resolution": "Read the resource again and retry with up-to-date values.",
"requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef"
}
}{
"error": {
"code": "LEAVE_NEGATIVE_BALANCE",
"name": "LeaveNegativeBalance",
"description": "The user does not have enough balance for this leave.",
"resolution": "Shorten the leave, use a different leave type, or ask an admin to adjust the quota.",
"requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef"
}
}{
"error": {
"code": "RATE_LIMITED",
"name": "RateLimited",
"description": "Too many requests were sent in a short time.",
"resolution": "Wait a few seconds and retry, using the same Idempotency-Key for writes.",
"requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef"
}
}{
"error": {
"code": "INTERNAL_ERROR",
"name": "InternalError",
"description": "Something went wrong on our side.",
"resolution": "Retry later, and if it keeps happening, contact Vacation Tracker support and quote the requestId.",
"requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef"
}
}Need help?
developers@vacationtracker.ioList automations of a type
This API method returns every automation of the type in the path, active and paused, in one response without pagination. Requires `automations:read`. Automations are company-wide: they are not limited by the key's data reach. Each automation has the fields of its type; `Automation` lists one schema per type (for example `BlackoutPeriodAutomation` for `blackout-period`). `locationIds`, `departmentIds` and `labelIds` are always arrays, and an empty array means the automation applies to everyone; `entitlement-by-role` automations have no filters. Errors: `404 AUTOMATION_TYPE_NOT_FOUND` (`type` is not one of the automation types).
Get an automation
This API method returns a single automation, with the fields of its type. Requires `automations:read`. Errors: `404 AUTOMATION_TYPE_NOT_FOUND` (`type` is not one of the automation types) and `404 RESOURCE_NOT_FOUND` (no automation of the type in the path has this ID, including when the ID belongs to an automation of another type).