Multi-Select Field

Store multiple choices from a predefined list of options on a record with a SELECT_MULTI custom field.


A multi-select custom field stores one or more choices from a predefined list of options on a record. Use it for categories, skills, affected products, or any field where several values from a controlled set apply at once. Multi-select fields are CustomField objects with type: SELECT_MULTI; each choice is a CustomFieldOption, and records are Record objects in the API.

Custom fields are scoped to a workspace by the blue-workspace-id header, so you do not pass a project ID in the field input.

Overview

A SELECT_MULTI field is created in two steps: create the field, then add its options. Set a value on a record by referencing one or more option IDs. The value reads back as the selectedOptions array on the record’s CustomField.

Create

Create the field with createCustomField, then add options with createCustomFieldOptions. The field carries the SELECT_MULTI type; the options carry the titles and colors.

mutation CreateMultiSelectField {
  createCustomField(
    input: {
      name: "Required Skills"
      type: SELECT_MULTI
      description: "All skills this task needs"
    }
  ) {
    id
    name
    type
  }
}

Then add options in one call. createCustomFieldOptions takes a single CreateCustomFieldOptionsInput — the customFieldId lives on the wrapper, and each item in customFieldOptions is a CustomFieldOptionInput with no customFieldId of its own.

mutation AddOptions {
  createCustomFieldOptions(
    input: {
      customFieldId: "field_123"
      customFieldOptions: [
        { title: "JavaScript", color: "#f7df1e" }
        { title: "React", color: "#61dafb" }
        { title: "Node.js", color: "#339933" }
        { title: "GraphQL", color: "#e10098" }
      ]
    }
  ) {
    id
    title
    color
    position
  }
}

To add a single option to an existing field instead, use createCustomFieldOption, whose input does carry customFieldId:

mutation AddOneOption {
  createCustomFieldOption(
    input: { customFieldId: "field_123", title: "Python", color: "#3776ab" }
  ) {
    id
    title
    color
  }
}

CreateCustomFieldInput

ParameterTypeRequiredDescription
nameString!YesDisplay name of the field.
typeCustomFieldType!YesMust be SELECT_MULTI.
descriptionStringNoHelp text shown with the field.

CreateCustomFieldOptionsInput

Used by createCustomFieldOptions to add several options at once.

ParameterTypeRequiredDescription
customFieldIdString!YesThe SELECT_MULTI field the options belong to.
customFieldOptions[CustomFieldOptionInput!]!YesThe options to create.

CustomFieldOptionInput

Each item in customFieldOptions. Note there is no customFieldId here — it is set once on the wrapper.

ParameterTypeRequiredDescription
titleString!YesDisplay text for the option.
colorStringNoColor for the option (any string; not validated as hex).
positionFloatNoSort order; defaults to the end of the list.

CreateCustomFieldOptionInput

Used by createCustomFieldOption to add a single option. This input does carry customFieldId.

ParameterTypeRequiredDescription
customFieldIdString!YesThe field the option belongs to.
titleString!YesDisplay text for the option.
colorStringNoColor for the option (any string).
positionFloatNoSort order.

Set a value

Set the selected options on a record with setRecordCustomField, passing the option IDs in customFieldOptionIds. This replaces the record’s current selection. Pass an empty array to clear all selections.

mutation SetSkills {
  setRecordCustomField(
    input: {
      todoId: "todo_123"
      customFieldId: "field_123"
      customFieldOptionIds: ["option_123", "option_456"]
    }
  )
}

setRecordCustomField returns Boolean! — it does not return the updated field. Read the value back with a separate recordQueries { todos } query (see Read a value).

{ "data": { "setRecordCustomField": true } }

SetRecordCustomFieldInput

ParameterTypeRequiredDescription
todoIdString!YesThe record to update.
customFieldIdString!YesThe SELECT_MULTI field to set.
customFieldOptionIds[String!]NoOption IDs to select. Replaces the current selection; pass an empty array to clear.

You can also set the value at record creation time. In createRecord, the CreateRecordInputCustomField.value is a comma-separated string of option IDs (no spaces required; whitespace is trimmed) — the resolver splits it and matches the IDs against the field’s options.

mutation CreateRecordWithSkills {
  createRecord(
    input: {
      title: "Build the new feature"
      todoListId: "list_123"
      customFields: [{ customFieldId: "field_123", value: "option_123,option_456,option_789" }]
    }
  ) {
    id
    title
    customFields {
      name
      type
      selectedOptions {
        id
        title
        color
      }
    }
  }
}

Read a value

A record’s fields come back as Record.customFields, which is [CustomField!]! — there is no wrapper object. For a SELECT_MULTI field, read the chosen options from selectedOptions.

query GetRecordSkills {
  recordQueries {
    todos(filter: { companyIds: ["company_123"], todoListIds: ["list_123"] }) {
      items {
        id
        title
        customFields {
          name
          type
          selectedOptions {
            id
            title
            color
          }
        }
      }
    }
  }
}
{
  "data": {
    "recordQueries": {
      "todos": {
        "items": [
          {
            "id": "clm4n8qwx000008l0g4oxdqn7",
            "title": "Build the new feature",
            "customFields": [
              {
                "name": "Required Skills",
                "type": "SELECT_MULTI",
                "selectedOptions": [
                  { "id": "option_123", "title": "JavaScript", "color": "#f7df1e" },
                  { "id": "option_456", "title": "React", "color": "#61dafb" }
                ]
              }
            ]
          }
        ]
      }
    }
  }
}

CustomField (selected return fields)

FieldTypeDescription
idID!The field’s unique identifier.
nameString!Display name of the field.
typeCustomFieldType!SELECT_MULTI for a multi-select field.
customFieldOptions[CustomFieldOption!]All options defined on the field.
selectedOptions[CustomFieldOption!]The options chosen on this record.

CustomFieldOption

FieldTypeDescription
idID!The option’s unique identifier.
titleString!Display text for the option.
colorString!The option’s color.
positionFloat!Sort order within the field.

Manage options

Update an option with editCustomFieldOption. It identifies the option by customFieldId and optionId — there is no top-level id argument.

mutation RenameOption {
  editCustomFieldOption(
    input: {
      customFieldId: "field_123"
      optionId: "option_123"
      title: "TypeScript"
      color: "#3178c6"
    }
  ) {
    id
    title
    color
  }
}

Reorder options by editing their position (there is no dedicated reorder mutation). Use a fractional value to slot an option between two others:

mutation ReorderOption {
  editCustomFieldOption(
    input: { customFieldId: "field_123", optionId: "option_123", position: 1.5 }
  ) {
    id
    position
  }
}

Delete an option with deleteCustomFieldOption, identifying it by customFieldId and optionId. It returns Boolean!.

mutation DeleteOption {
  deleteCustomFieldOption(customFieldId: "field_123", optionId: "option_123")
}

EditCustomFieldOptionInput

ParameterTypeRequiredDescription
customFieldIdString!YesThe field the option belongs to.
optionIdString!YesThe option to edit.
titleStringNoNew display text.
colorStringNoNew color.
positionFloatNoNew sort order.

deleteCustomFieldOption arguments

ArgumentTypeRequiredDescription
customFieldIdString!YesThe field the option belongs to.
optionIdString!YesThe option to delete.
todoIdStringNoScope the delete to a single record’s selection rather than the option definition.

Notes

  • The value in createRecord is a comma-separated string of option IDs; setRecordCustomField and bulkSetCustomField take an array (customFieldOptionIds).
  • setRecordCustomField replaces the record’s full selection on each call — it is not additive. Send the complete set of option IDs you want, or an empty array to clear.
  • Option IDs must belong to the same field; unknown IDs cause the call to fail.
  • color accepts any string (no hex validation).

Errors

CodeWhen
CUSTOM_FIELD_NOT_FOUNDThe customFieldId does not exist in the workspace.
BAD_USER_INPUTAn option ID in customFieldOptionIds is unknown or does not belong to the field.
FORBIDDENThe caller cannot edit the field or the record’s value.