Custom Fields, Values & Tags
Custom fields, custom values, and tags let you extend and label the data in your SMBcrm account without changing your data model. Custom fields attach structured data, like a referral source or preferred contact method, to records such as contacts, opportunities, and custom objects. Custom values are reusable snippets you can drop into templates and messages. Tags are simple labels you can filter and automate on.
Base URL: https://services.smbcrm.com · Version header: v3 ·
Scopes: locations/customFields.readonly, locations/customFields.write,
locations/customValues.readonly, locations/customValues.write, locations/tags.readonly,
locations/tags.write. See Scopes.
Custom values, tags, and contact and opportunity custom fields take your account/location ID
as a path segment, as described in Base URL & Headers. The custom
object field endpoints vary: some take locationId as a query parameter, some as a body
field, and looking up or deleting a field by ID doesn’t need it at all. Each endpoint below
shows where it goes.
Contact and opportunity custom fields
Section titled “Contact and opportunity custom fields”Custom fields on contacts and opportunities live under your location ID. Set model to
contact or opportunity to choose which kind of record a field belongs to.
Add the optional model query parameter to filter the list: contact, opportunity, or
all.
curl "https://services.smbcrm.com/locations/<location_id>/customFields?model=contact" \ -H "Authorization: Bearer <token>" \ -H "Version: v3"{ "customFields": [ { "id": "<field_id>", "name": "Referral Source", "fieldKey": "contact.referral_source", "placeholder": "Where did they hear about us?", "dataType": "TEXT", "position": 0, "locationId": "<location_id>", "model": "contact" }, { "id": "<field_id_2>", "name": "Preferred Contact Method", "fieldKey": "contact.preferred_contact_method", "dataType": "SINGLE_OPTIONS", "position": 1, "picklistOptions": ["Email", "Phone", "SMS"], "picklistImageOptions": [], "isAllowedCustomOption": false, "locationId": "<location_id>", "model": "contact" } ]}Each field also returns the settings that apply to its type. Choice fields return
picklistOptions, picklistImageOptions, and isAllowedCustomOption. File fields return
isMultiFileAllowed and maxFileLimit. Fields with validation or display settings return
urlValidation, dateTimeValidation, userFieldConfig, or optionDisplayType, described
under Data types and settings.
id can be the field’s ID or its field key, such as contact.referral_source.
curl https://services.smbcrm.com/locations/<location_id>/customFields/<field_id> \ -H "Authorization: Bearer <token>" \ -H "Version: v3"{ "customField": { "id": "<field_id>", "name": "Referral Source", "fieldKey": "contact.referral_source", "placeholder": "Where did they hear about us?", "dataType": "TEXT", "position": 0, "locationId": "<location_id>", "model": "contact" }}name and dataType are required. All other properties are optional.
| Property | Type | Description |
|---|---|---|
name |
string | Display name of the field. Required. |
dataType |
string | One of the data types. Required. |
model |
string | contact or opportunity. |
placeholder |
string | Placeholder text shown in the field. |
position |
number | Position of the field in the list. Defaults to 0. |
acceptedFormat |
array of strings | File extensions a FILE_UPLOAD field accepts, such as .pdf, .docx, and .jpeg. |
isMultipleFile |
boolean | Whether a FILE_UPLOAD field takes more than one file. |
maxNumberOfFiles |
number | Maximum number of files for a FILE_UPLOAD field. |
textBoxListOptions |
array | Entries for a TEXTBOX_LIST field, each as { label, prefillValue }. |
urlValidation |
object | URL rules. Required when dataType is URL. |
dateTimeValidation |
object | Date and time rules. Required for TIME and DATE_TIME, optional for DATE. |
userFieldConfig |
object | User field settings. Required when dataType is USER. |
optionDisplayType |
string | How RADIO and CHECKBOX options render. Defaults to TEXT_ONLY. |
curl -X POST https://services.smbcrm.com/locations/<location_id>/customFields \ -H "Authorization: Bearer <token>" \ -H "Version: v3" \ -H "Content-Type: application/json" \ -d '{ "name": "Referral Source", "dataType": "TEXT", "model": "contact", "placeholder": "Where did they hear about us?" }'{ "customField": { "id": "<field_id>", "name": "Referral Source", "fieldKey": "contact.referral_source", "placeholder": "Where did they hear about us?", "dataType": "TEXT", "position": 0, "locationId": "<location_id>", "model": "contact" }}name is required. You can also send placeholder, position, model, acceptedFormat,
isMultipleFile, maxNumberOfFiles, textBoxListOptions, urlValidation,
dateTimeValidation, userFieldConfig, and optionDisplayType. You can’t change a field’s
dataType after you create it. A urlValidation or dateTimeValidation object you send
replaces the existing rules, and multiSelect in userFieldConfig can’t change.
curl -X PUT https://services.smbcrm.com/locations/<location_id>/customFields/<field_id> \ -H "Authorization: Bearer <token>" \ -H "Version: v3" \ -H "Content-Type: application/json" \ -d '{ "name": "Referral Source", "placeholder": "How did they find us?" }'{ "customField": { "id": "<field_id>", "name": "Referral Source", "fieldKey": "contact.referral_source", "placeholder": "How did they find us?", "dataType": "TEXT", "position": 0, "locationId": "<location_id>", "model": "contact" }}curl -X DELETE https://services.smbcrm.com/locations/<location_id>/customFields/<field_id> \ -H "Authorization: Bearer <token>" \ -H "Version: v3"{ "succeded": true }The response uses the API’s own spelling, succeded, not succeeded.
Data types and settings
Section titled “Data types and settings”dataType is one of TEXT, LARGE_TEXT, NUMERICAL, PHONE, MONETORY (the API’s own
spelling), CHECKBOX, SINGLE_OPTIONS, MULTIPLE_OPTIONS, FLOAT, DATE, TEXTBOX_LIST,
FILE_UPLOAD, SIGNATURE, or RADIO. The types URL, USER, TIME, DATE_TIME, and
RICH_TEXT are Labs-only for now.
urlValidation
Section titled “urlValidation”Required when dataType is URL. On update, the object you send replaces the existing rules.
| Property | Type | Description |
|---|---|---|
mode |
string | allow_all accepts any URL, allow_only accepts only the allowedDomains, and block accepts anything except the blockedDomains. |
allowedDomains |
array of strings | Domains accepted when mode is allow_only. |
blockedDomains |
array of strings | Domains rejected when mode is block. |
dateTimeValidation
Section titled “dateTimeValidation”Required for TIME and DATE_TIME fields, and optional for DATE. On update, the object
you send replaces the existing rules.
| Property | Type | Description |
|---|---|---|
mode |
string | any allows any value, future_only requires a future value, past_only requires a past value, and range requires a value between rangeMin and rangeMax. |
bufferDays |
number | With future_only: the minimum number of days from today before a date can be selected. |
rollingDays |
number | With future_only: a rolling window in days from today, so 30 means the next 30 days. Can’t be combined with bufferDays. |
rangeMin |
string | An ISO date or datetime string. Required when mode is range. |
rangeMax |
string | An ISO date or datetime string. Required when mode is range. |
daysAllowed |
array of numbers | Days of the week that can be selected, from 0 (Sunday) to 6 (Saturday). Works with future_only, past_only, and range. |
inputType |
string | For DATE_TIME fields: date_only, time_only, or date_and_time. |
{ "dateTimeValidation": { "mode": "future_only", "bufferDays": 2, "daysAllowed": [1, 2, 3, 4, 5] }}userFieldConfig
Section titled “userFieldConfig”Required when dataType is USER. It has one property, multiSelect (boolean), which sets
whether the field is single-select or multi-select. You can’t change multiSelect after you
create the field.
optionDisplayType
Section titled “optionDisplayType”Sets how options render on RADIO and CHECKBOX fields: TEXT_ONLY, TEXT_WITH_ICON, or
TEXT_WITH_IMAGE. New fields default to TEXT_ONLY.
Upload files to a file field
Section titled “Upload files to a file field”Send the request as multipart/form-data with these form parts.
| Part | Description |
|---|---|
id |
The ID of the contact, opportunity, or custom field the files belong to. |
maxFiles |
The maximum number of files, as a string. |
Send each file as its own part, named after the file.
curl -X POST https://services.smbcrm.com/locations/<location_id>/customFields/upload \ -H "Authorization: Bearer <token>" \ -H "Version: v3" \ -F "id=<contact_id>" \ -F "maxFiles=2" \ -F "report.csv=@report.csv"uploadedFiles maps each file name to its URL, and meta lists the details of each upload.
{ "uploadedFiles": { "report.csv": "<file_url>" }, "meta": [ { "fieldname": "report.csv", "originalname": "report.csv", "encoding": "7bit", "mimetype": "text/csv", "size": 2061, "url": "<file_url>" } ]}Custom object fields
Section titled “Custom object fields”The /custom-fields/ endpoints manage fields on custom objects and on Company (Business)
records. For contact and opportunity fields, use the endpoints above. Fields can sit in
folders, and you create and manage those folders with the folder endpoints below. See
Custom Objects for the object schemas and records these
fields belong to.
Fields
Section titled “Fields”locationId is a required query parameter. The response has two arrays: fields holds the
object’s fields and folders holds its folders. Each folder includes id, locationId,
name, and objectKey.
curl "https://services.smbcrm.com/custom-fields/object-key/custom_objects.pet?locationId=<location_id>" \ -H "Authorization: Bearer <token>" \ -H "Version: v3"{ "fields": [ { "id": "<field_id>", "locationId": "<location_id>", "name": "Name", "fieldKey": "custom_object.pet.name", "dataType": "TEXT", "objectKey": "custom_object.pet", "parentId": "<folder_id>", "showInForms": true, "dateAdded": "2026-10-08T15:04:00.000Z", "dateUpdated": "2026-10-08T15:04:00.000Z" }, { "id": "<field_id_2>", "locationId": "<location_id>", "name": "Temperament", "fieldKey": "custom_object.pet.temperament", "dataType": "SINGLE_OPTIONS", "objectKey": "custom_object.pet", "parentId": "<folder_id>", "showInForms": true, "options": [ { "key": "calm", "label": "Calm" }, { "key": "playful", "label": "Playful" }, { "key": "shy", "label": "Shy" } ], "dateAdded": "2026-10-08T15:04:00.000Z", "dateUpdated": "2026-10-08T15:04:00.000Z" } ], "folders": [ { "id": "<folder_id>", "locationId": "<location_id>", "name": "Pet details", "objectKey": "custom_object.pet" } ]}curl https://services.smbcrm.com/custom-fields/<field_id> \ -H "Authorization: Bearer <token>" \ -H "Version: v3"{ "field": { "id": "<field_id>", "locationId": "<location_id>", "name": "Name", "fieldKey": "custom_object.pet.name", "dataType": "TEXT", "objectKey": "custom_object.pet", "parentId": "<folder_id>", "showInForms": true, "dateAdded": "2026-10-08T15:04:00.000Z", "dateUpdated": "2026-10-08T15:04:00.000Z" }}Send locationId, dataType, fieldKey, objectKey, parentId, and showInForms. All six
are required. parentId is the ID of the folder the field goes in. Folder IDs come from the
folders array when you list an object’s fields, or from creating a folder.
dataType is one of TEXT, LARGE_TEXT, NUMERICAL, PHONE, MONETORY (the API’s own
spelling), CHECKBOX, SINGLE_OPTIONS, MULTIPLE_OPTIONS, DATE, TEXTBOX_LIST,
FILE_UPLOAD, RADIO, or EMAIL.
| Property | Type | Description |
|---|---|---|
name |
string | Display name of the field. |
description |
string | Description of the field. |
placeholder |
string | Placeholder text shown in the field. |
options |
array | Choices for SINGLE_OPTIONS, MULTIPLE_OPTIONS, RADIO, CHECKBOX, and TEXTBOX_LIST fields. Each option is { key, label }, and key and label are both required. Other data types don’t use it. |
options[].url |
string | Optional. Valid only on RADIO options. |
allowCustomOption |
boolean | For RADIO fields: lets users enter a value that isn’t one of the predefined options. A custom value entered on one record doesn’t become an option on other records. |
acceptedFormats |
string | For FILE_UPLOAD fields: one of .pdf, .docx, .doc, .jpg, .jpeg, .png, .gif, .csv, .xlsx, .xls, or all. |
maxFileLimit |
number | For FILE_UPLOAD fields: the maximum number of files. |
curl -X POST https://services.smbcrm.com/custom-fields/ \ -H "Authorization: Bearer <token>" \ -H "Version: v3" \ -H "Content-Type: application/json" \ -d '{ "locationId": "<location_id>", "name": "Temperament", "dataType": "SINGLE_OPTIONS", "fieldKey": "custom_object.pet.temperament", "objectKey": "custom_object.pet", "parentId": "<folder_id>", "showInForms": true, "options": [ { "key": "calm", "label": "Calm" }, { "key": "playful", "label": "Playful" }, { "key": "shy", "label": "Shy" } ] }'To create a file field, send acceptedFormats and maxFileLimit instead of options:
curl -X POST https://services.smbcrm.com/custom-fields/ \ -H "Authorization: Bearer <token>" \ -H "Version: v3" \ -H "Content-Type: application/json" \ -d '{ "locationId": "<location_id>", "name": "Vaccination Records", "dataType": "FILE_UPLOAD", "fieldKey": "custom_object.pet.vaccination_records", "objectKey": "custom_object.pet", "parentId": "<folder_id>", "showInForms": true, "acceptedFormats": ".pdf", "maxFileLimit": 2 }'{ "field": { "id": "<field_id>", "locationId": "<location_id>", "name": "Temperament", "fieldKey": "custom_object.pet.temperament", "dataType": "SINGLE_OPTIONS", "objectKey": "custom_object.pet", "parentId": "<folder_id>", "showInForms": true, "options": [ { "key": "calm", "label": "Calm" }, { "key": "playful", "label": "Playful" }, { "key": "shy", "label": "Shy" } ], "dateAdded": "2026-10-08T15:04:00.000Z", "dateUpdated": "2026-10-08T15:04:00.000Z" }}locationId and showInForms are required. You can also send name, description,
placeholder, options, acceptedFormats, and maxFileLimit. dataType, fieldKey,
objectKey, and parentId can’t be changed after creation.
Sending options replaces the whole array, so include every existing option along with any
new ones. You can’t remove options through an update. Each option needs a key and a label.
curl -X PUT https://services.smbcrm.com/custom-fields/<field_id> \ -H "Authorization: Bearer <token>" \ -H "Version: v3" \ -H "Content-Type: application/json" \ -d '{ "locationId": "<location_id>", "name": "Temperament", "showInForms": true, "options": [ { "key": "calm", "label": "Calm" }, { "key": "playful", "label": "Playful" }, { "key": "shy", "label": "Shy" }, { "key": "anxious", "label": "Anxious" } ] }'{ "field": { "id": "<field_id>", "locationId": "<location_id>", "name": "Temperament", "fieldKey": "custom_object.pet.temperament", "dataType": "SINGLE_OPTIONS", "objectKey": "custom_object.pet", "parentId": "<folder_id>", "showInForms": true, "options": [ { "key": "calm", "label": "Calm" }, { "key": "playful", "label": "Playful" }, { "key": "shy", "label": "Shy" }, { "key": "anxious", "label": "Anxious" } ], "dateAdded": "2026-10-08T15:04:00.000Z", "dateUpdated": "2026-10-08T16:20:00.000Z" }}curl -X DELETE https://services.smbcrm.com/custom-fields/<field_id> \ -H "Authorization: Bearer <token>" \ -H "Version: v3"{ "succeded": true, "id": "<field_id>", "key": "custom_object.pet.temperament" }The response uses the API’s own spelling, succeded, not succeeded.
Folders
Section titled “Folders”Folders group an object’s fields in your custom field settings. A field’s parentId is the ID
of its folder.
objectKey, name, and locationId are all required.
curl -X POST https://services.smbcrm.com/custom-fields/folder \ -H "Authorization: Bearer <token>" \ -H "Version: v3" \ -H "Content-Type: application/json" \ -d '{ "objectKey": "custom_object.pet", "name": "Pet details", "locationId": "<location_id>" }'{ "id": "<folder_id>", "objectKey": "custom_object.pet", "locationId": "<location_id>", "name": "Pet details"}name and locationId are both required.
curl -X PUT https://services.smbcrm.com/custom-fields/folder/<folder_id> \ -H "Authorization: Bearer <token>" \ -H "Version: v3" \ -H "Content-Type: application/json" \ -d '{ "name": "Pet profile", "locationId": "<location_id>" }'{ "id": "<folder_id>", "objectKey": "custom_object.pet", "locationId": "<location_id>", "name": "Pet profile"}locationId is a required query parameter.
curl -X DELETE "https://services.smbcrm.com/custom-fields/folder/<folder_id>?locationId=<location_id>" \ -H "Authorization: Bearer <token>" \ -H "Version: v3"{ "succeded": true, "id": "<folder_id>", "key": "<folder_key>" }The response uses the API’s own spelling, succeded, not succeeded.
Custom values
Section titled “Custom values”Custom values are named snippets you define once in your account and reuse by name across
templates and messages. Typical examples are a business phone number, a support email
address, or a shipping cutoff time. Each custom value’s fieldKey is its merge tag, in the
form {{ custom_values.business_phone }}.
curl https://services.smbcrm.com/locations/<location_id>/customValues \ -H "Authorization: Bearer <token>" \ -H "Version: v3"{ "customValues": [ { "id": "<value_id>", "name": "Business Phone", "fieldKey": "{{ custom_values.business_phone }}", "value": "+15125550100", "locationId": "<location_id>" }, { "id": "<value_id_2>", "name": "Support Email", "fieldKey": "{{ custom_values.support_email }}", "value": "support@example.com", "locationId": "<location_id>" } ]}curl https://services.smbcrm.com/locations/<location_id>/customValues/<value_id> \ -H "Authorization: Bearer <token>" \ -H "Version: v3"{ "customValue": { "id": "<value_id>", "name": "Business Phone", "fieldKey": "{{ custom_values.business_phone }}", "value": "+15125550100", "locationId": "<location_id>" }}curl -X POST https://services.smbcrm.com/locations/<location_id>/customValues \ -H "Authorization: Bearer <token>" \ -H "Version: v3" \ -H "Content-Type: application/json" \ -d '{ "name": "Business Phone", "value": "+15125550100" }'{ "customValue": { "id": "<value_id>", "name": "Business Phone", "fieldKey": "{{ custom_values.business_phone }}", "value": "+15125550100", "locationId": "<location_id>" }}Both name and value are required. This endpoint replaces the whole custom value instead
of patching a single field.
curl -X PUT https://services.smbcrm.com/locations/<location_id>/customValues/<value_id> \ -H "Authorization: Bearer <token>" \ -H "Version: v3" \ -H "Content-Type: application/json" \ -d '{ "name": "Business Phone", "value": "+15125550199" }'{ "customValue": { "id": "<value_id>", "name": "Business Phone", "fieldKey": "{{ custom_values.business_phone }}", "value": "+15125550199", "locationId": "<location_id>" }}curl -X DELETE https://services.smbcrm.com/locations/<location_id>/customValues/<value_id> \ -H "Authorization: Bearer <token>" \ -H "Version: v3"{ "succeded": true }The response uses the API’s own spelling, succeded, not succeeded.
Tags are short labels you attach to contacts to segment lists and trigger automations. This section manages the tag definitions for your account; to add or remove a tag on a specific contact, use the tag endpoints on the Contacts API instead.
curl https://services.smbcrm.com/locations/<location_id>/tags \ -H "Authorization: Bearer <token>" \ -H "Version: v3"{ "tags": [ { "id": "<tag_id>", "name": "website-lead", "locationId": "<location_id>" }, { "id": "<tag_id_2>", "name": "vip", "locationId": "<location_id>" } ]}curl https://services.smbcrm.com/locations/<location_id>/tags/<tag_id> \ -H "Authorization: Bearer <token>" \ -H "Version: v3"{ "tag": { "id": "<tag_id>", "name": "website-lead", "locationId": "<location_id>" }}This endpoint returns 200, unlike the custom value and custom field create endpoints, which
return 201. Check for any 2xx status in your client.
curl -X POST https://services.smbcrm.com/locations/<location_id>/tags \ -H "Authorization: Bearer <token>" \ -H "Version: v3" \ -H "Content-Type: application/json" \ -d '{ "name": "webinar-2026" }'{ "tag": { "id": "<tag_id>", "name": "webinar-2026", "locationId": "<location_id>" }}curl -X PUT https://services.smbcrm.com/locations/<location_id>/tags/<tag_id> \ -H "Authorization: Bearer <token>" \ -H "Version: v3" \ -H "Content-Type: application/json" \ -d '{ "name": "webinar-2026-replay" }'{ "tag": { "id": "<tag_id>", "name": "webinar-2026-replay", "locationId": "<location_id>" }}curl -X DELETE https://services.smbcrm.com/locations/<location_id>/tags/<tag_id> \ -H "Authorization: Bearer <token>" \ -H "Version: v3"{ "succeded": true }The response uses the API’s own spelling, succeded, not succeeded.
Related
Section titled “Related”- Contacts: the
customFieldsarray you send when creating or updating a contact matches the fields you define here, and contacts carry the tags you define here. - Custom Objects: the custom object schemas and records that the custom object fields belong to.
- Locations: other account-level settings for your SMBcrm location.
- Scopes: the full list of scopes your token can request.
- Errors & Troubleshooting: status codes and error response shapes.
