Skip to content

Update a project state ​

PATCH/api/v2/workspaces/{slug}/project-states/{pk}/

Change a project state's name, color, description, group, position, or external ids. Projects in the state stay where they are.

PATCH is partial. Send only the fields you want to change. Anything you omit keeps its current value.

is_default is not writable here. A request that sends is_default or default succeeds, but the flag doesn't change. Use Mark a project state as default instead.

Path Parameters ​

slug:requiredstring

The workspace slug. It appears in your Plane URLs. In https://app.plane.so/my-team/projects/, the slug is my-team.

pk:requiredstring (uuid)

The id of the project state to update.

Body Parameters ​

Every field is optional. Send the subset you are changing.

name:optionalstring

New display name, unique in the workspace. Maximum 50 characters. The comparison is case-sensitive.

color:optionalstring

Hex color used wherever the project state is rendered. Maximum 255 characters.

description:optionalstring

Free-form description of what the stage means.

group:optionalstring

Move the project state to a different lifecycle group. One of draft, planning, execution, monitoring, completed, or cancelled.

sequence:optionalnumber

Ordering weight. Lower values sort first. Set it to reposition the stage.

external_id:optionalstring

Your system's identifier for this project state. Maximum 255 characters.

external_source:optionalstring

The system external_id came from. Maximum 255 characters.

Response shaping ​

fields:optionalstring

Comma-separated list of fields to return. Unrequested keys are omitted from the response, not returned as null, so absent means "not requested" and null means "actually null". id always comes back whether or not you name it.

Pass all for every requestable field. An unknown name is a 400 that lists the valid set and suggests the closest match, so a typo can't silently cost you the saving.

Requestable here: color, created_at, created_by_id, description, external_id, external_source, group, id, is_default, name, sequence, updated_at, updated_by_id.

See Sparse fields.

Scopes ​

workspaces.project_states:write

Errors ​

StatusCodeCause
400invalid_requestA group outside the six lifecycle groups, or a field over its length limit.
401unauthorizedMissing or invalid credentials.
402payment_requiredProject states aren't included in the workspace's plan, or are turned off in its settings.
403forbiddenYour role or token scope can't update project states.
404not_foundNo such project state or workspace, or it's outside your tenant.
406not_acceptableThe Accept header asks for a representation the API can't produce.
409conflictAnother project state in the workspace already uses this name.
409governance_migration_in_progressA governance migration is running, so the workspace is read-only. Retry after it finishes.
413payload_too_largeThe request body is over the size limit.
415unsupported_media_typeThe Content-Type isn't one this endpoint accepts.
429rate_limitedThrottled. Honor the Retry-After header before retrying.
Update a project state
bash
curl -X PATCH \
  "https://api.plane.so/api/v2/workspaces/my-team/project-states/6f0c3a85-9b2e-4d17-a8f6-3e5b1c7d9a42/" \
  -H "X-Api-Key: $PLANE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Scoping",
  "sequence": 20000
}'
Response200
json
{
  "id": "6f0c3a85-9b2e-4d17-a8f6-3e5b1c7d9a42",
  "name": "Scoping",
  "description": "Scoping and research before a plan is agreed",
  "color": "#3E63DD",
  "group": "planning",
  "sequence": 20000,
  "is_default": false,
  "external_id": null,
  "external_source": null,
  "created_at": "2026-02-03T16:45:12.904117Z",
  "updated_at": "2026-02-05T10:12:08.611540Z",
  "created_by_id": "16c61a3a-512a-48ac-b0be-b6b46fe6f430",
  "updated_by_id": "16c61a3a-512a-48ac-b0be-b6b46fe6f430"
}
Response400
json
{
  "type": "invalid_request",
  "code": "invalid_request",
  "detail": "One or more fields failed validation.",
  "errors": [
    {
      "field": "group",
      "code": "invalid_choice",
      "message": "\"started\" is not a valid choice."
    }
  ]
}