Trello Developers

Getting Started With Custom Fields

Get started with the Custom Fields API

Below is a guide for working with Custom Fields on Trello. The full REST API for Custom Fields is documented here.

Background

Custom Fields was initially a Power-Up that allowed users to create dynamic, custom fields on their cards for storing extra data relative to a card. For instance, software development teams could add a custom field to track the version number for a card. The original Custom Fields Power-Up embedded the field definition and values in the pluginData for cards and boards. However, this meant that the data couldn't be updated by third-party applications nor were webhooks available for when there were updates.

Now custom fields is a core component of the Trello API and the new Custom Fields Power-Up makes use of the API instead of pluginData. This means that Trello users can continue to add fields and data to their boards, as needed, and third-party integrations have full CRUD access to the data, as well as webhooks for them!

Additionally, the Custom Fields Power-Up will be available on all Trello clients!

Quick Overview

  • Custom fields require that the Custom Fields Power-Up be enabled.
  • Custom field definitions exist at the board level.
  • Values for definitions are set on cards within the board via customFieldItems.
  • Each card may have up to one customFieldItem per custom field on a board.
  • Custom Fields can have one of five types and the API validates inputs against those types.
  • The same custom field can exist across boards and Trello attempts to de-duplicate values when appropriate.
  • Webhooks are enabled for custom fields and there are specific custom field actions that will be sent to webhooks set on boards and cards with custom fields.

Custom Fields On Boards

Get Custom Fields On A Board

You can see all of the custom fields that belong to a board by including customFields as a URL parameter when querying the boards resource:

curl https://api.trello.com/1/boards/59e63d2744bf34022856c04a/customFields?key={APIkey}&token={APItoken}

If a custom field exists on the board you'll get a response similar to this one:

[
  {
    "id": "5a6a23abf958725e1ac86c21",
    "idModel": "5a00adcebe1991022b4a4bb4",
    "modelType": "board",
    "fieldGroup": "a18e01ef877d1dba894dfce28e4aee373bd384a458417ab0558d1058825d3d91",
    "name": "My Dropdown",
    "pos": 49152,
    "options": [
      {
        "id": "5a6a23abf958725e1ac86c23",
        "idCustomField": "5a6a23abf958725e1ac86c21",
        "value": {
          "text": "First Option"
        },
        "color": "none",
        "pos": 16384
      },
      {
        "id": "5a6a23abf958725e1ac86c22",
        "idCustomField": "5a6a23abf958725e1ac86c21",
        "value": {
          "text": "Second Option"
        },
        "color": "none",
        "pos": 32768
      },
    ],
    "type": "list"
  }
]

If the Custom Fields Power-Up is disabled on the board, you will get back an empty array regardless of whether or not the board has custom fields.

The definition above tells us that there is a single custom field defined for this board. It has a type of list which means that it also has a set of options from which the values of customFieldItems must come. customFieldItems and other custom field types are outlined further down in this guide.

Don't panic if you don't see anything returned when you look for custom fields data on one of your boards. We'll walk through creating and then updating the custom field above in this guide!

Create Custom Field On A Board

Let's assume you don't have a custom field on a board yet, though. However, you'd like to add one similar to the example above. You can create a new custom field by POSTing to the /1/customFields endpoint:

curl -X POST -H "Content-Type: application/json" \
https://api.trello.com/1/customFields \
-d '{
  idModel: "5a00adcebe1991022b4a4bb4",
  modelType: "board",
  name: "My Dropdown",
  options: [,
    {
      color: "none",
      value: {
        text: "First Option"
      }, 
      pos: 1024
    },
    {
      color: "none",
      value: {
        text: "Second Option"
      }, 
      pos: 2048
    }
  ],
  pos: "bottom",
  type: "list"
}'

The POST request includes the ID of the board (via idModel) on which the custom field should be created. It additionally sets the type, and, if applicable, the options. Here's the response:

{
  "id": "5a6a2154751b045645255afd",
  "idModel": "5a00adcebe1991022b4a4bb4",
  "modelType": "board",
  "fieldGroup": "cd1bcb6b508ae631db98d9eae556a793ea34fa3fd2748e8a4085d705d4af1984",
  "name": "checkbox3",
  "pos": 16384,
  "type": "checkbox"
}

If the Custom Fields Power-Up is disabled on the board you are trying to create a custom field on, you will get back a 403 - forbidden when making the POST request. The error message will be: Custom Fields Power-Up disabled for board

Parameter Overview

Below is an overview of the parameters that can be used when POSTing and PUTting to 1/customFields:

Key
Valid Values
Description

idModel
required

Valid ID of object.

The ID of the model to which the custom field should be attached. This should always be a board ID.

modelType
required

board is only valid value

The type of model idModel references. This can only be board.

name
required

String

The name of the custom field to be displayed to the user.

options

Array of objects.

See below for more details on options. Only available for list type fields.

type
required

One of: checkbox, date, list, number, text

See below for more details on type values and their meaning.

pos

One of: top, bottom, or a positive integer.

Determines the position of the custom field when viewing all custom fields for a board.

Custom Fields and Options

Custom fields of type list make use of the options key. Options are used when there is a pre-defined set of values to be used with the field. The user will be shown a dropdown populated with the option values as seen below:

Types of Custom Fields

There are six types of custom fields that you can create. Each type of custom field has validation on the server and clients for the values given.

Custom Field Type
Value Type
About

checkbox

boolean

Displayed to the user as a checkbox that they can check and uncheck.

date

ISO Formatted Datetime String

Text input box is displayed to the user that includes validation for ISO dates.

list

Object

Makes use of the options field. Read more about adding options below.

number

number

Text input box is displayed to the user that includes validation.

text

string

Text input box is displayed to the user.

Adding an Option To A Custom Field

Let's look at adding a new option to the custom field we created above:

curl -X POST -H "Content-Type: application/json" \ https://api.trello.com/1/customField/5a6a23abf958725e1ac86c21/options \ 
-d '{
  pos: "bottom",
  value: {
  	text: "Third Option"
  },
}'

And we get back the new option in the response:

{
  "id": "5a6a2799f958725e1ac86c7a",
  "idCustomField": "5a6a23abf958725e1ac86c21",
  "value": {
    "text": "Third Option"
  },
  "color": "none",
  "pos": 49152
}

Updating An Option On A Custom Field

Options are mutable and can be updated via PUT requests. Here we want to change the value of the option we just created:

curl -X PUT -H "Content-Type: application/json" \ https://api.trello.com/1/customField/5a6a23abf958725e1ac86c21/options/5a6a2799f958725e1ac86c7a \ 
-d '{
  "value": { "text": "Second-er Option" }
}'

Just like when we created a new option, the response to updating an option includes the changed option:

{
  "id": "5a6a2799f958725e1ac86c7a",
  "idCustomField": "5a6a23abf958725e1ac86c21",
  "value": {
    "text": "Second-er-er Option"
   },
   "color": "none",
   "pos": 49152
}

Get All Custom Field Definitions On A Board

To see all of the custom fields that have been defined for a board you can include customFields=true as a query parameter to the /1/boards/{idBoard} resource:

curl https://api.trello.com/1/boards/5a00adcebe1991022b4a4bb4/customFields&key={APIKey}&token={APIToken}

You'll receive the definitions for all custom fields on the board:

[
  {
    "id": "5a6a23abf958725e1ac86c21",
    "idModel": "5a00adcebe1991022b4a4bb4",
    "modelType": "board",
    "fieldGroup": "a18e01ef877d1dba894dfce28e4aee373bd384a458417ab0558d1058825d3d91",
    "name": "My Dropdown",
    "pos": 49152,
    "options": [
      {
        "id": "5a6a23abf958725e1ac86c23",
        "idCustomField": "5a6a23abf958725e1ac86c21",
        "value": {
          "text": "First Option"
        },
        "color": "none",
        "pos": 16384
      },
      {
        "id": "5a6a23abf958725e1ac86c22",
        "idCustomField": "5a6a23abf958725e1ac86c21",
        "value": {
          "text": "Second Option"
        },
        "color": "none",
        "pos": 32768
      },
      {
        "id": "5a6a2799f958725e1ac86c7a",
        "idCustomField": "5a6a23abf958725e1ac86c21",
        "value": {
          "text": "Second-er-er Option"
        },
        "color": "none",
        "pos": 49152
      }
    ],
    "type": "list"
  }
]

You can also get all of the custom field definitions as a nested resource on the boards endpoint by including customFields=true as a query parameter.

curl https://api.trello.com/1/boards/5a00adcebe1991022b4a4bb4/?customFields=true&key={APIKey}&token={APIToken}
{
  "id": "5a00adcebe1991022b4a4bb4",
  "name": "Test Board",
  ...
  "customFields": [
    {
      "id": "5a6a23abf958725e1ac86c21",
      "idModel": "5a00adcebe1991022b4a4bb4",
      "modelType": "board",
      "fieldGroup": "a18e01ef877d1dba894dfce28e4aee373bd384a458417ab0558d1058825d3d91",
      "name": "My Dropdown",
      "pos": 49152,
      "options": [
        {
          "id": "5a6a23abf958725e1ac86c23",
          "idCustomField": "5a6a23abf958725e1ac86c21",
          "value": {
            "text": "First Option"
          },
          "color": "none",
          "pos": 16384
        },
        ...
      ],
      "type": "list"
    }
  ]
}

Deleting Custom Fields

curl -X DELETE https://api.trello.com/1/customFields/5a6a23abf958725e1ac86c21?key={APIKey}&token={APIToken}

And we get back an empty object in the response - {}.

Deleting a custom field definition will also delete all of the values across all cards that have been set for that custom field. There is no way to get those values back after they have been deleted.

Custom Field Values On Cards

Alright, we've covered managing custom field definitions at the board level. What good is a custom field that doesn't have cards making use of it?

Now we'll cover how to assign values to cards for the definitions. Each card on a board on which custom field definitions exist may set a value for each custom field. The relationship between the value set on the card and the custom field is contained within the customFieldItem object.

Getting customFieldItems For Cards

You can get all of cards along with their customFieldItems via the following request:

curl https://api.trello.com/1/boards/5a00adcebe1991022b4a4bb4/cards/?fields=name&customFieldItems=true&key={APIKey}&token={APIToken}

But since we haven't set any values for our Custom Fields, the customFieldItems array is empty:

[
  {
    "id": "5a00add3be1991022b4a4bde",
    "name": "Card 1`",
    "customFieldItems": []
  },
  {
    "id": "5a4d294ff7239936994177f3",
    "name": "Card 2",
    "customFieldItems": []
  }
]

Get CustomFieldItem For Single Card

We can also get the customFieldItem for a single card by making a GET request to the /1/cards/{cardId} endpoint and passing in the parameter customFieldItems=true:

curl -X GET -H "Content-Type: application/json" \
https://api.trello.com/1/cards/5a4d294ff7239936994177f3/?fields=name&customFieldItems=true/

This will return all of the customFieldItems that have been set for the card:

{
  "id": "5a4d294ff7239936994177f3",
  "name": "Card 2",
  "customFieldItems": [
    {
      "id": "5a6a3608f958725e1ac86cb5",
      "idValue": "5a6a23abf958725e1ac86c23",
      "idCustomField": "5a6a23abf958725e1ac86c21",
      "idModel": "5a4d294ff7239936994177f3",
      "modelType": "card"
    }
  ]
}

Setting & Updating CustomFieldItems

We can set or update the value for a single card by making a PUT request to the customFieldItem endpoint. In the case of our list custom field, we'll change the idValue to be a different option:

curl -X PUT -H "Content-Type: application/json" \
https://api.trello.com/1/card/5a4d294ff7239936994177f3/customField/5a6a23abf958725e1ac86c21/item \
-d '{
  "idValue": "5a6a23abf958725e1ac86c22",
  "key": "",
  "token": ""
}'

Similar to adding a custom field value above, were this a type other than list we could pass in a value key containing the new value for the card:

All Values Are Strings

Even though there are many types of custom fields, they all expect the value to be a string.

// Custom Field Type - Text
{
  "value": { "text": "Hello, world!" }
}

// Custom Field Type - Number
{
  "value": { "number": "42" }
}

// Custom Field Type - Date
{
  "value": { "date": "2018-03-13T16:00:00.000Z" }
}

// Custom Field Type - Checkbox
{
  "value": { "checked": "true" }
}

Clearing CustomFieldItems

You can't make a DELETE request to any custom field item. You can only clear out a card's custom field item value with an empty PUT request:

curl -X PUT -H "Content-Type: application/json" \
https://api.trello.com/1/card/5a300b5036c4681398d3dab1/customField/5a6a23abf958725e1ac86c21/item \
-d '{
	"idValue": "",
  "value": "",
  "key": "",
  "token": ""
}'

And we get back an empty object in response - {}.

Getting field definitions and card values together

Sometimes you want to know the values on a card as well as the definitions of the fields. This way you don't have to ask to see if a card has a value, and if it does, then go figure out the definition that the value belongs to. We've packaged this all together so you only have to look in one place for each card.

This only works with the cards= filter parameter as that is what triggers the cards to be included.

curl https://api.trello.com/1/boards/5a00adcebe1991022b4a4bb4/?fields=name&cards=visible&card_fields=name&customFields=true&card_customFieldItems=true&key={APIKey}&token={APIToken}

And our response:

{
    "id": "5a00adcebe1991022b4a4bb4",
    "name": "ok",
    "cards": [
        {
            "id": "5a00add3be1991022b4a4bde",
            "name": "Card 1",
            "customFieldItems": []
        },
        {
            "id": "5a300b5036c4681398d3dab1",
            "name": "Card 2",
            "customFieldItems": [
                {
                    "id": "5a6a3988f958725e1ac86d20",
                    "idValue": "5a6a23abf958725e1ac86c22",
                    "idCustomField": "5a6a23abf958725e1ac86c21",
                    "idModel": "5a300b5036c4681398d3dab1",
                    "modelType": "card"
                }
            ]
        }
    ],
    "customFields": [
        {
            "id": "5a6a23abf958725e1ac86c21",
            "idModel": "5a00adcebe1991022b4a4bb4",
            "modelType": "board",
            "fieldGroup": "a18e01ef877d1dba894dfce28e4aee373bd384a458417ab0558d1058825d3d91",
            "name": "My Dropdown",
            "pos": 49152,
            "options": [
                {
                    "id": "5a6a23abf958725e1ac86c23",
                    "idCustomField": "5a6a23abf958725e1ac86c21",
                    "value": {
                        "text": "First Option"
                    },
                    "color": "none",
                    "pos": 16384
                },
                {
                    "id": "5a6a23abf958725e1ac86c22",
                    "idCustomField": "5a6a23abf958725e1ac86c21",
                    "value": {
                        "text": "Second Option"
                    },
                    "color": "none",
                    "pos": 32768
                },
                {
                    "id": "5a6a2799f958725e1ac86c7a",
                    "idCustomField": "5a6a23abf958725e1ac86c21",
                    "value": {
                        "text": "Second-er Option"
                    },
                    "color": "none",
                    "pos": 49152
                }
            ],
            "type": "list"
        }
    ]
}

Custom Fields Webhooks & Actions

Below is a list of the actions created that relate to custom fields. Additionally, the columns on the right indicate whether a webhook on a board or card will receive the different types of actions.

Action Type
Trigger
Board Webhook
Card Webhook

addCustomField

When a custom field is created on a board. Fires on a board.

Yes

No

deleteCustomField

When a custom field is removed from a board. Fires on a board.

Yes w/ option

Yes w/o option

No

updateCustomField

Yes

No

updateCustomFieldItem

When a custom field item is updated

Yes

Yes

Custom Field Limits

A board can have up to 50 Custom Fields defined on a board. Any number of cards on the board can have values set for each field.

Grouping Custom Fields Across Boards

In order for us to accommodate grouping field values across boards, we needed a way to determine whether or not "different" custom fields should be considered the "same". We have proposed a "matching" logic relies on a generating a unique hash property on the CustomField entity named fieldGroup. The hash (SHA256) is composed of the following custom field entity properties name, and type. The hash is generated when a field is created and re-generated when the field is updated. By comparing the hashes of two fields, we can roughly determine whether the fields are similar enough that we would consider them the same.

Moving and Copying Boards and Cards With Custom Fields

When copying or moving cards with Custom Fields between boards, we first check whether or not a "matching" field exists on the destination board. We check for a matching field by comparing hashes as described in the section above. If the field does not exist on the destination board, we create a new custom field on that board. The custom field items from the source card will be recreated on the destination card and they will reference the new custom field we just created.

If the field does exist, we will create new custom fields items on the destination card and they will reference the existing field on that board. In cases where the custom field is of list type, we try our best to merge the necessary option values. For instance, imagine a field that contains the options [ 1, 2, 3 ] and a corresponding field item on a card that has 2 selected; the matching destination field has the options [ 3, 4, 5 ]. In this case, one new CustomFieldOption will be added to the destination field with a value of 2, resulting in the set [ 2, 3, 4, 5 ].

As with card actions, we will not move the action history between boards.

Best Practices

Keep in mind that multiple integrations may be making use of the custom fields API and naming collisions can happen easily (everyone wants to add a "Start Date" field!). Your integration should use appropriate naming of field definitions. As always, you should also not take actions that are unexpected or confusing to the user - do your best to use the new custom fields API to provide delight!

Getting Started With Custom Fields

Get started with the Custom Fields API