---
title: "Bulk change product active state"
method: POST
path: "/companies/{company}/products/bulk-status"
tags: ["Products"]
---

# Bulk change product active state

`POST /companies/{company}/products/bulk-status`

## Request

- Base URL: `https://api.factuarea.com/v1`
- URL: `https://api.factuarea.com/v1/companies/{company}/products/bulk-status`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-API-Key`

Move up to 50 products (by id) to the target `new_status` (`active` or `inactive`). Idempotent with respect to the target: a product already in the requested state counts as `successful` without flipping. Returns a `BulkPartialSuccessResult`; products not found come back in `failures[]`.

## Path parameters

- `company` string, uuid, required

## Headers

- `Idempotency-Key` string, required
- `Factuarea-Version` string, date

## Request body

- BulkStatusProductsV1Request: Transition several products to `new_status` (`active` or `inactive`) in one request, up to 50 per batch. `ids` is an array of product UUIDs; the change is idempotent (a product already in the target status counts as successful). Products that do not exist are returned under `failures[]`.
  - `ids` string[], required
  - `new_status` 'active' | 'inactive', required

## Response `200`

- object
  - `data` BulkPartialSuccessResult, required: Result of a bulk or import operation that reports per-resource status. `total` is how many rows/resources were processed (`successful + failed`), `successful` how many were applied (deleted, created or validated) and `failed` how many could not be processed. `failures[]` carries one item per failed row. Shape shared by every bulk endpoint of the public API (the bulk-delete endpoints emit it today). Anchored integrators before `2026-09-01` keep receiving the previous `{object, deleted, failed[{id, reason}]}` shape via `Factuarea-Version`.
    - `total` integer, required: Number of rows/resources processed (`successful + failed`).
    - `successful` integer, required: Number of rows/resources processed successfully (deleted, created or validated).
    - `failed` integer, required: Number of rows/resources that could not be processed. Equals `failures` length.
    - `failures` object[], required: One item per failed row/resource. Always a list (empty, never `null`, when there are no failures).
      - `id` string: UUID v7 of the existing resource that could not be processed. Present for bulk operations over existing resources (e.g. bulk-delete).
      - `index` integer: 0-based position of the row within the batch. Present for new rows without a resource yet (bulk-create with `dry_run`, import CSV).
      - `error_code` string, required: Machine-readable error code from the v1 error catalog (stable across languages). For bulk-delete: `resource_not_found` or `resource_not_deletable`.
      - `error_message` string, required: Human-readable reason for the failure, in Spanish (internal messages are not exposed).
      - `errors` FieldIssue[]: Per-field blocking issues (validate-only / bulk-create flows). Empty or absent for bulk-delete.
        - `param` string, nullable, required: Name of the affected field, or `null` when the issue is not tied to a specific field.
        - `code` string, required: Machine-readable code for the field issue (stable across languages).
        - `message` string, required: Human-readable description of the issue, in Spanish.
      - `warnings` FieldIssue[]: Per-field non-blocking warnings (validate-only / bulk-create flows). Empty or absent for bulk-delete.
        - `param` string, nullable, required: Name of the affected field, or `null` when the issue is not tied to a specific field.
        - `code` string, required: Machine-readable code for the field issue (stable across languages).
        - `message` string, required: Human-readable description of the issue, in Spanish.

## Other responses

- `400`: `parameter_unknown` with `subcode` `retired_active_profile_header`: the retired `X-Active-Profile` header was sent; the company goes in the path. `parameter_invalid_format` on `Factuarea-Version`: the header is not a `YYYY-MM-DD` date. `unsupported_api_version`: the `Factuarea-Version` date is not a supported version.
- `401`: Missing or invalid API key.
- `403`: The request is authenticated but not allowed: the API key lacks the required scope (`insufficient_scope`), the plan does not include the public API or this feature (`addon_not_active`, `feature_not_available_in_plan`), or the module is not available with a test key (`module_not_available_in_sandbox`).
- `404`: The requested resource does not exist or belongs to another company. `profile_not_found`: the company in the path does not exist, is not in the API key scope or belongs to the other environment (live or test).
- `422`: Validation failed. The `error.param` field identifies which input is invalid.
- `429`: Rate limit exceeded. Retry after the duration in `Retry-After`.
- `500`: Unexpected server error.

---

[API](https://skmtc.dev/factuarea/apis/factuarea-public-api.md) · [All operations](https://skmtc.dev/factuarea/apis/factuarea-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/factuarea/apis/factuarea-public-api/revisions/718e77934422?raw)
