Shift Offers

Overview

The Shift Offers Notify API allows managers to send shift offer notifications to employees. When called, it makes the shift as "open" and sends notifications (via email/SMS) to specified employees, inviting them to accept the shift.

🚧

SMS Costs

If clients have SMS notifications enabled and choose to use this functionality via your API, they will incur SMS fees within Deputy. You should always make this clear to clients when utilising this function.

Endpoint Details

URL

curl --request POST --url 'https://{install}.{geo}.deputy.com/api/management/v2/shifts/offers:notify'

Content-Type: application/x-www-form-urlencoded

Authentication: OAuth 2.0 based token or direct API token

Request Header

 "Content-Type": "application/json",
 "Authorization": "Bearer {{JWT | Oauth token}}"

Request Body

{
  "data": {
    "shiftIds": [int], 
    "employeeIds": [int],
    "replacedEmployeeId": int,
    "message": "string"
  }
}

Response

{
  "success": true,
  "data": [
    {
      "id": int,
      "start": "ISO8601 datetime",
      "end": "ISO8601 datetime",
      "area": int,
      "employee": int,
      "isOpen": bool,
      "isPublished": bool,
      ...
    }
  ],
  "metadata": {
    "countEmployeeWithNoContactInfo": int
  }
}

Data Elements

ElementTypeDescription
idIntegerThe unique identifier for the shift.
startStringThe start time of the shift in ISO 8601 format.
endStringThe end time of the shift in ISO 8601 format.
mealbreakDurationFloatThe duration of the meal break in hours (e.g., 0.5 for 30 minutes).
durationFloatThe total paid duration of the shift in hours (excluding unpaid breaks).
costFloatThe estimated cost of the shift.
areaIntegerThe ID of the operational area (department) this shift belongs to.
employeeIntegerThe ID of the employee assigned to the shift. After this API call, this will be 0 as the shift is now open.
noteStringAny attached notes to the shift.
warningStringAny warnings associated with the shift (e.g. fatigue, cost).
warningOverrideCommentStringThe comment left when a shift warning was overridden.
isPublishedBooleantrueif the shift is visible to employees.
timesheetIntegerThe ID of the corresponding timesheet, if one exists (0 if none).
isOpenBooleantrue if the shift is open and available for employees to accept. This API sets this value to true
approvalRequiredBooleantrue if an employee's acceptance of this shift offer requires manager approval.
confirmationStatusStringThe confirmation status of the shift (e.g., "ROSTER_CONFIRMATION_NOT_REQUIRED").
confirmationNoteStringA note related to the shift confirmation.
confirmedByWhomIntegerThe ID of the user who confirmed the shift (0 if not confirmed).
confirmedAtStringThe timestamp when the shift was confirmed.
swapStatusStringThe status of any shift swap request (e.g., "SWAP_STATUS_NOT_REQUIRED")
swapApprovedByIntegerThe ID of the user who approved a swap (0 if none).
shiftTemplateIntegerThe ID of the shift template used to create this shift (0 if none).
childrenArrayAn array of any child shifts (e.g., for for split shifts).
canEditBooleantrue if the currently authenticated user has permission to edit this shift
customFieldsArrayAn array of custom fields associated with the shift.
customFieldDataIntegerThe ID of the custom field data record.
creatorIntegerThe ID of the usr who orginally created the shift
createdAtStringThe timestamp when the shift was created in ISO 8601 format.
modifiedAtStringThe timestamp when the shift was last modified in ISO 8601 format.
consentChangesetsArrayAn array of consent changesets related to the shift.

Request Samples

Success case:

POST

curl --location 'https://business.dev.local.dpty.io/api/management/v2/shifts/offers:notify' \
--header 'Content-Type: application/json' \
--header 'Authorization: ••••••' \
--data '{
    "shiftIds": [
        19
    ],
    "employeeIds": [
        3,
        1,
        2,
        5,
        4
    ],
    "message": "Would you like to work this shift?a nadfidafadsif",
    "replacedEmployeeId": 0
}'

Response

{
    "success": true,
    "data": [
        {
            "id": 19,
            "start": "2025-10-18T09:00:00+11:00",
            "end": "2025-10-18T17:00:00+11:00",
            "mealbreakDuration": 0.5,
            "mealbreakSlots": [
                {
                    "slotType": "BREAK",
                    "start": 0,
                    "end": 1800,
                    "state": "DURATION_ONLY",
                    "canStartEarly": false,
                    "canEndEarly": false,
                    "isMandatory": false,
                    "type": "MEAL_BREAK",
                    "typeLabel": "Meal Break"
                }
            ],
            "duration": 7.5,
            "cost": 0,
            "area": 1,
            "employee": 0,
            "note": "",
            "warning": "",
            "warningOverrideComment": "",
            "isPublished": true,
            "timesheet": 0,
            "isOpen": true,
            "approvalRequired": false,
            "confirmationStatus": "ROSTER_CONFIRMATION_NOT_REQUIRED",
            "confirmationNote": "",
            "confirmedByWhom": 0,
            "confirmedAt": "",
            "swapStatus": "SWAP_STATUS_NOT_REQUIRED",
            "swapApprovedBy": 0,
            "shiftTemplate": 1,
            "children": [],
            "canEdit": true,
            "customFields": [],
            "customFieldData": 0,
            "creator": 1,
            "createdAt": "2025-10-16T21:06:28+11:00",
            "modifiedAt": "2025-10-16T21:17:50+11:00",
            "consentChangesets": []
        }
    ],
    "metadata": {
        "countEmployeeWithNoContactInfo": 0
    }
}

Unauthorized case

POST

curl --location 'https://business.dev.local.dpty.io/api/management/v2/shifts/offers:notify' \
--header 'Content-Type: application/json' \
--data '{
    "shiftIds": [
        19
    ],
    "employeeIds": [
        3,
        1,
        2,
        5,
        4
    ],
    "message": "Would you like to work this shift?a nadfidafadsif",
    "replacedEmployeeId": 0
}'



Response

{
    "success": false,
    "error": {
        "code": 401,
        "message": "Unauthorized",
        "details": []
    }
}

404 Not Found case

POST

`curl --location 'https://business.dev.local.dpty.io/api/management/v2/shifts/offers:notify' \
--header 'Content-Type: application/json' \
--header 'Authorization: ••••••' \
--data '{
    "shiftIds": [
        20
    ],
    "employeeIds": [
        3,
        1,
        2,
        5,
        4
    ],
    "message": "Would you like to work this shift?a nadfidafadsif",
    "replacedEmployeeId": 0
}'

Response

{
    "success": false,
    "error": {
        "code": 404,
        "message": "No roster found for the given shift ids",
        "details": []
    }
}

Empty Shift ID case

POST

`curl --location 'https://business.dev.local.dpty.io/api/management/v2/shifts/offers:notify' \
--header 'Content-Type: application/json' \
--header 'Authorization: ••••••' \
--data '{
    "shiftIds": [
        
    ],
    "employeeIds": [
        3,
        1,
        2,
        5,
        4
    ],
    "message": "Would you like to work this shift?a nadfidafadsif",
    "replacedEmployeeId": 0
}'

Response

`{
    "success": false,
    "error": {
        "code": 400,
        "message": "Shift ids are required",
        "details": []
    }
}

Empty EmployeeId case

curl --location 'https://business.dev.local.dpty.io/api/management/v2/shifts/offers:notify' \
--header 'Content-Type: application/json' \
--header 'Authorization: ••••••' \
--data '{
    "shiftIds": [
        19
    ],
    "employeeIds": [
    ],
    "message": "Would you like to work this shift?a nadfidafadsif",
    "replacedEmployeeId": 0
}'

Response

{
    "success": false,
    "error": {
        "code": 400,
        "message": "Employee ids are required",
        "details": []
    }
}

Employee Not Found case

POST

curl --location 'https://business.dev.local.dpty.io/api/management/v2/shifts/offers:notify' \
--header 'Content-Type: application/json' \
--header 'Authorization: ••••••' \
--data '{
    "shiftIds": [
        19
    ],
    "employeeIds": [
        9999
    ],
    "message": "Would you like to work this shift?a nadfidafadsif",
    "replacedEmployeeId": 0
}'

Response

{
    "success": false,
    "error": {
        "code": 400,
        "message": "Cannot find employee for given ids",
        "details": []
    }
}

Potential Errors

HTTP 400

{
  "error": {
    "code": 400,
    "message": "Employee ids are required"
  }
}

Will return when employee ids are not provided in the payload

401 Unauthorized

{
  "error": {
    "code": 401,
    "message": "Authorization header is required."
  }
}

Will return when the token is invalid or authorization header not provided.

403 Forbidden

{
  "error": {
    "code": 403,
    "message": "Authorization failed, you do not have permission to make an open Roster"
  }
}

Will return when the user permission related to the token does not have access to the open roster functionality in Deputy.

404 Not Found

{
  "error": {
    "code": 404,
    "message": "No roster found for the given shift ids"
  }
}

Will return when the rosters based on the shift ids provided does not exist

500 Internal Server Error

{
  "error": {
    "code": 500,
    "message": "Internal server error"
  }
}

Will return when something happens at the server which is unknown and fails