---
title: "Bulk create or update shifts (asynchronous)"
method: POST
path: "/management/v2/shifts:bulk"
tags: ["Shifts"]
---

# Bulk create or update shifts (asynchronous)

`POST /management/v2/shifts:bulk`

## Request

- Base URL: `https://your-subdomain.deputy.deputy.com/api`
- URL: `https://your-subdomain.deputy.deputy.com/api/management/v2/shifts:bulk`
- Auth: API key in header `OAuth`

Creates or updates multiple shifts in bulk. This is an asynchronous API that returns immediately with an operation ID in the response metadata.operation.id field. Shifts without an ID will be created, while shifts with an ID will be updated. Use the operation ID to poll the /operations/v2/operations/{id} endpoint to check completion status. The operation processes upserts in the background. External IDs can be provided to track shifts from external systems. Optional override settings can bypass normal validation rules.

## Request body

- ScheduleShiftBulkUpsertRequestUpsertData
  - `items` ScheduleShiftBulkUpsertRequestUpsertItem[]: Array of shifts to create or update.
    - `externalIds` string[]: IDs that can be used to identify the shift request from the external system, e.g. a row number in a CSV file. The IDs may be used to identify multiple places e.g. for child shifts taken from multiple rows.
    - `override` ModelShiftOverride
      - `shiftValidation` boolean
      - `publishValidation` boolean
      - `compliance` ModelCompliance
        - `reason` string
        - `type` 'ALL'
    - `shift` Tenantschedulev2modelShift
      - `id` integer
      - `start` string
      - `end` string
      - `mealbreakDuration` number, float
      - `mealbreakSlots` ModelBreak[]
        - `slotType` 'BREAK' | 'WORK' | 'CUSTOM'
        - `start` integer
        - `end` integer
        - `state` 'NOT_START' | 'IN_PROGRESS' | 'FINISHED' | 'DURATION_ONLY' | 'DURATION_FINISHED'
        - `canStartEarly` boolean
        - `canEndEarly` boolean
        - `isMandatory` boolean
        - `type` 'MEAL_BREAK' | 'REST_BREAK'
        - `typeLabel` string
        - `startDateTime` string
        - `endDateTime` string
      - `duration` number, float
      - `cost` number, float
      - `area` integer
      - `employee` integer
      - `note` string
      - `warning` string
      - `warningOverrideComment` string
      - `isPublished` boolean
      - `timesheet` integer
      - `isOpen` boolean
      - `approvalRequired` boolean
      - `confirmationStatus` 'ROSTER_CONFIRMATION_NOT_REQUIRED' | 'ROSTER_CONFIRMATION_REQUIRED' | 'ROSTER_CONFIRMATION_DONE' | 'ROSTER_CONFIRMATION_DECLINED'
      - `confirmationNote` string
      - `confirmedByWhom` integer
      - `confirmedAt` string
      - `swapStatus` 'SWAP_STATUS_NOT_REQUIRED' | 'SWAP_STATUS_PENDING_OUT' | 'SWAP_STATUS_PENDING_IN' | 'SWAP_STATUS_PENDING_IN_OUT' | 'SWAP_STATUS_PENDING_APPROVAL' | 'SWAP_STATUS_APPROVED' | 'SWAP_STATUS_CANCELLED' | 'SWAP_STATUS_DECLINED'
      - `swapApprovedBy` integer
      - `shiftTemplate` integer
      - `children` V2modelChildShift[]
        - `id` integer
        - `start` string
        - `end` string
        - `cost` number, float
        - `area` integer
        - `canEdit` boolean
        - `parentId` integer
        - `isOpen` boolean
        - `approvalRequired` boolean
        - `isPublished` boolean
        - `confirmationStatus` 'ROSTER_CONFIRMATION_NOT_REQUIRED' | 'ROSTER_CONFIRMATION_REQUIRED' | 'ROSTER_CONFIRMATION_DONE' | 'ROSTER_CONFIRMATION_DECLINED'
        - `confirmedByWhom` integer
        - `confirmedAt` string
        - `creator` integer
        - `createdAt` string
        - `modifiedAt` string
        - `warning` string
        - `warningOverrideComment` string
        - `areaName` string
        - `location` integer
        - `locationName` string
      - `canEdit` boolean
      - `customFields` Tenantsharedv2modelCustomField[]
        - `id` string, int64
        - `booleanField` ModelBooleanField
          - `value` boolean
        - `stringField` ModelStringField
          - `value` string
        - `listField` ModelListField
          - `value` string
        - `multiListField` ModelMultiListField
          - `value` string[]
        - `fileField` ModelFileField
          - `value` integer
        - `employeeVisible` boolean
      - `customFieldData` integer
      - `creator` integer
      - `createdAt` string
      - `modifiedAt` string
      - `consentChangesets` ModelShiftConsentChangeset[]
        - `id` integer
        - `shiftId` integer
        - `consentTransactionId` string
        - `action` 'CREATE' | 'MODIFY' | 'DELETE'
        - `status` 'PENDING' | 'ACTIONED' | 'AUTO_ACTIONED'
        - `newData` ShiftConsentChangesetShiftConsentChangesetData
          - `start` string
          - `end` string
          - `approvalRequired` boolean
          - `cost` number, float
          - `date` string
          - `employee` integer
          - `mealbreakSlotsUnpaidMinutes` number, float
          - `mealbreakSlots` ModelBreak[]
            - `slotType` 'BREAK' | 'WORK' | 'CUSTOM'
            - `start` integer
            - `end` integer
            - `state` 'NOT_START' | 'IN_PROGRESS' | 'FINISHED' | 'DURATION_ONLY' | 'DURATION_FINISHED'
            - `canStartEarly` boolean
            - `canEndEarly` boolean
            - `isMandatory` boolean
            - `type` 'MEAL_BREAK' | 'REST_BREAK'
            - `typeLabel` string
            - `startDateTime` string
            - `endDateTime` string
          - `isOpen` boolean
          - `area` integer
          - `duration` number, float
          - `location` integer
        - `oldData` ShiftConsentChangesetShiftConsentChangesetData
          - `start` string
          - `end` string
          - `approvalRequired` boolean
          - `cost` number, float
          - `date` string
          - `employee` integer
          - `mealbreakSlotsUnpaidMinutes` number, float
          - `mealbreakSlots` ModelBreak[]
            - `slotType` 'BREAK' | 'WORK' | 'CUSTOM'
            - `start` integer
            - `end` integer
            - `state` 'NOT_START' | 'IN_PROGRESS' | 'FINISHED' | 'DURATION_ONLY' | 'DURATION_FINISHED'
            - `canStartEarly` boolean
            - `canEndEarly` boolean
            - `isMandatory` boolean
            - `type` 'MEAL_BREAK' | 'REST_BREAK'
            - `typeLabel` string
            - `startDateTime` string
            - `endDateTime` string
          - `isOpen` boolean
          - `area` integer
          - `duration` number, float
          - `location` integer
        - `violatedRules` ModelViolatedRules[]
          - `ruleCode` string
          - `warning` ModelViolatedRulesWarning
            - `message` string
          - `ruleConfigs` ModelViolatedRulesRuleConfig[]
            - `field` string
            - `operation` 'NOT_SPECIFIED' | 'GREATER_THAN' | 'LESS_THAN' | 'GREATER_THAN_OR_EQUAL' | 'LESS_THAN_OR_EQUAL' | 'EQUAL' | 'NOT_EQUAL'
            - `value` string
            - `gap` integer
            - `space` integer
        - `creator` integer
        - `createdAt` string
        - `modifiedAt` string
        - `consents` ModelConsent[]
          - `id` string
          - `recordId` string
          - `recordType` 'SHIFT' | 'TIMESHEET' | 'REGULAR_SCHEDULE'
          - `transactionId` string
          - `employeeId` integer
          - `status` 'PENDING' | 'ACCEPTED' | 'DECLINED' | 'CANCELLED' | 'OVERRIDDEN_ACCEPTED'
          - `description` string
          - `metadata` ModelShiftTypeConsentMetadata
            - `comment` string
            - `extras` object
          - `creator` integer
          - `createdAt` string, date-time
      - `areaName` string
      - `location` integer
      - `locationName` string
  - `skipCountChildren` boolean: If true, skips counting child shifts in the operation result. Useful for performance when dealing with many shifts with children.

## Response `200`

A successful response.

- ScheduleShiftBulkUpsertResponse: Response after initiating bulk upsert operation. Asynchronous API - returns immediately with operation ID.
  - `success` boolean: Indicates whether the bulk upsert request was accepted.
  - `metadata` ScheduleShiftBulkUpsertResponseMetadata
    - `operation` ScheduleShiftOperation: Operation tracking information for asynchronous APIs.
      - `operationId` string: Unique identifier for the operation. Use this to poll /operations/v2/operations/{id} for status updates.
      - `locks` OperationLock[]: Virtual Locks held by this operation that prevent conflicting operations.
        - `kind` string
        - `ids` object

---

[API](https://skmtc.dev/deputy/apis/deputy-v2-api.md) - [All operations](https://skmtc.dev/deputy/apis/deputy-v2-api/llms.txt) - [OpenAPI document](https://skmtc.dev/deputy/apis/deputy-v2-api/revisions/78f0278f4608?raw)
