---
title: "Set Requirements State Bulk"
method: POST
path: "/marketing/guidelines/requirements/state"
tags: ["marketing-guidelines"]
---

# Set Requirements State Bulk

`POST /marketing/guidelines/requirements/state`

## Request

- Base URL: `https://api.kobaltlabs.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.kobaltlabs.com/marketing/guidelines/requirements/state`
- Auth: none declared

Turn several requirements off, remove them, or put them back, in one press.

The library is long enough that the interesting selections are not one row: a search that finds
seventeen restatements of the same enforcement note is a single decision, and making it
seventeen times is how it does not get made.

**Removal stays archival.** `ARCHIVED` keeps the requirement and every version of it readable,
which is the point on regulated compliance material; there is no hard delete here.

One requirement's refusal never fails the batch, and every id gets an outcome — the three
refusals are `refuse_state_change`, the same function the rollout-consistency worklist uses, so
the two surfaces cannot drift about what a person may do to a requirement.

## Request body

- BulkSetRequirementStateRequest: Turn several requirements off, remove them, or put them back. Same rules as the single-requirement form, which is why the route carries the same refusals: SUPERSEDED is what a newer decomposition writes and PROPOSED is what an agent writes, never a person (`REFUSED_STATE_TARGETS`). The cap is not arbitrary. Each requirement takes a lock on the live library for the whole batch and costs one subtransaction id, and Postgres spills its per-backend `subxids` array past 64 — at which point every other backend's visibility checks start hitting `pg_subtrans`, which is a cluster-wide problem rather than a slow request.
  - `requirement_ids` string[], required
  - `state` 'active' | 'disabled' | 'archived' | 'superseded' | 'proposed', required: Whether a requirement is in the working library, and if not, why not. All of them are recorded as revisions, so every one is reversible and readable. ARCHIVED and SUPERSEDED are deliberately distinct: ARCHIVED is a person deciding this obligation does not apply to them, SUPERSEDED is a newer decomposition of the same guideline taking over. A regeneration must never overwrite the first with the second — that would erase a human decision.
  - `change_note` string, nullable

## Response `200`

Successful Response

- BulkRequirementStateResponse
  - `applied` integer, required
  - `skipped` integer, required
  - `outcomes` BulkRequirementStateOutcome[], required
    - `requirement_id` string, uuid, required
    - `applied` boolean, required
    - `state` 'active' | 'disabled' | 'archived' | 'superseded' | 'proposed', required: Whether a requirement is in the working library, and if not, why not. All of them are recorded as revisions, so every one is reversible and readable. ARCHIVED and SUPERSEDED are deliberately distinct: ARCHIVED is a person deciding this obligation does not apply to them, SUPERSEDED is a newer decomposition of the same guideline taking over. A regeneration must never overwrite the first with the second — that would erase a human decision.
    - `reason` string, nullable, required

## Other responses

- `422`: Validation Error

## Changes

- **2026-09-02** `425d5b8a3c17`: 1 warning, 1 info
  - added the new `proposed` enum value to the `outcomes/items/state/anyOf[subschema #1: GuidelineRequirementState]/` response property for the response status `200`
  - added the new `proposed` enum value to the request property `state`

[Operation history](https://skmtc.dev/kobaltlabs/apis/kobaltlabs-api/changes/marketing/guidelines/requirements/state/post.md)

---

[API](https://skmtc.dev/kobaltlabs/apis/kobaltlabs-api.md) - [All operations](https://skmtc.dev/kobaltlabs/apis/kobaltlabs-api/llms.txt) - [OpenAPI document](https://skmtc.dev/kobaltlabs/apis/kobaltlabs-api/revisions/8587332d5e43?raw)
