---
title: "Bulk Action Job"
method: POST
path: "/jobs/bulk_action"
---

# Bulk Action Job

`POST /jobs/bulk_action`

## Request

- Base URL: `https://dc-region.zuperpro.com/api`
- URL: `https://dc-region.zuperpro.com/api/jobs/bulk_action`
- Auth: API key in header `x-api-key`

Performs a bulk action on a set of jobs. The job set is determined by an explicit `job_uid` array and/or `filter_rules` (v3) / legacy `filter.*` fields, combined additively.

`assign_to_route` and `auto_assign_territory` are asynchronous: they queue a worker and respond with an acknowledgement before the work completes. `delete` responds before an async cascade-cleanup worker runs. `send_email` and `send_sms` respond before their per-job send loop finishes. `update_schedule` and `clear_schedule` are fully synchronous (one save per job) and are blocked with 403 if the company has the Appointments feature enabled. `update_status` applies to all matched jobs except those skipped for exceeding the job-status-history limit or failing a status-dependency check (when `mandate_dependency_check` is set) — those are reported back in `data`, the rest still succeed (partial success, not an all-or-nothing failure).

## Request body

- object
  - `action` 'delete' | 'assign' | 'unassign' | 'update_field' | 'assign_to_route' | 'update_status' | 'update_schedule' | 'send_email' | 'send_sms' | 'link_parent_job' | 'clear_schedule' | 'auto_assign_territory'
  - `job_uid` string[]: Optional explicit list of job uids. Combined additively with filter_rules/filter.
  - `filter_rules` object[]: v3 filter engine rules used to select the job set.
  - `filter` object: Legacy filter object, used only when filter_rules is omitted or empty.
  - `jobs` object[]: assign_to_route only. Explicit list of jobs to add to the route, each optionally with its own geo-coordinates. If omitted, the route-eligible jobs are resolved from the matched set's customer/property addresses.
    - `job_uid` string
    - `geo_cords` object
  - `unassign_users` boolean: assign_to_route only. Whether to unassign existing users from jobs added to the route. Defaults to true.
  - `mandate_dependency_check` boolean: update_status only. When true, jobs failing a status-dependency check are skipped (reported in the response) instead of transitioned.
  - `action_options` object
    - `team_uid` string: assign, unassign. Required.
    - `user_uid` union: assign, unassign. String, CSV string, or array of user uids. One of user_uid or assign_all/unassign_all is required.
      - string
      - string[]
    - `assign_all` boolean: assign only. Alternative to user_uid — assigns all eligible team members.
    - `unassign_all` boolean: unassign only. Alternative to user_uid — unassigns all currently assigned team members.
    - `custom_field` object: update_field only. Mutually exclusive with the plain field options below.
      - `label` string
      - `value` string
      - `group_uid` string
    - `due_date` string: update_field only. A falsy value clears it.
    - `job_title` string: update_field only.
    - `job_description` string: update_field only. A falsy value clears it.
    - `hide_to_fe` boolean: update_field only.
    - `job_priority` 'LOW' | 'MEDIUM' | 'HIGH' | 'URGENT': update_field only.
    - `job_tags` string[]: update_field only.
    - `business_unit` string: update_field only. A bu_uid. If the company restricts business-unit data, the caller's own business_units must include it, else 403.
    - `source` string: update_field only. A request_source uid.
    - `route_uid` string: assign_to_route only. Required.
    - `job_category` string: update_status only. A category uid. Required.
    - `job_status` string: update_status only. A status uid within job_category. One of job_status or status_internal_name is required.
    - `status_internal_name` string: update_status only. Alternative to job_status.
    - `remarks` string: update_status only. Optional.
    - `schedule_type` 'FIXED' | 'RELATIVE': update_schedule only. Required.
    - `date` string: update_schedule only. Required when schedule_type is FIXED.
    - `no_of_days` number: update_schedule only. Required when schedule_type is RELATIVE.
    - `email_subject` string: send_email only. Required unless a specific user_uid recipient is given.
    - `email_body` string: send_email only. Required unless a specific user_uid recipient is given.
    - `from_email` string: send_email only. Optional.
    - `sms_body` string: send_sms only. Required.
    - `parent_job` string: link_parent_job only. A job_uid. Required. Cannot itself be one of the matched/target jobs.

## Response `200`

200

- object
  - `type` string
  - `title` string
  - `message` string
  - `data` object[]: Present only for update_status, listing jobs skipped due to the status-history limit or a failed status-dependency check. All other matched jobs are still updated.
    - `message` string
    - `skipped_uids` string[]

## Other responses

- `400`: 400
- `403`: 403

## Changes

- **2026-11-03** `3c21bc232e16`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/zuper/apis/zuper-pro-api/changes/jobs/bulk_action/post.md)

---

[API](https://skmtc.dev/zuper/apis/zuper-pro-api.md) - [All operations](https://skmtc.dev/zuper/apis/zuper-pro-api/llms.txt) - [OpenAPI document](https://skmtc.dev/zuper/apis/zuper-pro-api/revisions/3c21bc232e16?raw)
