REST API v2
Errors
Error envelope and the full catalog of error codes returned by the API.
Every error response, including authentication and rate limit errors, uses the same envelope:
{ "error": { "code": "...", "name": "...", "description": "...", "resolution": "...", "requestId": "...", "details": {} } }codeis stable and meant for programmatic handling. Branch oncode, not onnameordescription.nameanddescriptionexplain what went wrong.resolutiontells the caller, a human or an AI agent, what to do next.requestIdidentifies the request; include it when you contact support.detailsis optional and carries extra context, such as the fields that failed validation.
400
| Code | Name | Description | Resolution |
|---|---|---|---|
BAD_REQUEST | BadRequest | The request is malformed and was rejected. | Check the method, headers and body of the request against the API reference. |
INVALID_IDEMPOTENCY_KEY | InvalidIdempotencyKey | The Idempotency-Key header is not 1 to 255 printable ASCII characters. | Send an Idempotency-Key of 1 to 255 printable ASCII characters, such as a UUID. |
INVALID_PAGINATION_TOKEN | InvalidPaginationToken | The nextToken was not issued by this API. | Send the nextToken exactly as the previous response returned it, or omit it to start from the first page. |
INVALID_REQUEST_BODY | InvalidRequestBody | The request body is not valid JSON. | Send a valid JSON object with the Content-Type header set to application/json. |
NOTIFICATION_FREQUENCY_CHANGE_NOT_ALLOWED | NotificationFrequencyChangeNotAllowed | A notification cannot be changed to or from the BIRTHDAY frequency. | Delete the notification and create a new one with the frequency you need. |
PRORATE_NOT_ALLOWED | ProrateNotAllowed | Prorating is allowed only for the first quota period of the user. | Remove prorate from the request, or send it only for the first quota period of the user. |
QUOTA_PERIOD_NOT_AVAILABLE | QuotaPeriodNotAvailable | The user has no next quota period for this leave type. | Send period=current instead of period=next. |
ROLE_SCOPE_MISMATCH | RoleScopeMismatch | The scope of the role assignment does not match the scope type of the role. | Send a scope of the type the role expects, or choose a role whose scope type matches the scope you send. |
VALIDATION_ERROR | ValidationError | A query parameter, body field or header failed validation. | Fix the fields listed in details.fields and send the request again. |
WEBHOOK_EVENTS_INVALID | WebhookEventsInvalid | The events list is empty or contains unknown event names. | Send at least one event name from the list of webhook events in the API reference. |
WEBHOOK_URL_INVALID | WebhookUrlInvalid | The webhook URL is not a valid public HTTPS URL. | Send an absolute HTTPS URL that points to a publicly reachable host. |
401
| Code | Name | Description | Resolution |
|---|---|---|---|
API_KEY_EXPIRED | ApiKeyExpired | The API key has expired. | Ask a Vacation Tracker admin to create a new key or rotate this one. |
API_KEY_INVALID | ApiKeyInvalid | The API key is not recognized. | Check that you copied the full key, or create a new key in the Vacation Tracker dashboard. |
API_KEY_MISSING | ApiKeyMissing | The request does not include an API key. | Send your API key in the Authorization header as "Bearer vt_live_...". |
API_KEY_REVOKED | ApiKeyRevoked | The API key has been revoked. | See details.reason for why it was revoked, then ask a Vacation Tracker admin to create a new key. |
UNAUTHORIZED | Unauthorized | The API key is missing, malformed or not recognized. | Send a valid API key in the Authorization header as Bearer followed by the full vt_live_ key. |
403
| Code | Name | Description | Resolution |
|---|---|---|---|
ACCESS_DENIED | AccessDenied | The request was rejected before it reached the API. | Check the API key and the request, and contact Vacation Tracker support with the requestId if it keeps happening. |
API_ADDON_INACTIVE | ApiAddonInactive | The API add-on is not active for this company. | Ask a Vacation Tracker admin to enable the API add-on in the billing settings. |
AUTOMATION_ADDON_NOT_ACTIVE | AutomationAddonNotActive | The add-on for this automation is not active for this company. | Ask a Vacation Tracker admin to buy the add-on in Settings, Add-ons, or contact Vacation Tracker support. |
AUTOMATION_ADMIN_REQUIRED | AutomationAdminRequired | This automation action is allowed only for admins, or for the user who created the automation. | Use an API key owned by an admin, or change only automations the key owner created. |
FEATURE_NOT_IN_PLAN | FeatureNotInPlan | The company subscription plan does not include this feature. | Remove the setting from the request, or ask a Vacation Tracker admin to upgrade the plan. |
FORBIDDEN | Forbidden | The key owner is not allowed to perform this action. | See details.reason, and ask a Vacation Tracker admin for the required permissions. |
INSUFFICIENT_SCOPE | InsufficientScope | The API key does not have the scopes this request needs. | Add the scopes listed in details.requiredScopes to the key in the Vacation Tracker dashboard. |
KEY_EXPIRED | KeyExpired | The API key has passed its expiry date. | Ask a Vacation Tracker admin to create a new key. |
KEY_OWNER_INACTIVE | KeyOwnerInactive | The user who owns the API key has been deactivated or deleted. | Ask a Vacation Tracker admin to create a new key owned by an active user. |
KEY_REVOKED | KeyRevoked | The API key has been revoked. | See details.revocationReason for why it was revoked, then ask a Vacation Tracker admin to create a new key. |
KEY_SCOPES_EXCEED_ROLE | KeyScopesExceedRole | The role of the key owner no longer allows the scopes of this API key. | Ask a Vacation Tracker admin to create a new key with scopes the owner role allows. |
ON_BEHALF_OF_NOT_ALLOWED | OnBehalfOfNotAllowed | The API key cannot act on behalf of the user in the X-On-Behalf-Of header. | Add the users:act-on-behalf scope to the key and make sure the key owner manages that user, or remove the X-On-Behalf-Of header. |
PLAN_NOT_SUPPORTED | PlanNotSupported | The company subscription plan does not include API access. | Ask a Vacation Tracker admin to upgrade to a paid plan. |
PUBLIC_API_NOT_ENABLED | PublicApiNotEnabled | The company does not have the Open API add-on or is on the Freemium plan. | Ask a Vacation Tracker admin to upgrade to a paid plan and enable the Open API add-on. |
SCHEDULED_REPORTS_NOT_AVAILABLE | ScheduledReportsNotAvailable | Scheduled reports are not included in the company subscription plan. | Ask a Vacation Tracker admin to upgrade to the Complete plan. |
SUBSCRIPTION_EXPIRED | SubscriptionExpired | The company subscription has expired. | Ask a Vacation Tracker admin to renew the subscription. |
SUBSCRIPTION_INACTIVE | SubscriptionInactive | The company subscription has expired or was canceled. | Ask a Vacation Tracker admin to renew the subscription. |
WEBHOOK_EVENTS_NOT_ALLOWED | WebhookEventsNotAllowed | The webhook owner or the API key is not allowed to receive some of the requested events. | Subscribe only to events that the owner role and the API key scopes allow, or ask a Vacation Tracker admin for more permissions. |
WORK_HOURS_LIMIT_REACHED | WorkHoursLimitReached | The work hours in the request exceed what the company subscription plan allows. | Use the default work hours, or ask a Vacation Tracker admin to upgrade the plan. |
404
| Code | Name | Description | Resolution |
|---|---|---|---|
AUTOMATION_TYPE_NOT_FOUND | AutomationTypeNotFound | The automation type in the path is not recognized. | Use one of the automation types listed in the API reference. |
OPERATION_NOT_FOUND | OperationNotFound | The operation does not exist or has expired. | Check the operation ID; operations are kept for 90 days. |
RESOURCE_NOT_FOUND | ResourceNotFound | The requested resource does not exist or is outside the data this key can access. | Check the ID of the resource named in details.resource and that the key owner can see it. |
ROLE_NOT_FOUND | RoleNotFound | The role does not exist in this company. | Check the role ID and send a role that exists in the company. |
ROUTE_NOT_FOUND | RouteNotFound | No endpoint matches this method and path. | Check the method and path against the API reference. |
WEBHOOK_DELIVERY_NOT_FOUND | WebhookDeliveryNotFound | The webhook delivery does not exist or has expired. | Check the delivery ID; deliveries are kept for 30 days. |
WEBHOOK_NOT_FOUND | WebhookNotFound | The webhook does not exist or is not visible to the key owner. | Check the webhook ID, and list the webhooks to see the ones the key owner can manage. |
409
| Code | Name | Description | Resolution |
|---|---|---|---|
AUTOMATION_OVERRIDE_REQUIRED | AutomationOverrideRequired | The leave breaks one or more automation rules, listed in details.warnings. | Repeat the request with overrideAutomations listing every code in details.warnings, or change the dates. |
CONFLICT | Conflict | The request conflicts with the current state of the resource. | Read the resource again and retry with up-to-date values. |
DEFAULT_DEPARTMENT_DELETE_FORBIDDEN | DefaultDepartmentDeleteForbidden | The default department cannot be deleted. | Make another department the default first, then delete this one. |
DEFAULT_DEPARTMENT_UNSET_FORBIDDEN | DefaultDepartmentUnsetForbidden | The company must always have a default department. | Make another department the default first instead of unsetting this one. |
DEFAULT_LOCATION_DELETE_FORBIDDEN | DefaultLocationDeleteForbidden | The default location cannot be deleted. | Make another location the default first, then delete this one. |
DEFAULT_LOCATION_UNSET_FORBIDDEN | DefaultLocationUnsetForbidden | The company must always have a default location. | Make another location the default first instead of unsetting this one. |
DEPARTMENT_CIRCULAR_PARENT | DepartmentCircularParent | A department cannot have one of its own subdepartments as its parent. | Choose a parent department that is not below this department. |
DEPARTMENT_HAS_SUBDEPARTMENTS | DepartmentHasSubdepartments | A department with subdepartments cannot be deleted. | Delete or move its subdepartments first, then delete the department. |
DUPLICATE_NAME | DuplicateName | Another item of the same kind already uses this name. | Choose a different name, or update the existing item instead of creating a new one. |
EMAIL_ALREADY_EXISTS | EmailAlreadyExists | Another user in the company already has this email address. | Use a different email address, or update the existing user instead of creating a new one. |
HOLIDAY_DATES_OVERLAP | HolidayDatesOverlap | The holiday dates overlap another holiday in the same location. | Choose dates that do not overlap an existing holiday, or change the other holiday first. |
HOLIDAY_UPDATE_NOT_POSSIBLE | HolidayUpdateNotPossible | The holiday cannot be updated in its current state. | Read the holiday again, or delete it and create a new one. |
IDEMPOTENCY_REQUEST_IN_PROGRESS | IdempotencyRequestInProgress | A request with this Idempotency-Key is still being processed. | Wait a few seconds and retry with the same Idempotency-Key. |
LAST_ADMIN_CANNOT_BE_REMOVED | LastAdminCannotBeRemoved | The user is the only admin in the company, so the admin role cannot be removed. | Make another user an admin first, then remove the admin role from this user. |
USER_SEAT_LIMIT_REACHED | UserSeatLimitReached | The company has no free user seats left in its subscription. | Deactivate another user, or ask a Vacation Tracker admin to add seats to the subscription, then retry. |
WEBHOOK_REVOKED | WebhookRevoked | The webhook has been revoked and can no longer be changed or used. | See revocationReason on the webhook for why it was revoked, then create a new webhook. |
422
| Code | Name | Description | Resolution |
|---|---|---|---|
HOLIDAY_INVALID_DATES | HolidayInvalidDates | The holiday dates are not valid. | Send a start and end in the same year, with the start not after the end, and a start year from 2020 to next year. |
IDEMPOTENCY_KEY_REUSED | IdempotencyKeyReused | This Idempotency-Key was already used with a different request payload. | Use a new Idempotency-Key for a different request, or resend the original payload. |
LEAVE_BLACKOUT_PERIOD | LeaveBlackoutPeriod | The leave falls within a blackout period. | Choose dates outside the blackout period, or ask an admin to change it. |
LEAVE_DURATION_LIMIT | LeaveDurationLimit | The leave is longer than this leave type allows. | Shorten the leave or split it into several requests. |
LEAVE_INVALID_DATE_RANGE | LeaveInvalidDateRange | The leave end date is before its start date. | Send an end date that is the same as or after the start date. |
LEAVE_INVALID_DURATION | LeaveInvalidDuration | The leave duration is not allowed for this leave type. | Check whether the leave type allows half days or hourly leaves, and adjust the request. |
LEAVE_INVALID_HALF_DAY_DURATION | LeaveInvalidHalfDayDuration | The leave type is booked in half days, and the requested times are not exactly half of the user's working hours on that day. | Set the end time to the start time plus half of the user's working hours on that day, or plus 4 hours on a day without working hours. The end can be 24:00. |
LEAVE_MAXIMUM_USERS_AWAY | LeaveMaximumUsersAway | Too many users are already away on these dates. | Choose other dates, or ask an admin to change the maximum users away setting. |
LEAVE_NEGATIVE_BALANCE | LeaveNegativeBalance | The user does not have enough balance for this leave. | Shorten the leave, use a different leave type, or ask an admin to adjust the quota. |
LEAVE_NOTICE_PERIOD | LeaveNoticePeriod | The leave does not respect the required notice period. | Choose a later start date that meets the notice period. |
LEAVE_NO_WORKING_DAYS | LeaveNoWorkingDays | The selected dates contain no working days. | Choose dates that include at least one working day for the user. |
LEAVE_OVERLAP | LeaveOverlap | The leave overlaps with another leave of the same user. | Choose dates that do not overlap an existing leave, or cancel the other leave first. |
LEAVE_POLICY_MISSING | LeavePolicyMissing | The leave type is not enabled for the user location. | Use a leave type enabled for the user location, or ask an admin to enable it there. |
LEAVE_PROBATION_PERIOD | LeaveProbationPeriod | The user is still in a probation period for this leave type. | Choose dates after the probation period ends, or use a different leave type. |
LEAVE_REASON_REQUIRED | LeaveReasonRequired | This leave type requires a reason. | Add a reason to the request. |
LEAVE_REQUEST_NOT_EDITABLE | LeaveRequestNotEditable | The leave can no longer be changed. | Read the leave to see its current status, or cancel it and create a new one. |
LEAVE_REQUEST_NOT_OPEN | LeaveRequestNotOpen | The leave request is no longer open for approval or denial. | Read the leave to see its current status before taking another action. |
LEAVE_START_DATE_IN_PAST | LeaveStartDateInPast | The leave starts in the past, which this leave type does not allow. | Choose a start date that is today or later. |
LEAVE_TYPE_INACTIVE | LeaveTypeInactive | The leave type is not active. | Use an active leave type, or ask an admin to activate this one. |
PLAN_LIMIT_REACHED | PlanLimitReached | The company has reached a limit of its subscription plan. | Ask a Vacation Tracker admin to upgrade the plan or remove unused items. |
REQUEST_REJECTED | RequestRejected | The request was rejected by a business rule. | See details.message for the reason, adjust the request, and try again. |
TOIL_INVALID_REQUEST | ToilInvalidRequest | The dates, hours or duration of the time off in lieu request are not valid. | Check that the end is after the start and that the duration matches what the leave type allows, then send the request again. |
TOIL_NOT_ALLOWED | ToilNotAllowed | Time off in lieu is not enabled for this user or leave type. | Ask an admin to enable time off in lieu for the leave type in the user location. |
TOIL_OVERLAP | ToilOverlap | The time off in lieu request overlaps with another request of the same user. | Choose dates that do not overlap an existing request, or cancel the other request first. |
TOIL_REASON_REQUIRED | ToilReasonRequired | This leave type requires a reason for time off in lieu requests. | Add a reason to the request. |
TOIL_REQUEST_NOT_OPEN | ToilRequestNotOpen | The time off in lieu request is no longer open for this action. | Read the request to see its current status before taking another action. |
UNKNOWN_USER_IDS | UnknownUserIds | Some user IDs in userIds or approvers do not belong to active users of the company. | Remove the unknown user IDs from userIds and approvers and send the request again. |
USER_NOT_EMPLOYED_ON_DATES | UserNotEmployedOnDates | The user is not employed on some of the selected dates. | Choose dates between the user employment start and end dates. |
429
| Code | Name | Description | Resolution |
|---|---|---|---|
QUOTA_EXCEEDED | QuotaExceeded | The request quota for this API key has been used up. | Wait until the quota resets, or contact Vacation Tracker support for a higher quota. |
RATE_LIMITED | RateLimited | Too many requests were sent in a short time. | Wait a few seconds and retry, using the same Idempotency-Key for writes. |
500
| Code | Name | Description | Resolution |
|---|---|---|---|
INTERNAL_ERROR | InternalError | Something went wrong on our side. | Retry later, and if it keeps happening, contact Vacation Tracker support and quote the requestId. |