This guide explains how to sync custom fields between Xurrent and remote systems using Exalate.
Overview
Xurrent custom fields are defined in UI Extensions attached to Request Templates. Each template can have its own set of custom fields with different types and validation rules.
Custom fields use the same .value syntax as other Exalate connectors:
entity.customFields."Field Name"?.value = <value> // incoming
replica.customFields."Field Name" = entity.customFields."Field Name" // outgoing
Values are validated against the template's field definitions when the request is written to Xurrent.
Prerequisites
- The API token needs the Request Template – Read and UI Extensions – Read permissions to read custom field definitions.
- When creating a request, set
entity.templateIdbefore setting custom fields. - When updating a request, the request's current template is used automatically. Set
entity.templateIdonly if you want to change the template.
Outgoing Sync (Xurrent → Remote System)
To send custom fields from Xurrent to the remote system:
// Send all custom fields
replica.customFields = entity.customFields
// Send specific custom fields by their display name (label) in Xurrent
replica.customFields."Distribution Center" = entity.customFields."Distribution Center"
replica.customFields."Story Points" = entity.customFields."Story Points"
// Access a custom field value directly
replica.myCustomValue = entity.customFields."Priority Level"?.value
Note: On the Xurrent side,
entity.customFieldsis keyed by the field's display name (label), for example"Story Points", not by its internal ID (story_points). Keys fall back to internal IDs only when the API token cannot read UI Extensions. The internal ID of a field is available asentity.customFields."Story Points"?.uid.
Converting Select Field IDs to Labels
Xurrent returns internal IDs for select field values (e.g., value_2). To get the display label:
def companyField = entity.customFields."Company"
def displayLabel = nodeHelper.getCustomFieldValueLabel(entity.templateId, companyField?.uid, companyField?.value)
// Returns: "Acme Corporation"
replica.companyName = displayLabel
Incoming Sync (Remote System → Xurrent)
To receive custom fields from the remote system and set them in Xurrent, assign the field's .value. The field can be referenced by its display name or its internal ID.
// On create, set the template first
entity.templateId = 12345
// Text / text area fields
entity.customFields."Description"?.value = "Task details here"
// Number fields
entity.customFields."Story Points"?.value = 5
entity.customFields."Cost Estimate"?.value = 1234.56
// Select fields (display label OR internal option ID)
entity.customFields."Priority"?.value = "High"
entity.customFields."Company"?.value = "value_1" // internal option ID also works
entity.customFields."story_points"?.value = 8 // internal field ID also works
// Date fields (YYYY-MM-DD)
entity.customFields."Due Date"?.value = "2025-12-31"
// DateTime fields (UTC)
entity.customFields."Meeting Time"?.value = "2025-12-31T14:30:00Z"
// Time fields (HH:mm)
entity.customFields."Start Time"?.value = "09:30"
// Email fields
entity.customFields."Contact Email"?.value = "john.doe@company.com"
// Rich text fields
entity.customFields."Custom Description"?.value = "**Bold** and __italic__ text"
entity.customFields."Custom Description"?.value = nodeHelper.convertWikiToXurrent(replica.description) // remote is Jira (wiki markup)
entity.customFields."Custom Description"?.value = nodeHelper.convertHtmlToXurrent(replica.description) // remote uses HTML
// Copy a value from the remote custom field
entity.customFields."Priority"?.value = replica.customFields."Priority"?.value
// Clear/reset a field (null or empty string)
entity.customFields."Optional Field"?.value = null
entity.customFields."Optional Field"?.value = ""
How it behaves
- Only fields whose value changed are sent to Xurrent. Reading a field in a script (for example in an
if) never writes or clears it. - Select labels are converted to internal option IDs, and numbers, dates, times and emails are validated, before the request is written. An invalid value fails the sync with one of the errors listed below.
- The same syntax works on both create and update.
Supported Field Types
| Type | Format | Example Value |
|---|---|---|
| text | Any string | "Task details here" |
| text area | Any multiline string | "Task details here for more details" |
| rich_text | Xurrent rich text format | "**bold** and __italic__" |
| number | Integer or decimal | 42 or 1234.56 |
| checkbox | Boolean value | true or false |
| select | Option label or internal ID | "High" or "value_1" |
| date | YYYY-MM-DD | "2025-12-31" |
| date_time | YYYY-MM-DDTHH:mm:ssZ (UTC) | "2025-12-31T14:30:00Z" |
| time | HH:mm | "09:30" |
| Valid email address | "user@example.com" |
Validation Rules and Expected Errors
Select Fields
Values must match an existing option (by label or internal ID).
// Valid
entity.customFields."Priority"?.value = "High"
entity.customFields."Priority"?.value = "value_1"
// Invalid - fails the sync
entity.customFields."Priority"?.value = "SuperHigh"
Error:
Invalid value 'SuperHigh' for custom field 'Priority'.
Available options: "Low" (id: value_1), "Medium" (id: value_2), "High" (id: value_3)
Number Fields
Values must be valid integers or decimals.
// Valid
entity.customFields."Points"?.value = 5
entity.customFields."Points"?.value = "5"
entity.customFields."Cost"?.value = 123.45
// Invalid - fails the sync
entity.customFields."Points"?.value = "five"
Error:
Invalid number value 'five' for custom field 'Points'.
Expected a valid number (integer or decimal).
Email Fields
Values must be valid email addresses.
// Valid
entity.customFields."Contact"?.value = "user@example.com"
// Invalid - fails the sync
entity.customFields."Contact"?.value = "not-an-email"
Error:
Invalid email format 'not-an-email' for custom field 'Contact'.
Expected a valid email address (e.g., user@example.com).
DateTime Fields
Values must be in UTC format: YYYY-MM-DDTHH:mm:ssZ
// Valid
entity.customFields."Meeting"?.value = "2025-12-31T14:30:00Z"
entity.customFields."Meeting"?.value = "2025-12-31T14:30:00.123Z"
// Invalid - fails the sync
entity.customFields."Meeting"?.value = "2025-12-31 14:30:00"
entity.customFields."Meeting"?.value = "12/31/2025"
Error:
Invalid datetime format '2025-12-31 14:30:00' for custom field 'Meeting'.
Expected UTC format: yyyy-MM-ddTHH:mm:ssZ (e.g., 2025-12-02T10:11:00Z).
Note: Xurrent expects datetime in UTC. The UI displays it in the user's timezone based on profile settings.
Date Fields
Values must be in format: YYYY-MM-DD
// Valid
entity.customFields."Due Date"?.value = "2025-12-31"
// Invalid - fails the sync
entity.customFields."Due Date"?.value = "12/31/2025"
entity.customFields."Due Date"?.value = "31-12-2025"
Error:
Invalid date format '12/31/2025' for custom field 'Due Date'.
Expected format: yyyy-MM-dd (e.g., 2025-12-03).
Time Fields
Values must be in format: HH:mm
// Valid
entity.customFields."Start Time"?.value = "09:30"
entity.customFields."Start Time"?.value = "14:00"
// Invalid - fails the sync
entity.customFields."Start Time"?.value = "9:30 AM"
entity.customFields."Start Time"?.value = "9:30"
Error:
Invalid time format '9:30 AM' for custom field 'Start Time'.
Expected format: HH:mm (e.g., 12:30 or 09:05).
Field Not Found
When the field name doesn't exist in the template:
entity.customFields."NonExistent"?.value = "value"
Error:
Custom field 'NonExistent' not found in template 12345.
Available fields: "Priority" (id: priority), "Description" (id: description), "Due Date" (id: due_date)
Template Not Set
When a new request sets custom fields without a template:
template_id is required when setting custom fields. Set entity.templateId before setting custom fields.
No Custom Field Definitions
When the template's custom field definitions cannot be read, the error names the cause:
| Error starts with | Cause | What to do |
|---|---|---|
Cannot read request template 12345. | Template does not exist, or the token lacks Request Template – Read | Check the templateId and the token permission |
Request template 12345 has no UI extension attached | The template defines no custom fields | Attach a UI extension to the template, or remove the custom field assignments from the script |
Cannot read UI extension 678 for template 12345 | The token lacks UI Extensions – Read | Grant the permission |
UI extension 678 on template 12345 defines no custom fields | The UI extension has no fields | Add the fields in Xurrent, or remove the assignments |
... endpoint returned 401 Unauthorized and is cached as inaccessible for up to 1 hour | A missing permission was detected earlier | Grant the permission, then restart the node to clear the cache |
Helper Methods Reference
getCustomField(templateId, fieldName, value) — deprecated
The earlier assignment style still works, but is no longer needed:
entity.customFields."Priority" = nodeHelper.getCustomField(entity.templateId, "Priority", "High")
// Equivalent:
entity.customFields."Priority"?.value = "High"
getCustomField validates immediately, while the script runs, and needs a template ID at that moment (on create, set entity.templateId before calling it). Existing scripts can keep using it.
Troubleshooting
"Cannot read request template" / "Cannot read UI extension" / "defines no custom fields"
- Follow the "What to do" column in the table above.
"Invalid value 'X' for custom field"
- For select fields, check available options in the Xurrent UI.
- Use the exact option label or internal ID.
- Check for typos or extra whitespace.
A custom field is not updated and no error is shown
- Check that the field name is not a reserved name (see Incoming Sync), for example use
"Company"instead of"company". - On the outgoing side, reference fields by their display name, not their internal ID.
DateTime displaying wrong time
- Xurrent expects UTC format (Z suffix).
- The UI displays time in the user's timezone based on profile settings.
- Always send UTC; Xurrent handles timezone conversion.
- API token must have
ui_extensionspermission to read custom field definitions - Know the
templateIdof the request (available asentity.templateIdorreplica.templateId)
Important Notes
- Date Format: Date fields must use
YYYY-MM-DDformat - DateTime Format: DateTime fields must use UTC format
YYYY-MM-DDTHH:mm:ssZ - Time Format: Time fields must use
HH:mmformat (24-hour, zero-padded) - Select Fields: Values must match existing options exactly (label or internal ID)
- Null/Empty Values: Setting null or empty string clears/resets the field
- Permissions: API token needs
ui_extensionspermission for field validation
More information
Have more questions? Ask the community