---
title: "Bulk Action Invoice"
method: POST
path: "/invoice/bulk_action"
---

# Bulk Action Invoice

`POST /invoice/bulk_action`

## Request

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

Performs a bulk action on a set of invoices. The invoice set to act on is determined either by an explicit `invoice_uid` array, or by `filter_rules` (preferred) / legacy `filter.*` fields — `invoice_uid` can be combined with either filter mode and is merged in additively (`$in`), not used as an exclusive selector.

If `filter_rules` is a non-empty array, it takes precedence as the v3 filter engine; otherwise the legacy `filter` object (or `filter.*` query/body params) is used.

Actions `update_status` (except PARTIALLY_PAID/BAD_DEBT/ARCHIVED/CLOSED transitions), `charge_card`, and `send_email` are processed asynchronously — the response only acknowledges that the job was queued and does not reflect per-invoice success/failure. `update_field` and the synchronous `update_status` transitions apply immediately and return `data.total_updated` / `data.total_invalid` counts. `associate_campaign` is the only action that returns a per-item result (`data.skipped_invoice_uids`).

The maximum number of invoices a single call can affect is governed by the account's `bulk_action_limit` policy (falls back to a platform default). `charge_card` has its own, separate cap (default 10). `associate_campaign` is capped at 1000 invoices per call.

## Request body

- object
  - `action` 'update_field' | 'update_status' | 'charge_card' | 'send_email' | 'associate_campaign': update_field: change one field across all matched invoices. update_status: transition invoice_status. charge_card: charge the customer's card on file. send_email: send an email/SMS notice. associate_campaign: enroll matched invoices into a marketing campaign.
  - `invoice_uid` string[]: Optional explicit list of invoice uids to include. Combined additively ($in) with filter_rules/filter — not an exclusive selection mode.
  - `filter_rules` object[]: v3 filter engine rules used to select the invoice set. Takes priority over `filter` when a non-empty array is supplied.
  - `action_options` object
    - `custom_field` object: update_field only. Sets a custom field value across matched invoices.
      - `label` string
      - `value` string
      - `type` string
      - `read_only` boolean
      - `hide_to_fe` boolean
      - `hide_field` boolean
      - `group_uid` string
      - `group_name` string
    - `invoice_date` string: update_field only. Mutually exclusive with the other update_field options below.
    - `due_date` string: update_field only.
    - `template` string: update_field only. An invoice-type template_uid.
    - `business_unit` string: update_field only. A business_unit uid.
    - `tags` string[]: update_field only.
    - `invoice_status` 'DRAFT' | 'AWAIT_PAYMENT' | 'PARTIALLY_PAID' | 'PAID' | 'BAD_DEBT' | 'ARCHIVED' | 'CLOSED' | 'CANCELED' | 'READY_TO_INVOICE': update_status only.
    - `remarks` string: update_status only. Optional.
    - `payment_date` string: Required when action is charge_card, or update_status with invoice_status PAID.
    - `payment_mode_uid` string: Required when action is charge_card, or update_status with invoice_status PAID.
    - `type` 'EMAIL' | 'SMS': send_email only. Defaults to EMAIL.
    - `email_subject` string: send_email only. Required when type is EMAIL.
    - `email_body` string: send_email only. Required when type is EMAIL.
    - `sms_body` string: send_email only. Required when type is SMS.
    - `campaign_uid` string: associate_campaign only. The campaign must not be in a COMPLETED or ARCHIVED state.
  - `send_pdf` boolean: send_email only. Read independently of action_options — pass at the top level (or as a query/path param) rather than nested inside action_options.
  - `filter` object: Legacy filter object, used only when filter_rules is omitted or empty.
    - `invoice_date_filter` string
    - `due_date_filter` string
    - `invoice_from_date` string
    - `invoice_to_date` string
    - `due_from_date` string
    - `due_to_date` string
    - `status` string
    - `job` string
    - `customer` string
    - `estimate` string
    - `organization` string
    - `created_by` string
    - `team_uid` string

## Response `200`

200

- object
  - `type` string
  - `title` string
  - `message` string
  - `data` object: Present for update_status (sync transitions), update_field, and associate_campaign only. Not returned for asynchronously-queued actions.
    - `total_updated` integer
    - `total_invalid` integer
    - `enrolled_count` integer
    - `skipped_count` integer
    - `skipped_invoice_uids` string[]

## Other responses

- `400`: 400

## Changes

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

[Operation history](https://skmtc.dev/zuper/apis/zuper-pro-api/changes/invoice/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)
