Below is a guide for working with Custom Fields on Trello. The full REST API for Custom Fields is documented here.
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!
customFieldItems
.customFieldItem
per custom field 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:
1 2curl 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:
1 2[ { "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 type
s 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!
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 POST
ing to the /1/customFields
endpoint:
1 2curl -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:
1 2{ "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
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 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:
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.
Key | Valid Values | Description |
---|---|---|
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. |
Let's look at adding a new option to the custom field we created above:
1 2curl -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:
1 2{ "id": "5a6a2799f958725e1ac86c7a", "idCustomField": "5a6a23abf958725e1ac86c21", "value": { "text": "Third Option" }, "color": "none", "pos": 49152 }
Options are mutable and can be updated via PUT requests. Here we want to change the value of the option we just created:
1 2curl -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:
1 2{ "id": "5a6a2799f958725e1ac86c7a", "idCustomField": "5a6a23abf958725e1ac86c21", "value": { "text": "Second-er-er Option" }, "color": "none", "pos": 49152 }
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:
1 2curl https://api.trello.com/1/boards/5a00adcebe1991022b4a4bb4/customFields&key={APIKey}&token={APIToken}
You'll receive the definitions for all custom fields on the board:
1 2[ { "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.
1 2curl https://api.trello.com/1/boards/5a00adcebe1991022b4a4bb4/?customFields=true&key={APIKey}&token={APIToken}
1 2{ "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" } ] }
1 2curl -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.
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.
You can get all of cards along with their customFieldItems
via the following request:
1 2curl 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:
1 2[ { "id": "5a00add3be1991022b4a4bde", "name": "Card 1`", "customFieldItems": [] }, { "id": "5a4d294ff7239936994177f3", "name": "Card 2", "customFieldItems": [] } ]
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
:
1 2curl -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:
1 2{ "id": "5a4d294ff7239936994177f3", "name": "Card 2", "customFieldItems": [ { "id": "5a6a3608f958725e1ac86cb5", "idValue": "5a6a23abf958725e1ac86c23", "idCustomField": "5a6a23abf958725e1ac86c21", "idModel": "5a4d294ff7239936994177f3", "modelType": "card" } ] }
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:
1 2curl -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:
Even though there are many types of custom fields, they all expect the value to be a string.
1 2// 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" } }
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:
1 2curl -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 - {}
.
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.
1 2curl 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:
1 2{ "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" } ] }
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 | No |
updateCustomField | Yes | No | |
updateCustomFieldItem | When a custom field item is updated | Yes | Yes |
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.
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.
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.
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!
Rate this page: