readyDocs Open the appOpen the app

Tags and custom fields

Tags and custom fields are how you sort and label your contacts. A tag is a short label, like vip. A custom field holds one value per contact, like a renewal date, and you can use it in a message as {{custom.<name>}}. To save a filter or read the values to filter by, see Saved views and filter helpers.

A team member limited to their assigned contacts only sees and changes their own and unassigned contacts on these routes.

#Tags

Tags are exact text, up to 64 characters, and case-sensitive: VIP isn’t vip. The Opted Out tag is managed by Ready, so you can’t add or remove it here. To set the tags of one contact, update the contact.

#List tags

Every tag on your contacts, A to Z. Tags an automation starts on ("contact tagged") are listed too, even before any contact has them. The list is cached and can be up to 5 minutes behind. Needs the view_contacts permission.

Parameters

with_countsstring · query
1 or true returns {tag, count} objects instead of plain names. count is how many contacts have the tag; an automation’s tag no contact has yet counts 0.

Returns a list of tag names (or {tag, count} objects) in data.

Errors
HTTPCodeWhen
500no codeWe couldn’t read your tags. Retry.

#Tag or untag many contacts

Adds one tag to, or removes it from, a set of contacts. Pick the contacts one way: by id, by assignee, by filter, or all of them. Sending it twice is safe: contacts that already match aren’t changed again. Tag automations and Zaps run for the contacts that changed. Needs the view_contacts and edit_contacts permissions.

Parameters

tagstringRequired
Trimmed and cut to 64 characters.
actionstringDefault add
add or remove. Leave it out to add. Any other value is refused with invalid_field.
contact_idsinteger[]Max 50,000
The contacts to change. Ids that aren’t valid are dropped.
assigned_tointeger
Every contact assigned to this team member.
filtersobject
Every contact that matches, using the filters of List contacts as keys, like {"tag": "trial", "state": "TX"}. Spam contacts are left out unless you send "include_spam": "1". A key that isn’t a filter is refused with unknown_filter, so a typo never matches every contact.
allboolean
true: every contact on your account. Use with care.

Send one of contact_ids, assigned_to, filters or all. If you send more than one, the first in that order wins.

Returns
action, tagstring
What was done, and the tag as saved.
updatedinteger
Contacts that changed.
undo_tokenstring | null
Reverses this change for 48 hours: POST /contacts/bulk-actions/<undo_token>/undo. null when nothing changed. Over 20000 contacts there is no undo: the answer is 202 with queued: true, job_id, action, tag and undo_unavailable: "selection_too_large", and the change runs in the background.
warning, warning_codestring
Only when we couldn’t check your automations and Zaps for this change. The tags are saved. warning_code is contact_events_queued.
Errors
HTTPCodeWhen
400tag_requiredNo tag.
400no codeThe tag is Opted Out, or filters can’t be read.
400selection_requiredNo contacts picked.
400no_valid_contactsNone of the contact_ids is a valid id.
400too_many_contactsMore than 50,000 contact_ids.
400invalid_fieldassigned_to is too large to be an id, or a field has the wrong type.
429rate_limitedOver about 120 bulk changes a minute per account.
500bulk_tag_failedThe change failed. Some contacts may be tagged; list them before you retry.

#Remove a tag from every contact

Takes one tag off every contact on your account that has that exact spelling. Sending it again changes nothing. undo_token puts the tag back for 48 hours. Needs the view_contacts and edit_contacts permissions.

Parameters

tagstring · pathRequired
The tag, URL-encoded: Spring%20promo.
Returns
removedinteger
Contacts the tag was removed from.
tagstring
The tag, as we read it.
undo_tokenstring | null
Puts the tag back on those contacts for 48 hours: POST /contacts/bulk-actions/<undo_token>/undo. null when nothing changed or more than 20000 contacts changed.
warning, warning_codestring
As in Tag or untag many contacts.
Errors
HTTPCodeWhen
400tag_requiredThe tag is blank.
400no codeThe tag is Opted Out.
500tag_delete_failedNothing was changed. Retry.

#Custom fields

A custom field is defined once for your account, then each contact can hold a value for it. Names are unique on your account, ignoring case and spaces: Renewal Date and renewal date are the same field. Values are stored as text. You can also set values by name with custom_fields when you update a contact. A value set by field id is what texts and filters use; the contact’s custom_fields can still show the earlier value, so read values with Get a contact’s custom field values.

#The custom field object

idinteger
The field id.
user_idinteger
Your account id.
namestring
The field’s name. In a message it’s {{custom.<name>}}, lowercase, with spaces as _.
field_typestring
Lowercase: text, number, date or dropdown. The type picks the input in the dashboard; values aren’t checked against it.
optionsstring | null
A dropdown’s choices, one per line.
required, position, group_name, placeholderboolean, integer, string, string
Not set by this API.
created_atstring
When the field was made, ISO 8601.

#List custom fields

Every custom field on your account, oldest first. Fields from a CSV import or a connected GoHighLevel account are added to the list first. Any team member can call it.

Returns a list of custom field objects in data.

Errors
HTTPCodeWhen
503no codeWe couldn’t read the fields, or fields from an import are still being added. Retry in a few seconds.

#Create a custom field

Adds a field. If you already have a field with that name, nothing changes and you get 200 with the list, so sending it twice is safe. Needs the edit_contacts permission.

Parameters

namestringRequired
Up to 128 characters. Can’t contain {, } or |.
field_typestringDefault text
Use text, number, date or dropdown. Other words are saved as given, in lowercase, and show as a text box.
optionsstring
For a dropdown: the choices, one per line. Up to 5000 characters.

Returns every custom field object on your account in data, the new one included.

Errors
HTTPCodeWhen
400no codeNo name, or the name has {, } or |.
400invalid_fieldA field isn’t text, or is too long.

#Update a custom field

Renames a field or changes its type or options. Always send name, even when it stays the same; field_type and options you leave out keep their value. Values on contacts are kept. Needs the edit_contacts permission, and a team member limited to their assigned contacts can’t.

Parameters

idinteger · pathRequired
namestringRequired
Same rules as when you create one.
field_typestring
Leave it out to keep the field’s type. Use text, number, date or dropdown.
optionsstring
For a dropdown: the choices, one per line. Leave it out to keep the current choices.

Returns every custom field object on your account in data.

Errors
HTTPCodeWhen
400no codeNo name, or the name has {, } or |.
400invalid_fieldThe id isn’t a whole number, or a field isn’t text or is too long.
403no codeYou only see your assigned contacts.
404CUSTOM_FIELD_NOT_FOUNDNo field with this id on your account.
409no codeAnother field already has this name.

#Delete a custom field

Deletes the field and every value saved for it. Values that came from a CSV import stay in the contact’s custom_fields, and an import or sync won’t add the field back. Creating it again does. Needs the edit_contacts permission, and a team member limited to their assigned contacts can’t.

Returns { "success": true }. Sending it again returns 404.

Errors
HTTPCodeWhen
400invalid_fieldThe id isn’t a whole number.
400unknown_fieldYou sent a body. This route takes none.
403no codeYou only see your assigned contacts.
404CUSTOM_FIELD_NOT_FOUNDNo field with this id on your account.

#Get a contact’s custom field values

The values saved on one contact. Fields with no value aren’t listed. A contact that isn’t on your account returns an empty list. Needs the view_contacts permission.

Parameters

contactIdinteger · pathRequired
Returns

A list in data, one item per value:

field_idinteger
The custom field’s id.
name, field_typestring
From the field.
valuestring
The value, as text.
Errors
HTTPCodeWhen
400invalid_fieldcontactId isn’t a whole number.
503no codeWe couldn’t read the values. Retry.

#Set a contact’s custom field values

Saves values by field id. Each value replaces the one saved; fields you don’t send are left alone. Sending it twice is safe. Needs the view_contacts and edit_contacts permissions.

Parameters

contactIdinteger · pathRequired
fieldsobject[]RequiredMax 500
Each is {"field_id": 31, "value": "2027-01-15"}. A value is text, a number or true/false, up to 2000 characters, and is saved as text. null saves an empty value.
Returns
skipped_field_idsinteger[]
Only when some ids aren’t fields on your account. Those weren’t saved; the rest were.
Errors
HTTPCodeWhen
400invalid_fieldcontactId isn’t a whole number, fields isn’t a list, an item isn’t an object, or a value is an object or list.
400no codeA value is over 2000 characters, or more than 500 items.
404CONTACT_NOT_FOUNDNo contact with this id on your account.