Work item properties overview
A work item property is a custom field you define on a project. Once a property is attached to a work item type, every work item of that type can carry a value for it, such as a severity, a customer name, a due-by timestamp, or a link to a design doc.
A property is a definition, not a value. It says what the field is called, what kind of data it holds, whether it is required, and what choices are available. The values themselves live on individual work items.
Properties in this group are project-level: they are defined inside one project and belong only to that project. The workspace equivalent lives at Work item properties (workspace).
One mode per workspace
A workspace manages work item types, and therefore their properties, in exactly one mode: project-level or workspace-level. Writing to the endpoints on this page while the workspace is in workspace mode returns 409 work_item_types_managed_at_workspace, not 404 or 403. The same write is available on the other surface. Reads are not affected by mode. See Work item type modes.
The work item property object
Attributes
idstring (uuid)Unique identifier for the property. This is the id you pass when attaching the property to a type or managing its options.
namestringThe machine-readable slug for the property, derived by Plane. It is read-only and is not a create or update body field. Use it when you need a stable key in your own storage.
display_namestringThe human-readable label shown wherever the property is rendered. This is the field you write on create and update. Maximum 255 characters.
descriptionstringFree-form explanation of what the field is for. Plane shows it as helper text next to the field.
property_typestringWhat kind of data the property holds. One of
TEXT,DATETIME,DECIMAL,BOOLEAN,OPTION,RELATION,URL,EMAIL,FILE, orFORMULA. See the property type reference below.relation_typestringWhat a
RELATIONproperty points at. One ofISSUE,USER,RELEASE, orRICH_TEXT.nullfor every other property type.is_multibooleanWhether the property accepts more than one value, for example a multi-select severity list, a set of assignable reviewers, or several linked work items.
is_requiredbooleanWhether a value must be present. Turning this on for an existing property affects work items edited from then on. It does not backfill values on existing work items.
is_activebooleanWhether the property is currently offered. Deactivating is the reversible alternative to deleting: the definition and its recorded values stay, and the field is no longer offered on new edits.
default_valuearray of stringThe value applied when none is supplied. Always an array, even for a single-valued property: a decimal that defaults to
3is["3"], not3.optionsarray of anyFor
OPTIONproperties, the resolved list of choices. Each entry is a property option object with the same fields as a property option read. Manage them through Property options, or define them inline when you create the property.settingsanyFree-form object holding type-specific configuration. What it contains depends on
property_type. Treat it as opaque unless you wrote the value yourself.validation_rulesanyFree-form object holding type-specific validation constraints. As with
settings, the shape depends on the type, so read and write it as a whole instead of assuming keys.logo_propsanyIcon configuration used when rendering the property. Read-only through this API.
external_id,external_sourcestringCorrelation fields for sync and import. Together they let you map a property to a field in another system and find it again later.
created_atstring (date-time)When the property was created.
updated_atstring (date-time)When the property was last updated.
updated_by_idstring (uuid) or nullThe user who last updated the property.
nulluntil someone updates it.
display_name writes, name reads
These are two different fields, and mixing them up is the most common first error. You send display_name on create; Plane derives name from it and returns both. There is no name field in a request body.
{
"id": "9d2f0b74-6a51-4c8e-b3d7-2f1a8c05e964",
"name": "severity",
"display_name": "Severity",
"description": "How badly this affects customers",
"property_type": "OPTION",
"relation_type": null,
"is_multi": false,
"is_required": true,
"is_active": true,
"default_value": [],
"options": [
{
"id": "3e7a5c19-42b8-4d06-9f3e-7c1b8a0d2456",
"name": "Critical",
"description": "Production is down",
"parent_id": null,
"is_default": false,
"is_active": true,
"sort_order": 15000,
"logo_props": {},
"external_id": null,
"external_source": null,
"updated_at": "2026-01-14T09:22:41.478363Z",
"updated_by_id": "16c61a3a-512a-48ac-b0be-b6b46fe6f430"
},
{
"id": "b6c04f83-1d29-4e57-8a3b-90e2f5c7d418",
"name": "Major",
"description": "A core workflow is broken",
"parent_id": null,
"is_default": true,
"is_active": true,
"sort_order": 25000,
"logo_props": {},
"external_id": null,
"external_source": null,
"updated_at": "2026-01-14T09:22:41.478363Z",
"updated_by_id": "16c61a3a-512a-48ac-b0be-b6b46fe6f430"
}
],
"settings": {},
"validation_rules": {},
"logo_props": {},
"external_id": null,
"external_source": null,
"created_at": "2026-01-14T09:22:41.478363Z",
"updated_at": "2026-01-14T09:22:41.478363Z",
"updated_by_id": null
}Property type reference
property_type is required on create and sets what the field can hold. The Value shape column describes the value the property carries. default_value uses the same shape, always wrapped in an array.
property_type | What it is | Value shape |
|---|---|---|
TEXT | Free-form text | A string, for example ["Needs a repro"]. |
DATETIME | A point in time | An ISO 8601 timestamp, for example ["2026-03-01T00:00:00Z"]. |
DECIMAL | A number | The number expressed as a string, for example ["3"] or ["12.5"]. |
BOOLEAN | A yes/no flag | ["true"] or ["false"]. |
OPTION | A choice from a fixed set | One of the property's defined options. With is_multi, several of them. |
RELATION | A reference to a record | The referenced record, with relation_type deciding what kind. See below. |
URL | A link | A URL string, for example ["https://example.com/spec"]. |
EMAIL | An email address | An address string, for example ["ana@example.com"]. |
FILE | An uploaded file | A reference to the stored file. |
FORMULA | A computed value | Computed by Plane, not entered by a person. Its configuration is per type. |
relation_type
relation_type is only meaningful when property_type is RELATION. It is null on every other property.
relation_type | Points at |
|---|---|
ISSUE | A work item |
USER | A member |
RELEASE | A release |
RICH_TEXT | Rich text content |
Endpoints
| Method | Path | Description |
|---|---|---|
GET | /api/v2/workspaces/{slug}/projects/{project_id}/work-item-properties/ | List work item properties |
GET | /api/v2/workspaces/{slug}/projects/{project_id}/work-item-properties/{pk}/ | Get a work item property |
POST | /api/v2/workspaces/{slug}/projects/{project_id}/work-item-properties/ | Create a work item property |
PATCH | /api/v2/workspaces/{slug}/projects/{project_id}/work-item-properties/{pk}/ | Update a work item property |
DELETE | /api/v2/workspaces/{slug}/projects/{project_id}/work-item-properties/{pk}/ | Delete a work item property |
Attaching a property to a type
Creating a property defines the field, but nobody can fill it in yet. Attaching it to a work item type makes it appear on work items.
- Create the property with Create a work item property.
- Attach it to a type with Attach a type property.
The same property can be attached to more than one type, which is why the two steps are separate.
Defining options
OPTION properties need choices. You can define them in two ways:
- Pass an
optionsarray in the create or update body to define the choices in the same request.optionsis write-only: you send it, and the response returns the resolvedoptionsarray instead. - Create the property first, then add choices one at a time through Property options. Use this when options change over the life of the property.
Deactivate before you delete
is_active: false stops a property from being offered without removing it. Deleting permanently removes the definition and its options. If you are retiring a field but still need to read historical values, deactivate it.

