Delete a work item type
Remove a work item type from a project. A successful delete returns 204 with an empty body.
Deletion is guarded. A type that is the project default, or that still has work items on it, is rejected with 409 conflict rather than cascading — the API will not silently untype existing work.
If your goal is to stop people picking a type, set is_active to false instead. That works regardless of how many work items already use the type, and it is reversible.
This write requires project mode
If the workspace manages types at the workspace level, this returns 409 work_item_types_managed_at_workspace. Delete the type on the workspace surface instead. See Work item type modes.
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.
project_id:requiredstring (uuid)The project the type belongs to.
pk:requiredstring (uuid)The id of the work item type to delete.
Response shaping
fields:optionalstringComma-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: created_at, description, id, is_active, is_default, is_epic, level, logo_props, name.
See Sparse fields.
Scopes
projects.work_item_types:write
Errors
| Status | Code | Cause |
|---|---|---|
400 | invalid_request | The request could not be processed as sent. |
401 | unauthorized | Missing or invalid credentials. |
402 | payment_required | The feature this endpoint belongs to isn't enabled on your plan, or is switched off. |
403 | forbidden | Your role or token scope can't delete work item types. |
404 | not_found | No such type, project, or workspace — or the type belongs to another project. |
406 | not_acceptable | The Accept header asks for a representation the API can't produce. |
409 | conflict | The type is the project default, or work items still use 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/projects/4af68566-94a4-4eb3-94aa-50dc9427067b/work-item-types/d1e7a4c9-2b58-4f36-9a0e-7c3b5d81f240/" \
-H "X-Api-Key: $PLANE_API_KEY"import requests
response = requests.delete(
"https://api.plane.so/api/v2/workspaces/my-team/projects/4af68566-94a4-4eb3-94aa-50dc9427067b/work-item-types/d1e7a4c9-2b58-4f36-9a0e-7c3b5d81f240/",
headers={"X-Api-Key": "your-api-key"},
)
print(response.status_code) # 204const response = await fetch(
"https://api.plane.so/api/v2/workspaces/my-team/projects/4af68566-94a4-4eb3-94aa-50dc9427067b/work-item-types/d1e7a4c9-2b58-4f36-9a0e-7c3b5d81f240/",
{
method: "DELETE",
headers: {
"X-Api-Key": "your-api-key",
},
},
);
console.log(response.status); // 204(empty body){
"type": "conflict",
"code": "conflict",
"detail": "A work item type with existing work items cannot be deleted."
}Before a delete will succeed
Work through these in order:
- It must not be the default. Promote another type with mark-default. Marking a new default clears the flag on this one in the same request.
- No work items may reference it. Move them to another type, or delete them. There is no force flag — the check is the point.
Both failures come back as 409 conflict, distinguished by the detail string. Branch on the status and code; treat detail as text for humans.
Two 409s, two different meanings
conflict means the type is protected or in use — a state you can fix. work_item_types_managed_at_workspace means you called the wrong surface — a routing mistake, fixed by calling the workspace endpoint instead. Always read the code, never just the status.

