Remove a state from a workspace workflow
Take a catalog state out of a workflow's chain. The catalog state itself stays in the workspace and in every other workflow that uses it. A successful removal returns 204 with an empty body.
This DELETE takes an optional JSON body. Plane runs these checks in order and stops at the first one that fails:
- The chain keeps at least one state. Removing the last one returns
400. - Removing the chain's default state needs a
new_default_state_idthat stays in the chain, or the request returns400. - Every work item whose state would be outside the remaining chain needs a target in
state_mapping. The check covers every project and work item type whose pick points at the workflow. Without a target, the request returns409 workflow_state_orphanswith the same report as Update a workspace workflow. - No transition may start from, target, or reject to the state. If one does, the request returns
409 workflow_state_dependencies. Delete those transitions first with Delete a workspace workflow transition.
When every check passes, Plane removes the state and moves the stranded work items to their mapped states. Above 500 work items per project and work item type, the move runs in the background.
Path Parameters
slug:requiredstringThe workspace slug. It appears in your Plane URLs. In https://app.plane.so/my-team/projects/, the slug is my-team.
workflow_id:requiredstring (uuid)The catalog workflow whose chain you are working with.
state_id:requiredstring (uuid)The catalog state id, not the chain entry's own id. A state that isn't in this workflow's chain returns 404.
Body Parameters
new_default_state_id:optionalstring (uuid)Required when the state you are removing is the chain's default. The catalog state that becomes the new default. It must stay in the chain.
state_mapping:optionalobjectWhere to move stranded work items. Each key is a catalog state id that work items sit in, usually the removed state, and each value is a catalog state id that stays in the chain.
Move the default before you remove it
To remove the default state, mark another state as default with Mark a workspace workflow state as default first. The state you then remove is no longer the default, so you don't need new_default_state_id.
Scopes
workspaces.workflows:write
Errors
| Status | Code | Cause |
|---|---|---|
400 | invalid_request | The state is the last one in the chain, or it is the default and new_default_state_id is missing or not in the remaining chain. |
401 | unauthorized | Missing or invalid credentials. |
402 | payment_required | Workflows isn't on your plan, or is switched off. |
403 | forbidden | Your role or token scope can't edit workspace workflows. |
404 | not_found | No such workflow in this workspace's catalog, or the state isn't in its chain. |
406 | not_acceptable | The Accept header asks for a representation the API can't produce. |
409 | governance_migration_in_progress | A governance migration is running in this workspace, so writes are paused. Retry after it finishes. |
409 | states_managed_at_project | The workspace doesn't have governance turned on. Use the project's workflows instead. |
409 | workflow_state_dependencies | A transition still starts from, targets, or rejects to the state. |
409 | workflow_state_orphans | The removal would leave work items outside the remaining chain, and state_mapping doesn't map their state to a state that stays in it. |
413 | payload_too_large | The request body is over the size limit. |
415 | unsupported_media_type | The Content-Type isn't one this endpoint accepts. |
429 | rate_limited | Throttled. Honor the Retry-After header before retrying. |
curl -X DELETE \
"https://api.plane.so/api/v2/workspaces/my-team/workflows/9c1f0b3d-6d2e-4c9a-8b41-2f7e5a0d6c88/states/e5a1c8d3-4b7f-4e29-a6d0-2c9f5b8e1a74/" \
-H "X-Api-Key: $PLANE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state_mapping": {
"e5a1c8d3-4b7f-4e29-a6d0-2c9f5b8e1a74": "b7e42a19-3c5d-4f80-9a26-8d1c0f4e7b53"
}
}'import requests
response = requests.delete(
"https://api.plane.so/api/v2/workspaces/my-team/workflows/9c1f0b3d-6d2e-4c9a-8b41-2f7e5a0d6c88/states/e5a1c8d3-4b7f-4e29-a6d0-2c9f5b8e1a74/",
headers={"X-Api-Key": "your-api-key"},
json={
"state_mapping": {
"e5a1c8d3-4b7f-4e29-a6d0-2c9f5b8e1a74": "b7e42a19-3c5d-4f80-9a26-8d1c0f4e7b53",
},
},
)
print(response.status_code)const response = await fetch(
"https://api.plane.so/api/v2/workspaces/my-team/workflows/9c1f0b3d-6d2e-4c9a-8b41-2f7e5a0d6c88/states/e5a1c8d3-4b7f-4e29-a6d0-2c9f5b8e1a74/",
{
method: "DELETE",
headers: {
"X-Api-Key": "your-api-key",
"Content-Type": "application/json",
},
body: JSON.stringify({
state_mapping: {
"e5a1c8d3-4b7f-4e29-a6d0-2c9f5b8e1a74": "b7e42a19-3c5d-4f80-9a26-8d1c0f4e7b53",
},
}),
},
);
console.log(response.status);No response body.
{
"type": "conflict",
"code": "workflow_state_dependencies",
"detail": "Remove the flows that reference this state before removing it."
}{
"type": "conflict",
"code": "workflow_state_orphans",
"detail": "Removing this state strands work items; 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": "e5a1c8d3-4b7f-4e29-a6d0-2c9f5b8e1a74",
"state_name": "QA",
"count": 12,
"per_project": [
{
"project_id": "4af68566-94a4-4eb3-94aa-50dc9427067b",
"count": 9
},
{
"project_id": "d1e8a3c5-7f2b-4a96-8e04-3b6c9d1f5a27",
"count": 3
}
]
}
],
"invalid_targets": []
}
}{
"type": "invalid_request",
"code": "invalid_request",
"detail": "new_default_state_id is required when removing the default state."
}
