Vacation TrackerDeveloper Docs
REST API v2API referenceNotifications

Create a notification

This API method creates a notification. Requires notifications:write. The acting user is the key owner, or the X-On-Behalf-Of user; it must be an approver or an admin, and becomes the notification's owner (ownerId). It waits for the notification to be created and returns it with 201, or 202 Accepted with an operation to poll.

frequency selects the kind, and CreateNotificationRequest lists one request schema per frequency:

  • DAILY sends a summary of who is off on the days in sendOnDays; it needs groupBy and sendEmpty.
  • WEEKLY sends a summary of the current or the next week on day; it needs firstDayOfWeek, day, currentWeek, groupBy and sendEmpty.
  • BIRTHDAY announces birthdays; it needs sendOnNonWorkingDays, and each microsoft or slack destination needs a channelName.

Every kind needs name, timezone, hour, minute and at least one destination:

  • hour and minute are local to timezone; they are not converted to UTC.
  • locale defaults to en. locationIds, departmentIds and labelIds default to empty arrays, which means everyone.
  • enabled defaults to true. A DAILY or WEEKLY notification can only be created enabled; sending enabled: false fails validation.
  • An email destination takes one or more email addresses in addresses; a microsoft or slack destination takes exactly one channel ID. msGroup is accepted only for microsoft, and channelName is not accepted for email.
  • name fails validation when it looks like HTML or script. Fields of another frequency and unknown fields fail validation.

Errors: 400 VALIDATION_ERROR (details.fields), 400 INVALID_REQUEST_BODY, 403 ON_BEHALF_OF_NOT_ALLOWED, 403 FORBIDDEN (the acting user may not create notifications), and the Idempotency-Key codes.

POST
/v2/notifications

Authorization

bearerAuth notifications:write
AuthorizationBearer <token>

API 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: notifications:write

Header Parameters

Idempotency-Key?string

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.

Length1 <= length <= 255
X-On-Behalf-Of?string

ID 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

curl -X POST "https://example.com/v2/notifications" \  -H "Content-Type: application/json" \  -d '{    "name": "Daily team summary",    "frequency": "DAILY",    "timezone": "Europe/Belgrade",    "hour": 9,    "minute": 0,    "sendOnDays": [      1,      2,      3,      4,      5    ],    "groupBy": "TEAM",    "sendEmpty": false,    "destinations": [      {        "platform": "slack",        "addresses": [          "C04ABCDEF12"        ],        "channelName": "general"      }    ]  }'

{
  "data": {
    "id": "notification-2b7f0e4a-1d93-4c61-8a47-3f1c2b9e4d5e",
    "name": "Daily team summary",
    "frequency": "DAILY",
    "enabled": true,
    "ownerId": "user-63b17e97-d38b-4586-8498-bb4f5d2e2c14",
    "timezone": "Europe/Belgrade",
    "hour": 9,
    "minute": 0,
    "locale": "en",
    "locationIds": [],
    "departmentIds": [],
    "labelIds": [],
    "destinations": [
      {
        "platform": "slack",
        "addresses": [
          "C04ABCDEF12"
        ],
        "channelName": "general"
      }
    ],
    "sendOnDays": [
      1,
      2,
      3,
      4,
      5
    ],
    "groupBy": "TEAM",
    "sendEmpty": false
  }
}

{
  "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": "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"
  }
}