Skip to content

Work item type governance overview ​

In a workspace with workspace governance turned on, workflows live in the workspace catalog instead of in each project. Governance decides, for every project and work item type, which catalog workflow applies and who chose it. You set the rules per work item type with the routes in this group.

This page explains the model once. The endpoint pages link back here.

Learn more about workspace governance · Learn more about workflows

How a project's workflow is decided ​

Each active pair of a project and a work item type has one pick, the catalog workflow that project uses for that type. Plane writes the pick when the type is activated in the project, and every governance change below keeps it valid. When a pair has no pick, the workspace default workflow applies.

The type's governance mode controls who may change the pick:

ModeWho chooses the workflowThe project's own pick
anyThe project, from any active catalog workflow. This is the default for every type.Allowed.
constrainedThe project, from the type's allowlist of catalog workflows.Allowed inside the allowlist. A workflow outside it returns 400 workflow_outside_allowlist.
requiredThe workspace. Plane writes one mandated workflow into the pick of every project that uses the type.Refused with 403 workflow_mandated.

A pin works alongside the mode. It fixes the workflow for the projects you name. Creating a pin writes those projects' picks and marks them as set by the workspace, so a pinned project's attempt to set its own pick returns 403 workflow_assigned_by_workspace. Pins work under any and constrained. Under required, the mandate already decides, so creating a pin returns 409 workflow_pins_unavailable.

The mode is also on the work item type itself as the read-only governance_mode field. See Work item types.

To see which workflow resolved for each type in one project, and where that answer came from, use Work item type workflows.

The governance object ​

GET and PATCH on /work-item-types/{type_id}/governance/ return this object.

Attributes ​

  • mode string

    The type's governance mode. One of any, constrained, or required.

  • required_workflow_id string (uuid) or null

    The mandated workflow when mode is required, otherwise null.

  • allowlist array of objects

    The workflows the type is tied to. Under constrained, this is the allowlist. Under required, it holds the one mandated workflow. Under any, it is empty. Each entry has these fields:

    • workflow_id string (uuid). The catalog workflow.
    • name string or null. The workflow's name.
    • locked boolean. true while at least one project's pick uses this workflow for the type. A locked workflow can't leave the allowlist unless you send acknowledge: true.
    • in_use_by_project_ids array of string (uuid). The projects whose pick uses this workflow for the type.

Project ids, not names

in_use_by_project_ids carries ids only. Someone who can read workspace governance isn't necessarily a member of every project listed, so resolve the ids you're allowed to see with the projects endpoints.

Response200
json
{
  "mode": "constrained",
  "required_workflow_id": null,
  "allowlist": [
    {
      "workflow_id": "a1f4c7e2-3b98-4d61-8e25-6c0b9d7f3a14",
      "name": "Standard delivery",
      "locked": true,
      "in_use_by_project_ids": [
        "4af68566-94a4-4eb3-94aa-50dc9427067b",
        "7c19e5b3-2d84-4f6a-b0e7-93a1c5d8f246"
      ]
    },
    {
      "workflow_id": "e6b2d9f1-48a7-4c3e-9f50-1d7a8c2b6e93",
      "name": "Regulated release",
      "locked": false,
      "in_use_by_project_ids": []
    }
  ]
}

The pin object ​

Attributes ​

  • id string (uuid)

    Unique identifier for the pin.

  • project_id string (uuid)

    The project whose workflow the pin fixes.

  • workflow_id string (uuid)

    The catalog workflow the project is pinned to.

  • work_item_type_id string (uuid)

    The work item type the pin applies to.

  • created_at string (date-time)

    When the pin was created.

  • updated_at string (date-time)

    When the pin was last updated. Pinning a project that already has a pin for the type moves that pin to the new workflow.

Response200
json
{
  "id": "0b6d3f92-7e15-4a48-9c27-5f8e1a4d6b30",
  "project_id": "4af68566-94a4-4eb3-94aa-50dc9427067b",
  "workflow_id": "e6b2d9f1-48a7-4c3e-9f50-1d7a8c2b6e93",
  "work_item_type_id": "d1e7a4c9-2b58-4f36-9a0e-7c3b5d81f240",
  "created_at": "2026-01-14T09:22:41.478363Z",
  "updated_at": "2026-01-14T09:22:41.478363Z"
}

The preview object ​

Every dry run in this group returns the same shape. It counts the work items a change would move, broken down by the state they sit in now.

Attributes ​

  • total integer

    The number of work items the change would move.

  • per_state array of objects

    One entry per current state and affected project, so the same state_id can appear more than once when several projects are affected. Each entry has state_id (string (uuid)), the state the work items sit in now, and count (integer).

Response200
json
{
  "total": 12,
  "per_state": [
    {
      "state_id": "b7e42a19-3c5d-4f80-9a26-8d1c0f4e7b53",
      "count": 9
    },
    {
      "state_id": "b7e42a19-3c5d-4f80-9a26-8d1c0f4e7b53",
      "count": 3
    }
  ]
}

Changing the mode ​

Send the new mode to Update work item type governance. What happens depends on the direction.

  • To any. Plane clears the allowlist. Pins stay, because a pin is valid under any. No pick changes and no work item moves.
  • To constrained. Send workflow_ids, the new allowlist. Every id must be an active catalog workflow. If a workflow that some project's pick uses would leave the allowlist, the request returns 409 workflow_allowlist_excludes_in_use and lists those workflows. Send the same body with acknowledge: true to go ahead. Plane then removes the affected projects' picks and deletes any pin that points outside the new allowlist. Those projects fall back to the workspace default workflow.
  • To required. Send required_workflow_id, an active catalog workflow. Without acknowledge: true, the request is a dry run. It returns 200 with a preview object and changes nothing. With acknowledge: true, Plane writes the mandated workflow into every project pick for the type and deletes every pin for the type, so returning to any or constrained later can't bring an old pin back.

acknowledge confirms a consequence you have already seen. Call Preview a governance change first to see how many work items would move.

The orphan gate ​

A change that moves projects onto a different workflow can leave work items in states the new workflow doesn't contain. Before Plane applies such a change, it counts those work items. If any exist and your state_mapping doesn't cover every one of their states, the request returns 409 workflow_state_orphans and writes nothing.

state_mapping is an object that maps a current state id to a state id in the target workflow:

json
{
  "state_mapping": {
    "b7e42a19-3c5d-4f80-9a26-8d1c0f4e7b53": "f960d3c2-8524-4a41-b8eb-055ce4be2a7f"
  }
}

The target workflow depends on the change. It is the workspace default workflow when a constrained change strands projects, the mandated workflow for required, or the workflow you pick with Update a work item type workflow.

The 409 body carries an orphans report. Its inner orphans array lists each stranded state with state_id, state_name, count, and a per_project breakdown. invalid_targets lists mapping values that aren't in the target workflow. Plane ignores a mapping key that isn't a valid UUID, so that state shows up as uncovered.

json
{
  "type": "conflict",
  "code": "workflow_state_orphans",
  "detail": "This change strands work items outside the target workflow; supply a state_mapping that covers them.",
  "orphans": {
    "error": "Some work items are in states that are not part of the new chain — map every affected state to a state in it.",
    "code": "orphaned_states",
    "orphans": [
      {
        "state_id": "b7e42a19-3c5d-4f80-9a26-8d1c0f4e7b53",
        "state_name": "In Review",
        "count": 12,
        "per_project": [
          { "project_id": "4af68566-94a4-4eb3-94aa-50dc9427067b", "count": 9 },
          { "project_id": "7c19e5b3-2d84-4f6a-b0e7-93a1c5d8f246", "count": 3 }
        ]
      }
    ],
    "invalid_targets": []
  }
}

Once the gate passes, Plane moves each stranded work item to its mapped state and records an activity entry on the work item. These rules decide which work items count:

  • Archived work items count and move. Draft work items don't.
  • Work items in a triage group state never move.
  • A change that moves more than 500 work items in one project finishes in the background, so the response can arrive before every work item has moved.

Pins ​

Create workflow pins pins one workflow across several projects in one call. Each pin also writes the project's pick, so the project starts using the pinned workflow immediately. Plane moves work items that are outside the pinned workflow to its default state.

Deleting a pin removes only the marker. The project keeps the workflow the pin set, and its own pick endpoint accepts changes again.

Governed workspaces only ​

Most of these routes work only under governance. In an ungoverned workspace, every route in this group except the two pin reads returns 409 states_managed_at_project. Workflows there belong to each project, so see Workflows instead.

Every route in this group also needs the workspace governance feature on your plan and returns 402 payment_required without it.

Endpoints ​

MethodPathDescription
GET/api/v2/workspaces/{slug}/work-item-types/{type_id}/governance/Get work item type governance
PATCH/api/v2/workspaces/{slug}/work-item-types/{type_id}/governance/Update work item type governance
POST/api/v2/workspaces/{slug}/work-item-types/{type_id}/governance/preview/Preview a governance change
GET/api/v2/workspaces/{slug}/work-item-types/{type_id}/governance/pins/List workflow pins
GET/api/v2/workspaces/{slug}/work-item-types/{type_id}/governance/pins/{pk}/Get a workflow pin
POST/api/v2/workspaces/{slug}/work-item-types/{type_id}/governance/pins/Create workflow pins
DELETE/api/v2/workspaces/{slug}/work-item-types/{type_id}/governance/pins/{pk}/Delete a workflow pin

The project side of the same model is in Work item type workflows. The catalog workflows themselves are in Workspace workflows.

Changed from v1 ​

  • The orphan gate returns 409 workflow_state_orphans. v1 returns 400 for the same condition.
  • allowlist[].in_use_by_project_ids carries project ids. v1 returns project names.
  • In an ungoverned workspace, these routes return 409 states_managed_at_project in the standard error shape.

See Migrating from v1 for the full list.

Response shaping ​

The pin reads accept ?fields= for sparse responses. See Sparse fields. The governance object and the preview object don't. Errors follow the shared problem+json contract.