---
title: "Transition multiple flags to a new status in one call"
method: PUT
path: "/flags/update-status-bulk/{status}"
tags: ["Flag"]
---

# Transition multiple flags to a new status in one call

`PUT /flags/update-status-bulk/{status}`

Transitions a list of flags to the given target status in a single request, evaluating each flag independently against its own current status and the caller's permissions. Use this instead of calling PUT /flags/{id}/update-status/{status} once per flag; per-flag failures do not abort the batch. Two selection modes are supported: the default "ids" mode, where the JSON body or multipart form supplies flagIds directly, plus optional comment and/or files applied to every successfully transitioned flag; and a JSON-only "filter" mode (set type to "filter"), where filter selects all matching flags server-side and expectedCount is the client's snapshot count used to detect drift — the request is rejected with 409 if the live count no longer matches. Filter-based selection can be disabled by configuration, in which case it returns 503. The status path parameter accepts the same canonical wire values and aliases as PUT /flags/{id}/update-status/{status} (case-insensitive). The caller must hold at least one of the listed per-transition permissions to pass the outer authorization gate; each flag is then re-checked individually against the specific transition it requires. Always returns HTTP 200, even when every flag in the batch fails — inspect the response body's successful/failed arrays and successCount/failureCount for the actual outcome. An empty or omitted flagIds list returns 200 with totalCount, successCount, and failureCount all zero.

## Path parameters

- `status` string, required

## Headers

- `tenant-id` string, required

## Request body

- BulkFlagStatusUpdateRequest — Request to update status of multiple flags
  - `type` string — Selection type: "ids" (default) or "filter".
  - `flagIds` string[] — Flag IDs to update (used when type is "ids").
  - `filter` JsonNode
    - `empty` boolean
    - `valueNode` boolean
    - `containerNode` boolean
    - `missingNode` boolean
    - `array` boolean
    - `object` boolean
    - `nodeType` 'ARRAY' | 'BINARY' | 'BOOLEAN' | 'MISSING' | 'NULL' | 'NUMBER' | 'OBJECT' | 'POJO' | 'STRING'
    - `pojo` boolean
    - `number` boolean
    - `integralNumber` boolean
    - `floatingPointNumber` boolean
    - `short` boolean
    - `int` boolean
    - `long` boolean
    - `float` boolean
    - `double` boolean
    - `bigDecimal` boolean
    - `bigInteger` boolean
    - `textual` boolean
    - `boolean` boolean
    - `null` boolean
    - `binary` boolean
  - `expectedCount` integer — Expected number of matching flags for the filter (required when type is "filter").
  - `comment` string — Optional comment for the status change; stored on each flag's history record.

## Response `200`

Bulk update completed. successful/failed are arrays of {flagId, flagResponse} or {flagId, errorMessage, errorCode} respectively — errorCode is the stringified HTTP status code for that flag's failure (e.g. "409"). Each flagResponse omits the internal `tenantProviderId` and `hash` columns. totalCount, successCount, and failureCount summarize the batch.

- BulkFlagStatusUpdateResponse — Response containing results of bulk flag status update operation
  - `successful` StatusUpdateResult[], required — List of successful status updates
    - `flagId` string — Flag ID that was processed
    - `flagResponse` object — The updated flag record; present only when this flag's transition succeeded, null when it failed. The internal tenantProviderId and hash columns are omitted.
      - `id` string
      - `tenantProviderId` string
      - `flagTypeId` string
      - `data` JsonNode
        - `empty` boolean
        - `valueNode` boolean
        - `containerNode` boolean
        - `missingNode` boolean
        - `array` boolean
        - `object` boolean
        - `nodeType` 'ARRAY' | 'BINARY' | 'BOOLEAN' | 'MISSING' | 'NULL' | 'NUMBER' | 'OBJECT' | 'POJO' | 'STRING'
        - `pojo` boolean
        - `number` boolean
        - `integralNumber` boolean
        - `floatingPointNumber` boolean
        - `short` boolean
        - `int` boolean
        - `long` boolean
        - `float` boolean
        - `double` boolean
        - `bigDecimal` boolean
        - `bigInteger` boolean
        - `textual` boolean
        - `boolean` boolean
        - `null` boolean
        - `binary` boolean
      - `createdAt` string, date
      - `createdBy` string
      - `updatedAt` string, date
      - `updatedBy` string
      - `originMonitoringWorkflowId` string
      - `hash` string
      - `tenantId` string
      - `practitionerPrefix` string
      - `practitionerFirstName` string
      - `practitionerMiddleName` string
      - `practitionerLastName` string
      - `practitionerNpi` string
      - `statesToCredential` string[]
      - `practitionerType` string[]
      - `credentialingStatus` string
      - `dataSource` string
      - `practitionerDateOfBirth` string
      - `practitionerEmail` string
      - `lastCredentialedDate` string
      - `markedSeenAt` string, date
      - `markedSeenBy` string
    - `errorMessage` string — Human-readable reason this flag's transition failed; null when it succeeded
    - `errorCode` string — The stringified HTTP status code corresponding to why this flag's transition failed (e.g. "400", "403", "404", "409", "500"); null when it succeeded
  - `failed` StatusUpdateResult[], required — List of failed status updates
    - `flagId` string — Flag ID that was processed
    - `flagResponse` object — The updated flag record; present only when this flag's transition succeeded, null when it failed. The internal tenantProviderId and hash columns are omitted.
      - `id` string
      - `tenantProviderId` string
      - `flagTypeId` string
      - `data` JsonNode
        - `empty` boolean
        - `valueNode` boolean
        - `containerNode` boolean
        - `missingNode` boolean
        - `array` boolean
        - `object` boolean
        - `nodeType` 'ARRAY' | 'BINARY' | 'BOOLEAN' | 'MISSING' | 'NULL' | 'NUMBER' | 'OBJECT' | 'POJO' | 'STRING'
        - `pojo` boolean
        - `number` boolean
        - `integralNumber` boolean
        - `floatingPointNumber` boolean
        - `short` boolean
        - `int` boolean
        - `long` boolean
        - `float` boolean
        - `double` boolean
        - `bigDecimal` boolean
        - `bigInteger` boolean
        - `textual` boolean
        - `boolean` boolean
        - `null` boolean
        - `binary` boolean
      - `createdAt` string, date
      - `createdBy` string
      - `updatedAt` string, date
      - `updatedBy` string
      - `originMonitoringWorkflowId` string
      - `hash` string
      - `tenantId` string
      - `practitionerPrefix` string
      - `practitionerFirstName` string
      - `practitionerMiddleName` string
      - `practitionerLastName` string
      - `practitionerNpi` string
      - `statesToCredential` string[]
      - `practitionerType` string[]
      - `credentialingStatus` string
      - `dataSource` string
      - `practitionerDateOfBirth` string
      - `practitionerEmail` string
      - `lastCredentialedDate` string
      - `markedSeenAt` string, date
      - `markedSeenBy` string
    - `errorMessage` string — Human-readable reason this flag's transition failed; null when it succeeded
    - `errorCode` string — The stringified HTTP status code corresponding to why this flag's transition failed (e.g. "400", "403", "404", "409", "500"); null when it succeeded
  - `totalCount` integer, required — Total number of flags processed
  - `successCount` integer, required — Number of successful updates
  - `failureCount` integer, required — Number of failed updates

## Other responses

- `400` — Bad Request - the status path parameter does not match any known status or alias, the tenant-id header is missing, or (filter mode) filter or expectedCount was omitted
- `401` — Unauthorized - authentication is required; the JWT is missing or invalid
- `403` — Forbidden - the caller lacks any of the per-transition permissions required to use this endpoint at all (individual flags a caller can't transition are instead reported in the failed array with errorCode 403)
- `409` — Conflict - filter mode only: the expectedCount submitted by the client no longer matches the live count of flags matching filter; retry with currentCount from the response body as the new expectedCount
- `500` — Internal server error - an unexpected error occurred while processing the request
- `503` — Service Unavailable - filter mode only: filter-based Select All is currently disabled by configuration; fall back to submitting explicit flagIds

---

[API](https://skmtc.net/certifyos/apis/certify-api-layer.md) · [All operations](https://skmtc.net/certifyos/apis/certify-api-layer/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/certifyos/certify-api-layer/revisions/563848e0ecc0/schema)
