Skip to main content

Custom Fields

Custom fields let a firm store data Clio Manage doesn't model natively, such as a USCIS receipt number, a referral source, or an internal case code. They exist on matters and contacts, and they are one of the most common sources of "where is this field?" confusion in the API.

Most of that confusion comes down to two concepts that are easy to mix up:

  • A custom field is the definition: its name, the type of data it holds, and whether it applies to matters or contacts. Definitions have their own top-level endpoint (GET /api/v4/custom_fields.json). Firm administrators usually create them in account settings; see Get Started With Custom Fields on the product side.
  • A custom field value is the data stored in that field on a specific matter or contact. Values are not exposed at a top-level endpoint; they are accessed through the parent record, via the custom_field_values association on a matter or contact.

This guide covers working with both through the API: listing the fields defined in an account, reading and writing values on matters and contacts, handling picklist fields, and filtering records by a custom field's value. For the full endpoint reference, see the Custom Fields API reference.

Custom Fields vs. Custom Field Values

Custom field (definition)Custom field value
What it isThe field itself: name, type, and which record it applies toThe data stored in that field on one matter or contact
Where it livesThe custom_fields endpointThe custom_field_values association on a matter or contact
Key attributesid, name, field_type, parent_typeid (composite), value, custom_field
Who manages itFirm administrators, once per accountYour integration, per record

It is important to note the two kinds of id. The custom_field.id is a plain integer (for example, 55001) that identifies the field definition. The custom_field_value.id is a composite string (for example, text_line-982340) that identifies a value on a record. You use each in different places, described below.

Listing the Custom Fields in an Account

Before reading or writing values, you usually need to know which custom fields a firm has defined and their ids. List them with:

GET /api/v4/custom_fields.json

Working with the custom_fields endpoint requires the custom_fields access permission. If you're not sure whether your application has this scope, check your application settings in the Developer Portal.

Every custom field has a parent_type of either Matter or Contact, which determines the kind of record it applies to, and a field_type, which determines the shape of its values. Filter to one record type with the parent_type parameter:

GET /api/v4/custom_fields.json?fields=id,name,field_type,parent_type&parent_type=Matter

Field types

The field_type tells you what kind of data a field holds, which in turn tells you what to expect when reading a value and what to send when writing one:

field_typeHolds
text_lineA single line of text.
text_areaMultiple lines of text.
numericA whole, non-negative number (integer, 0 and up).
currencyA monetary amount.
dateA date (ISO-8601).
timeA time (ISO-8601).
checkboxA boolean.
picklistOne option from a predefined list. See Picklist, Matter, and Contact Fields.
contactA reference to a contact.
matterA reference to a matter.
emailAn email address.
urlA URL.

Custom field definitions are often created by firm administrators in Clio Manage; see Create Custom Fields in Clio Manage for that workflow.

Reading Custom Field Values

Custom field values are returned under the custom_field_values association, which is not included by default. Request it through the fields parameter, and because it is a nested association you select the sub-fields you want inside braces:

GET /api/v4/matters/{id}.json?fields=id,display_number,custom_field_values{id,field_name,field_type,value,custom_field}

The same association works on contacts:

GET /api/v4/contacts/{id}.json?fields=id,name,custom_field_values{id,field_name,field_type,value,custom_field}

A response looks like this:

{
"data": {
"id": 1001,
"display_number": "2024-001",
"custom_field_values": [
{
"id": "text_line-55001",
"field_name": "USCIS Receipt Number",
"field_type": "text_line",
"value": "MSC2490012345",
"custom_field": {
"id": 55001,
"etag": "12f7870682652de6a68f6d0d2c363349"
}
},
{
"id": "date-55002",
"field_name": "Filing Deadline",
"field_type": "date",
"value": "2025-03-31",
"custom_field": {
"id": 55002,
"etag": "12f7870682652de6a68f6d0d2c363349"
}
}
]
}
}

Two things to note about the value's id:

  • It is a composite string of the field type and the field's id (for example, text_line-55001), not a plain integer. You use this composite id to update or delete the value.
  • It can be null when a field is displayed on the record by default but has not been given a value yet. In that case there is nothing to update, so you create the value instead (see Setting and Updating Values).

The nested custom_field.id is the plain integer id of the field definition, which is what you use when setting a value for the first time.

If a record has many custom fields but you only care about a few, restrict which values are returned with custom_field_ids[], passing the plain field ids. This narrows the returned values without filtering the records themselves:

GET /api/v4/matters/{id}.json?fields=id,custom_field_values{id,field_name,value}&custom_field_ids[]=55001&custom_field_ids[]=55002

Picklist, Matter, and Contact Fields

Most field types store their value directly: a text_line returns the text, a date returns an ISO-8601 date. Three types are different because their value is a reference to something else, and for those the value is an id, not a display string:

  • picklist: value is the id of the selected picklist option.
  • matter: value is the id of the referenced matter.
  • contact: value is the id of the referenced contact.

For a picklist field, the available options are defined on the field itself, under picklist_options:

GET /api/v4/custom_fields/{id}.json?fields=id,name,field_type,picklist_options{id,option}
{
"data": {
"id": 55003,
"name": "Referral Source",
"field_type": "picklist",
"picklist_options": [
{ "id": 9001, "option": "Web" },
{ "id": 9002, "option": "Referral" },
{ "id": 9003, "option": "Existing Client" }
]
}
}

When you read a picklist value, the value is the option's id. To get the human-readable label in the same request, ask for the picklist_option sub-association, which pairs the id with its text:

GET /api/v4/matters/{id}.json?fields=id,custom_field_values{id,field_name,value,picklist_option}
{
"data": {
"id": 1001,
"custom_field_values": [
{
"id": "picklist-55003",
"field_name": "Referral Source",
"value": "9002",
"picklist_option": { "id": 9002, "option": "Referral" }
}
]
}
}

To set a picklist value, send the option's id as the value (see below). Matter and contact fields work the same way: send the referenced record's id as the value, and request the matter{...} or contact{...} sub-association to read details back.

Setting and Updating Values

Custom field values are written through the same custom_field_values association on a POST (create) or PATCH (update) to the matter or contact. The association takes a list, and each entry is one of three operations. For the product-side view of how these changes appear in Clio Manage, see Apply and Update Custom Fields in Clio Manage.

Set a value for the first time by passing the field definition's id under custom_field, along with the value:

{
"data": {
"custom_field_values": [
{ "custom_field": { "id": 55001 }, "value": "MSC2490012345" }
]
}
}

Update an existing value by passing its composite id (from a read) and the new value. You do not repeat custom_field here:

{
"data": {
"custom_field_values": [
{ "id": "text_line-55001", "value": "MSC2490099999" }
]
}
}

Remove a value by passing its composite id with _destroy set to true:

{
"data": {
"custom_field_values": [
{ "id": "text_line-55001", "_destroy": true }
]
}
}
A value with a null id

If you read a custom_field_value back and its id is null, the field exists on the record but has no value yet. To populate it, use the set form above (custom_field id plus value), not the update form.

These operations can be combined in a single request, and sent alongside other fields on the record. Send only the values you are changing; values you omit are left as they are.

Finding Records by Custom Field Value

To find matters or contacts by a custom field's value, rather than reading values off a single record, use the custom_field_values filter on the list endpoint. It is keyed by the field definition's plain integer id and takes the value to match:

GET /api/v4/matters.json?custom_field_values[55001]=MSC2490012345

The operators available depend on the field type:

Field typesSupported operators
text_line, text_area, email, url, picklist, checkbox, contact, matterEquality only (=)
numeric, currency, date, timeEquality and range comparisons (=, <, >, <=, >=)

To express a range, repeat the parameter once per condition:

GET /api/v4/matters.json?custom_field_values[55004]=>=45&custom_field_values[55004]=<=50

Remember that the list endpoint is paginated. To retrieve every matching record, follow the meta.paging.next URL until it is absent; see How do I retrieve all records across pages? for the full pattern.