Custom Fields API Reference
Set or clear one or more custom field values on existing LEAD, APPOINTMENT, CONTRACT, PAYMENT, or DELIVERY_ENGAGEMENT records.
Overview: Custom fields let your organization store additional structured data on records. Each field is defined once (as a CustomFieldDefinition) and then holds a per-record value.
This API exposes a single write endpoint: update the custom field values on a specific record. Reading custom field values is embedded in the list and detail responses of the relevant resource (leads, appointments, contracts, payments).
This API exposes a single write endpoint: update the custom field values on a specific record. Reading custom field values is embedded in the list and detail responses of the relevant resource (leads, appointments, contracts, payments).
Update Custom Field Values
Perform a partial merge update of custom field values. Only the fields explicitly provided in the request body are updated. Passing null for a custom field ID explicitly clears its stored value.
PATCH/api/external/custom-fields/:entity_type/:entity_id
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| entity_type | string (enum) | Required | The type of record to update: LEAD, APPOINTMENT, CONTRACT, PAYMENT, DELIVERY_ENGAGEMENT. |
| entity_id | string (UUID) | Required | The UUID of the record to update. Must be a valid UUID v4. |
Headers
Content-Type:application/json
x-api-key:sk_live_your_key_here
Request Body Format
The request body must contain a custom_fields object where the keys are custom field definition IDs (UUID/cuid) and the values represent the new data.
json
{
"custom_fields": {
"<custom_field_id>": "<value>",
"<custom_field_id_2>": null
}
}Expected Value Formats by Type
| Field Type | Expected Value Type in JSON | Notes / Description |
|---|---|---|
| TEXT | string | Short single-line text (e.g. "Acme Corp"). |
| LONG_TEXT | string | Multi-line text (e.g. "Multi-line text..."). |
| NUMBER | number | Integer or decimal (e.g. 42). |
| CURRENCY | number | Decimal amount in major units (e.g. 9997.50). |
| DATE | string | Date without time in YYYY-MM-DD format (e.g. "2026-03-15"). |
| DATETIME | string | Date and time in ISO 8601 UTC format (e.g. "2026-03-15T14:30:00.000Z"). |
| BOOLEAN | boolean | true or false. |
| SINGLE_SELECT | string | Must be one of the configured options (e.g. "Enterprise"). |
| MULTI_SELECT | string[] | Each element must be one of the configured options (e.g. ["Enterprise", "SaaS"]). |
| URL | string | Full URL including protocol (e.g. "https://example.com"). |
| string | Valid email address (e.g. "contact@example.com"). | |
| PHONE | object | Phone object matching {"e164": "+14155551234", "country": "US"}. |
Code Examples
curl -X PATCH "https://api.hermon.io/api/external/custom-fields/LEAD/cljk3x9a10001qz6z8h3f2b1a" \
-H "Content-Type: application/json"
-H "x-api-key: sk_live_your_key_here"
-d '{
"custom_fields": {
"cljk3z1b40002qz6znotes001": "Called back on Friday",
"cljk3z1b40002qz6zscore001": 87,
"cljk3z1b40002qz6zsource01": null
}
}'Response Example (200 OK)
On success, returns the updated record's full custom field state, excluding fields with visibility: ["NONE"].
json
{
"success": true,
"message": "Custom field values updated successfully",
"data": {
"entity_type": "LEAD",
"entity_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"custom_fields": [
{
"id": "cf_def_001",
"label": "Industry",
"type": "SINGLE_SELECT",
"options": ["Technology", "Finance", "Healthcare", "Other"],
"display_order": 0,
"visibility": ["LISTING", "DETAILS"],
"value": "Technology"
},
{
"id": "cf_def_002",
"label": "Annual Revenue",
"type": "CURRENCY",
"options": null,
"display_order": 1,
"visibility": ["DETAILS"],
"value": 150000
},
{
"id": "cf_def_003",
"label": "Product Type",
"type": "MULTI_SELECT",
"options": ["Enterprise", "SaaS", "SMB", "Agency"],
"display_order": 2,
"visibility": ["LISTING", "DETAILS"],
"value": ["Enterprise", "SaaS"]
},
{
"id": "cf_def_004",
"label": "Notes",
"type": "LONG_TEXT",
"options": null,
"display_order": 3,
"visibility": ["DETAILS"],
"value": null
}
]
}
}Values Reference
Entity Type Values
| Value | Description |
|---|---|
| LEAD | A lead record |
| APPOINTMENT | An appointment record |
| CONTRACT | A contract record |
| PAYMENT | A payment record |
| DELIVERY_ENGAGEMENT | A delivery engagement record |
Visibility Values
| Value | Description |
|---|---|
| LISTING | Field is shown in list/table views |
| DETAILS | Field is shown in the record detail view |
| NONE | Field is hidden in the UI (still readable and writable via API) |
Nested Objects Reference
Response Object Fields
| Field | Type | Description |
|---|---|---|
| entity_type | string (enum) | The entity type that was updated. |
| entity_id | string (UUID) | The record ID that was updated. |
| custom_fields | array | Full current state of all custom fields for this record after the update. See Custom Field Value Object. |
Custom Field Value Object Fields
| Field | Type | Description |
|---|---|---|
| id | string (UUID) | Custom field definition ID. Use this as the key in request body when updating values. |
| label | string | Human-readable field name (e.g. "Industry"). |
| type | string (enum) | Field type. See Field Type Values. |
| options | string[] | null | Allowed options for SINGLE_SELECT and MULTI_SELECT fields. null for other types. |
| display_order | integer | The display order of this field within its entity type (0-indexed). |
| visibility | string[] | Where the field appears in the platform UI. See Visibility Values. |
| value | mixed | Current value of the field. Type depends on type. null when not set. |
Reading Custom Field Values
Custom field values are embedded in the custom_fields array on every list item and detail response for resources that support them (Leads, Appointments, Contracts, Payments). Only fields with visibility of LISTING or DETAILS are included in API responses.
Error Responses
400Validation Failure / Unknown Custom Field
json
{
"success": false,
"message": "Descriptive error message"
}401Missing or invalid API key
json
{
"status": "error",
"message": "Invalid or revoked API key"
}404Resource not found / Scoped to another org
json
{
"status": "error",
"message": "Resource not found"
}429Rate limit exceeded
json
{
"status": "error",
"message": "Too many requests"
}