Skip to content

Update a work item type ​

PATCH/api/v2/workspaces/{slug}/projects/{project_id}/work-item-types/{pk}/

Rename a type, rewrite its description, hide it from pickers, or correct its sync correlation fields. Work items already using the type are unchanged: this edits the type and does not change the type of any work item.

PATCH is partial. Send only the fields you want to change; anything you omit keeps its current value. Omitting a field is not the same as sending null.

This write requires project mode

If the workspace manages types at the workspace level, this returns 409 work_item_types_managed_at_workspace. Edit the type with the workspace endpoint instead. See Work item type modes.

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.

project_id:requiredstring (uuid)

The project the type belongs to.

pk:requiredstring (uuid)

The id of the work item type to update.

Body parameters ​

Every field is optional. Send only the fields you are changing.

name:optionalstring

New display name for the type. Maximum 255 characters. Renaming is safe: work items reference the type by type_id, not by name.

description:optionalstring

What this type is for. It is returned as type_description by the schema endpoint, so this is the field to edit when integrations are choosing the wrong type.

is_active:optionalboolean

Whether the type can be assigned to new work items. Setting it to false hides the type from pickers without deleting it. Existing work items keep the type and stay readable. Use this instead of delete, which rejects a type that is in use.

external_id:optionalstring

Your system's identifier for this type, for sync and import correlation. Maximum 255 characters, nullable.

external_source:optionalstring

The system external_id came from, for example github or jira. Maximum 255 characters, nullable.

is_default, is_epic and level are not accepted here

is_default moves through mark-default, which is a separate request because promoting one type demotes another. is_epic and level are read-only, as is logo_props.

Response shaping ​

fields:optionalstring

Comma-separated list of fields to return. Fields you don't request are left out of the response instead of coming back as null, so a missing key means you didn't ask for it and null means the value is null. id is always included, whether or not you name it.

Pass all to get every requestable field. An unknown field name returns 400 with the list of valid names and the closest match, so a typo is caught instead of being silently ignored.

Requestable here: created_at, description, external_id, external_source, governance_mode, id, is_active, is_active_in_project, is_default, is_default_in_project, is_epic, level, logo_props, name, project_ids, rollout, updated_at, updated_by_id.

See Sparse fields.

Scopes ​

projects.work_item_types:write

Errors ​

StatusCodeCause
400invalid_requestA field over its 255-character limit, or "is_active": false on the default type.
401unauthorizedMissing or invalid credentials.
402payment_requiredThe feature this endpoint belongs to isn't enabled on your plan, or is switched off.
403forbiddenYour role or token scope can't update work item types.
404not_foundNo such type, project, or workspace, or the type belongs to another project.
406not_acceptableThe Accept header asks for a representation the API can't produce.
409conflictAnother type in this project already uses this external_id and external_source pair.
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 work item type
bash
curl -X PATCH \
  "https://api.plane.so/api/v2/workspaces/my-team/projects/4af68566-94a4-4eb3-94aa-50dc9427067b/work-item-types/d1e7a4c9-2b58-4f36-9a0e-7c3b5d81f240/" \
  -H "X-Api-Key: $PLANE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Defect",
  "description": "A verified regression in shipped behavior"
}'
Response200
json
{
  "id": "d1e7a4c9-2b58-4f36-9a0e-7c3b5d81f240",
  "name": "Defect",
  "description": "A verified regression in shipped behavior",
  "logo_props": {
    "in_use": "icon",
    "icon": {
      "name": "AlertCircle",
      "background_color": "#EF5974"
    }
  },
  "is_epic": false,
  "is_default": false,
  "is_active": true,
  "is_active_in_project": true,
  "is_default_in_project": false,
  "level": 0,
  "governance_mode": "any",
  "rollout": "none",
  "project_ids": ["4af68566-94a4-4eb3-94aa-50dc9427067b"],
  "external_id": null,
  "external_source": null,
  "created_at": "2026-01-14T09:24:03.117482Z",
  "updated_at": "2026-02-03T16:45:12.904117Z",
  "updated_by_id": "16c61a3a-512a-48ac-b0be-b6b46fe6f430"
}
Response400
json
{
  "type": "invalid_request",
  "code": "invalid_request",
  "detail": "The default work item type cannot be deactivated.",
  "errors": []
}

The default type cannot be deactivated

The API rejects "is_active": false for the project's default type, because every project needs a type for untyped work items. Promote another type with mark-default first, then deactivate this one.

Deactivate rather than delete

Delete refuses to remove a type that still has work items. Setting "is_active": false is usually what you want anyway: the type stops appearing in pickers, existing work items still render correctly, and you can reverse the change.