Create a workspace property option
Add a choice to a workspace-level OPTION property. The new option is appended to the end of the property's list and becomes immediately selectable on work items across the workspace.
The property must have property_type: "OPTION". Posting an option to a property of any other type returns 400 invalid_request, because a TEXT or DECIMAL property has no option list.
Workspace mode only
This write requires the workspace to manage work item types at the workspace level. In project mode it returns 409 work_item_types_managed_at_project. Add the option through the project-level endpoint 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.
property_id:requiredstring (uuid)The workspace-level OPTION property to add the choice to. A project-scoped property id returns 404 here, because this path only looks up workspace-level properties. See Workspace work item properties.
Body parameters
name:requiredstringThe choice as it is displayed. Maximum 255 characters.
description:optionalstringFree-form text explaining when to pick this choice.
is_default:optionalbooleanMake this the property's default choice. At most one option per property can be the default, and Plane does not move the default automatically: if another option already has it, this request returns 400 invalid_request. Clear the current default with a PATCH first.
external_id:optionalstringYour system's identifier for this option, for sync and import correlation. Maximum 255 characters.
external_source:optionalstringThe system external_id came from, for example github or jira. Maximum 255 characters.
sort_order is not accepted. Plane appends the new option after the current last one, so create options in the order you want them displayed.
Scopes
workspaces.work_item_properties:write
Errors
| Status | Code | Cause |
|---|---|---|
400 | invalid_request | Missing name, a field over 255 characters, is_default when the property already has a default, or a property whose property_type is not OPTION. |
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 write this workspace's properties. |
404 | not_found | No such workspace or workspace-level property, or it's outside your tenant. |
406 | not_acceptable | The Accept header asks for a representation the API can't produce. |
409 | conflict | This workspace manages work item types at the project level. Use the project-level options endpoint. |
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 POST \
"https://api.plane.so/api/v2/workspaces/my-team/work-item-properties/9d0e1f3b-6a72-4c85-9e4d-2b7f1a6c8d54/options/" \
-H "X-Api-Key: $PLANE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Sandbox",
"description": "Reported on an isolated test tenant",
"external_id": "env-sandbox",
"external_source": "servicedesk"
}'import requests
response = requests.post(
"https://api.plane.so/api/v2/workspaces/my-team/work-item-properties/9d0e1f3b-6a72-4c85-9e4d-2b7f1a6c8d54/options/",
headers={"X-Api-Key": "your-api-key"},
json={
"name": "Sandbox",
"description": "Reported on an isolated test tenant",
"external_id": "env-sandbox",
"external_source": "servicedesk",
},
)
print(response.json())const response = await fetch(
"https://api.plane.so/api/v2/workspaces/my-team/work-item-properties/9d0e1f3b-6a72-4c85-9e4d-2b7f1a6c8d54/options/",
{
method: "POST",
headers: {
"X-Api-Key": "your-api-key",
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Sandbox",
description: "Reported on an isolated test tenant",
external_id: "env-sandbox",
external_source: "servicedesk",
}),
},
);
const data = await response.json();{
"id": "2f6a94c1-7b38-4d50-91ae-3c0d5e8b7a26",
"name": "Sandbox",
"description": "Reported on an isolated test tenant",
"parent_id": null,
"is_default": false,
"is_active": true,
"sort_order": 40000,
"logo_props": {},
"external_id": "env-sandbox",
"external_source": "servicedesk",
"updated_at": "2026-01-14T09:22:41.478363Z",
"updated_by_id": null
}{
"type": "conflict",
"code": "work_item_types_managed_at_project",
"detail": "Work item types are managed at the project level for this workspace."
}Seeding a whole option set
Create the options in display order in one pass, then set the default with a follow-up PATCH. That keeps every create request free of is_default so a retried request can't run into the one-default rule.

