Skip to content

Create a workspace work item property ​

POST/api/v2/workspaces/{slug}/work-item-properties/

Define a custom property once for the whole workspace. display_name and property_type are the only required fields; everything else refines how the value is captured.

A new property is not live yet

Creating a property adds it to the workspace catalog. It appears on work items only once a context binds it to projects and work item types. Follow this call with Create a property context, or the property will sit in the catalog unused.

Wrong mode is a 409, not a 404

If the workspace manages work item types at the project level, this route returns 409 with the code work_item_types_managed_at_project. Create the property on the project-level resource 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.

Body Parameters ​

display_name:requiredstring

The label shown wherever the property is rendered. Maximum 255 characters.

property_type:requiredstring

What kind of value the property holds. Choose carefully — it governs what relation_type, options, settings, and validation_rules mean.

  • TEXT — free-form text
  • DATETIME — a date and time
  • DECIMAL — a number
  • BOOLEAN — true or false
  • OPTION — a choice from a defined list
  • RELATION — a pointer to another record; pair it with relation_type
  • URL — a link
  • EMAIL — an email address
  • FILE — a file
  • FORMULA — a formula-backed value

A value outside this list is a 400 invalid_request.

relation_type:optionalstring

For a RELATION property, what it points at. One of ISSUE, USER, RELEASE, or RICH_TEXT. Leave it out — or send null — for every other property type.

description:optionalstring

Free-form explanation of what the property captures. Nullable.

is_required:optionalboolean

Whether a value must be supplied for this property.

is_multi:optionalboolean

Whether the property accepts more than one value.

is_active:optionalboolean

Whether the property is in use. Send false to define a property without putting it into circulation yet.

default_value:optionalarray of string

The value applied when none is supplied. Send an array even for a single value.

options:optionalarray of object

Seed the choices for an OPTION property in the same call. Write-only: the created options come back on the read-only options array of the response, and are managed afterwards through Property options, which is also where the fields an option accepts are documented.

settings:optionalany

Type-specific configuration. Its shape depends on property_type.

validation_rules:optionalany

Type-specific validation configuration.

external_id:optionalstring

Your system's identifier for this property, 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.

Response shaping ​

fields:optionalstring

Comma-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, default_value, description, display_name, external_id, external_source, id, is_active, is_multi, is_required, logo_props, name, options, property_type, relation_type, settings, validation_rules.

See Sparse fields.

Scopes ​

workspaces.work_item_properties:write

Errors ​

StatusCodeCause
400invalid_requestMissing display_name/property_type, or an enum value outside the allowed set.
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 write workspace work item properties.
404not_foundNo such workspace, or it's outside your tenant.
406not_acceptableThe Accept header asks for a representation the API can't produce.
409conflictThis workspace manages work item types at the project level.
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.
Create a workspace property
bash
curl -X POST \
  "https://api.plane.so/api/v2/workspaces/my-team/work-item-properties/" \
  -H "X-Api-Key: $PLANE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "display_name": "Severity",
  "property_type": "OPTION",
  "description": "How badly the customer is affected",
  "is_required": true,
  "is_multi": false,
  "options": [
    { "name": "Critical", "description": "Production is down" },
    { "name": "Major", "description": "A core workflow is broken", "is_default": true }
  ]
}'
Response201
json
{
  "id": "a7e3f1d0-5c92-4b68-8f31-2d4a6b9e0c15",
  "name": "severity",
  "display_name": "Severity",
  "description": "How badly the customer is affected",
  "property_type": "OPTION",
  "relation_type": null,
  "is_required": true,
  "is_multi": false,
  "is_active": true,
  "default_value": [],
  "options": [
    {
      "id": "9d2c7b41-6a80-4f35-8e19-5c3b0a7d2e46",
      "name": "Critical",
      "description": "Production is down",
      "is_default": false,
      "sort_order": 10000,
      "external_id": null,
      "external_source": null
    },
    {
      "id": "5a83e0b7-2c46-4d19-9f70-6b12c8e5a03d",
      "name": "Major",
      "description": "A core workflow is broken",
      "is_default": true,
      "sort_order": 20000,
      "external_id": null,
      "external_source": null
    }
  ],
  "settings": {},
  "validation_rules": {},
  "logo_props": {},
  "external_id": null,
  "external_source": null,
  "created_at": "2026-01-14T09:22:41.478363Z"
}
Response400
json
{
  "type": "invalid_request",
  "code": "invalid_request",
  "detail": "The request body failed validation.",
  "errors": [
    {
      "field": "property_type",
      "code": "invalid_choice",
      "message": "\"SELECT\" is not a valid choice."
    }
  ]
}

After creating ​

  1. Bind it — Create a property context decides which projects and work item types see the property.
  2. For OPTION properties, refine the choices with Property options.
  3. To put the property on a workspace-level work item type directly, use Attach properties to a workspace type.