Update a work item property
Change a property's label, description, default, requirement, or availability. Values already recorded on work items stay where they are — you are editing the field definition, not rewriting anyone's data.
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.
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 property belongs to.
pk:requiredstring (uuid)The id of the property to update.
Body Parameters
Every field is optional — send the subset you are changing. There is no name field: name is the read-side slug, and display_name is what you write.
display_name:optionalstringNew human-readable label for the field. Maximum 255 characters.
description:optionalstringFree-form explanation of what the field is for, shown as helper text.
property_type:optionalstringThe kind of data the field holds: TEXT, DATETIME, DECIMAL, BOOLEAN, OPTION, RELATION, URL, EMAIL, FILE, or FORMULA.
Changing the type of a property that already holds values changes what those values mean, so treat this as a migration rather than an edit — in most cases creating a new property and retiring the old one with is_active: false is the safer move. The full reference is on the properties overview.
relation_type:optionalstringWhat a RELATION property points at: ISSUE, USER, RELEASE, or RICH_TEXT. Only meaningful when property_type is RELATION.
options:optionalarray of objectWrite-only. Define OPTION choices inline, the same way you can on create. Each entry is a property option object with name required.
For adding, editing, or removing a single choice on a live property, prefer the dedicated endpoints under Property options — they let you address one option by id instead of restating the set. The response always returns the resolved options array, never the payload you sent.
is_multi:optionalbooleanWhether the field accepts more than one value. Turning it off on a property that already holds several values per work item is a narrowing change — check your data first.
is_required:optionalbooleanWhether a value must be present. This applies going forward: existing work items with the field empty are not rejected retroactively, but the next edit will ask for a value. Pair it with a default_value so automated flows have something to fall back on.
is_active:optionalbooleanWhether the property is offered. Setting false is the reversible way to retire a field — the definition, its options, and its recorded values all survive, and the field simply stops being offered.
default_value:optionalarray of stringThe value applied when none is supplied. Always an array, even for a single-valued property — a DECIMAL field that defaults to 3 is sent as ["3"], not 3. Send [] to clear the default.
settings:optionalanyFree-form object holding type-specific configuration. The shape depends on property_type, so send the whole object rather than assuming keys — a partial settings object replaces the stored one.
validation_rules:optionalanyFree-form object holding type-specific validation constraints. Same whole-object caveat as settings.
external_id:optionalstringYour system's identifier for this field, for sync and import correlation. Maximum 255 characters.
external_source:optionalstringThe system external_id came from, for example jira or linear. Maximum 255 characters.
Scopes
projects.work_item_properties:write
Errors
| Status | Code | Cause |
|---|---|---|
400 | validation_error | An enum value outside the list, or a field over its length limit. |
401 | unauthorized | Missing or invalid credentials. |
403 | forbidden | Your role or token scope can't update properties. |
404 | resource_not_found | No such property, project, or workspace — or it's outside your tenant. |
409 | work_item_types_managed_at_workspace | This workspace manages work item types at the workspace level. Update the property on the workspace endpoint instead. |
429 | rate_limited | Throttled. Honor the Retry-After header before retrying. |
A 409 means wrong surface, not missing permission
If the workspace manages work item types at the workspace level, this project endpoint returns 409 work_item_types_managed_at_workspace — the write belongs on Update a workspace work item property instead. Reading the same property through this path still works. See Work item type modes.
name is not writable
name is derived by Plane and returned on reads only. Renaming the field means sending a new display_name.
curl -X PATCH \
"https://api.plane.so/api/v2/workspaces/my-team/projects/4af68566-94a4-4eb3-94aa-50dc9427067b/work-item-properties/c81b7e2a-5f34-4d90-8e17-3a6c9b0f2d75/" \
-H "X-Api-Key: $PLANE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"display_name": "Story points",
"is_required": true,
"default_value": ["3"]
}'import requests
response = requests.patch(
"https://api.plane.so/api/v2/workspaces/my-team/projects/4af68566-94a4-4eb3-94aa-50dc9427067b/work-item-properties/c81b7e2a-5f34-4d90-8e17-3a6c9b0f2d75/",
headers={"X-Api-Key": "your-api-key"},
json={
"display_name": "Story points",
"is_required": True,
"default_value": ["3"],
},
)
print(response.json())const response = await fetch(
"https://api.plane.so/api/v2/workspaces/my-team/projects/4af68566-94a4-4eb3-94aa-50dc9427067b/work-item-properties/c81b7e2a-5f34-4d90-8e17-3a6c9b0f2d75/",
{
method: "PATCH",
headers: {
"X-Api-Key": "your-api-key",
"Content-Type": "application/json",
},
body: JSON.stringify({
display_name: "Story points",
is_required: true,
default_value: ["3"],
}),
}
);
const data = await response.json();{
"id": "c81b7e2a-5f34-4d90-8e17-3a6c9b0f2d75",
"name": "story_points",
"display_name": "Story points",
"description": "Relative sizing for planning",
"property_type": "DECIMAL",
"relation_type": null,
"is_multi": false,
"is_required": true,
"is_active": true,
"default_value": ["3"],
"options": [],
"settings": {},
"validation_rules": {},
"logo_props": {},
"external_id": null,
"external_source": null,
"created_at": "2026-01-14T09:24:03.117482Z"
}{
"type": "https://api.plane.so/errors/conflict",
"title": "Conflict",
"status": 409,
"code": "work_item_types_managed_at_workspace",
"detail": "Work item types are managed at the workspace level for this workspace."
}Retiring a field without losing data
Deleting a property is permanent. When you want a field to stop appearing but its history to stay readable, deactivate it:
{
"is_active": false
}The definition, its options, and every value already recorded stay in place, and setting is_active back to true brings the field back exactly as it was.

