States overview
A state is a step in a project's workflow. Every work item sits in exactly one state. In most workspaces, a state belongs to exactly one project. A workspace with governance turned on keeps its states in a workspace catalog instead, and each project uses the catalog states that its workflows include. See Workspace states for the catalog and for a list of every project's states in one call.
Each state is assigned to a group, which is what Plane uses to reason about progress. Boards, charts, and cycle burndowns read the group, not the state name, so a project can rename In Progress to Building without breaking any reporting.
The state object
Attributes
idstring (uuid)Unique identifier for the state.
namestringDisplay name, unique within the project. Maximum 255 characters.
descriptionstringFree-form description of what the state means in this workflow.
colorstringHex color used wherever the state is rendered, for example
#3f76ff.groupstringThe workflow group this state belongs to. One of
backlog,unstarted,started,completed,cancelled, ortriage.sequencenumberOrdering weight within the project. Lower values sort first.
is_defaultbooleanWhether new work items land in this state when no
state_idis supplied. Exactly one state per project is the default.is_triagebooleanWhether this is the project's triage state, used by intake. Read-only — a triage state is created and managed by Plane.
external_id,external_sourcestringCorrelation fields for sync and import. Together they let you map a state to a record in another system and find it again later.
created_atstring (date-time)When the state was created.
updated_atstring (date-time)When the state was last updated.
created_by_idstring (uuid)The user who created the state.
updated_by_idstring (uuid) or nullThe user who last updated the state.
nulluntil someone updates it.
Group drives behavior, name does not
Filtering work items by state_group=started is stable across projects even when each project names its in-progress state differently. Filtering by state_id is exact, but a state id belongs to one project unless the workspace is governed.
{
"id": "f960d3c2-8524-4a41-b8eb-055ce4be2a7f",
"name": "In Progress",
"description": "Actively being worked on",
"color": "#3f76ff",
"group": "started",
"sequence": 25000,
"is_default": false,
"is_triage": false,
"external_id": null,
"external_source": null,
"created_at": "2026-01-14T09:22:41.478363Z",
"created_by_id": "16c61a3a-512a-48ac-b0be-b6b46fe6f430"
}Endpoints
| Method | Path | Description |
|---|---|---|
GET | /api/v2/workspaces/{slug}/projects/{project_id}/states/ | List states |
GET | /api/v2/workspaces/{slug}/projects/{project_id}/states/{pk}/ | Get a state |
POST | /api/v2/workspaces/{slug}/projects/{project_id}/states/ | Create a state |
PATCH | /api/v2/workspaces/{slug}/projects/{project_id}/states/{pk}/ | Update a state |
DELETE | /api/v2/workspaces/{slug}/projects/{project_id}/states/{pk}/ | Delete a state |
POST | /api/v2/workspaces/{slug}/projects/{project_id}/states/upsert/ | Upsert a state |
POST | /api/v2/workspaces/{slug}/projects/{project_id}/states/bulk-create/ | Bulk create states |
POST | /api/v2/workspaces/{slug}/projects/{project_id}/states/bulk-update/ | Bulk update states |
POST | /api/v2/workspaces/{slug}/projects/{project_id}/states/bulk-delete/ | Bulk delete states |
Deleting states
Two deletes are rejected with 409 conflict:
- The project's default state cannot be deleted. Mark another state as default first.
- A state that still holds work items cannot be deleted. Move those work items to another state first.
Workspace governance
In a workspace with workspace governance turned on, these routes are read-only:
- List and get return the catalog states that the project's workflows include.
- Create, update, delete, and upsert return
409 states_managed_at_workspaceand change nothing. Manage states through workspace states and workspace workflows instead. - The bulk routes answer
200, and each row that reaches the governance check fails withstates_managed_at_workspace.
The governance check runs after the existence and permission checks on update and delete, so an unknown id is still 404 and a missing permission is still 403. On create it runs before body validation, so a governed workspace answers 409 even when the body is invalid.
Changed from v1
defaultis nowis_default.updated_byis nowupdated_by_id.- Reads no longer return
projectorworkspace. groupacceptstriagein addition to the five v1 groups.
See Migrating from v1 for the full list.

