How to Sync Custom Fields in Xurrent

    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.templateId before setting custom fields.
    • When updating a request, the request's current template is used automatically. Set entity.templateId only 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.customFields is 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 as entity.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

    TypeFormatExample Value
    textAny string"Task details here"
    text areaAny multiline string"Task details here for more details"
    rich_textXurrent rich text format"**bold** and __italic__"
    numberInteger or decimal42 or 1234.56
    checkboxBoolean valuetrue or false
    selectOption label or internal ID"High" or "value_1"
    dateYYYY-MM-DD"2025-12-31"
    date_timeYYYY-MM-DDTHH:mm:ssZ (UTC)"2025-12-31T14:30:00Z"
    timeHH:mm"09:30"
    emailValid 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 withCauseWhat to do
    Cannot read request template 12345.Template does not exist, or the token lacks Request Template – ReadCheck the templateId and the token permission
    Request template 12345 has no UI extension attachedThe template defines no custom fieldsAttach a UI extension to the template, or remove the custom field assignments from the script
    Cannot read UI extension 678 for template 12345The token lacks UI Extensions – ReadGrant the permission
    UI extension 678 on template 12345 defines no custom fieldsThe UI extension has no fieldsAdd the fields in Xurrent, or remove the assignments
    ... endpoint returned 401 Unauthorized and is cached as inaccessible for up to 1 hourA missing permission was detected earlierGrant 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_extensions permission to read custom field definitions
    • Know the templateId of the request (available as entity.templateId or replica.templateId)

    Important Notes

    1. Date Format: Date fields must use YYYY-MM-DD format
    2. DateTime Format: DateTime fields must use UTC format YYYY-MM-DDTHH:mm:ssZ
    3. Time Format: Time fields must use HH:mm format (24-hour, zero-padded)
    4. Select Fields: Values must match existing options exactly (label or internal ID)
    5. Null/Empty Values: Setting null or empty string clears/resets the field
    6. Permissions: API token needs ui_extensions permission for field validation

    More information

    Have more questions? Ask the community