Configure how data transforms between Field Nation and external platforms using flexible mapping actions.
Every field mapping consists of:
Prop
Type
Description
Source FieldstringThe field path in the originating system (e.g., `assignee.user.first_name`)
Target FieldstringThe field path in the destination system where data will be written
Transformation ActionenumHow to transform the data: Sync, Set Static, Array Map, Range Map, Date Convert, Concat, Custom JSONNET
Default Value?anyValue to use if source field is empty, null, or missing
Direct field-to-field copy with optional type conversion.
The simplest mapping action - copies the source field value directly to the target field.
{
// Field Nation → External System
"source": "workorder.title",
"target": "external_system.job_name",
"action": "sync"
}Use Cases:
Assign a predetermined static value regardless of source data.
Always sets the target field to a specific value.
{
"target": "priority",
"action": "set_static",
"value": "High"
}Use Cases:
source_system: "Field Nation")Example: Always set status to "New"
{
"target": "status",
"action": "set_static",
"value": "New"
}Map source values to target values using exact match lookups.
Performs equality checks and returns corresponding mapped values.
{
"source": "pay.type",
"target": "payment_type",
"action": "array_map",
"mappings": [
{ "compare": "fixed", "value": "Fixed Price" },
{ "compare": "hourly", "value": "Hourly Rate" },
{ "compare": "blended", "value": "Blended Rate" }
],
"default": "Unknown"
}Use Cases:
Example: Work Order Status Mapping
{
"source": "status.name",
"target": "external_status",
"action": "array_map",
"mappings": [
{ "compare": "draft", "value": "New" },
{ "compare": "assigned", "value": "Assigned" },
{ "compare": "work_done", "value": "Completed" },
{ "compare": "approved", "value": "Approved" }
],
"default": "Unknown"
}Map numeric values to categories based on range comparisons.
Uses less-than-or-equal comparisons from right to left.
{
"source": "time_logs.hours",
"target": "duration_category",
"action": "range_map",
"ranges": [
{ "compare": 0.5, "value": "15-30 Minutes" },
{ "compare": 1, "value": "31-60 Minutes" },
{ "compare": 2, "value": "1-2 Hours" },
{ "compare": 4, "value": "2-4 Hours" }
],
"default": "4+ Hours"
}How it works:
0.3 → "15-30 Minutes" (≤ 0.5)1.5 → "1-2 Hours" (≤ 2)5 → "4+ Hours" (default, exceeds all ranges)Use Cases:
Transform date values between formats and timezones.
{
"source": "schedule.service_window.start.utc",
"target": "scheduled_date",
"action": "date_convert",
"input_format": "YYYY-MM-DD HH:mm:ss",
"output_format": "MM/DD/YYYY h:mm:ss A",
"timezone_in": "UTC",
"timezone_out": "America/New_York"
}Common Date Formats:
YYYY-MM-DDTHH:mm:ssZMM/DD/YYYYYYYY-MM-DD HH:mm:ssX (seconds) or x (milliseconds)Use Cases:
Example: UTC to Local Business Hours
{
"source": "created_at",
"target": "created_local",
"action": "date_convert",
"input_format": "YYYY-MM-DD HH:mm:ss",
"output_format": "MM/DD/YYYY hh:mm A",
"timezone_in": "UTC",
"timezone_out": "America/Chicago"
}Combine multiple fields into a single target field.
{
"target": "full_name",
"action": "concat",
"parts": [
{ "type": "field", "value": "assignee.user.first_name" },
{ "type": "static", "value": " " },
{ "type": "field", "value": "assignee.user.last_name" }
]
}Use Cases:
Example: Full Address
{
"target": "full_address",
"action": "concat",
"parts": [
{ "type": "field", "value": "location.address1" },
{ "type": "static", "value": ", " },
{ "type": "field", "value": "location.city" },
{ "type": "static", "value": ", " },
{ "type": "field", "value": "location.state" },
{ "type": "static", "value": " " },
{ "type": "field", "value": "location.zip" }
]
}Execute custom JSONNET code for complex transformations.
For logic that can't be expressed through standard actions, write custom JSONNET.
{
"target": "priority_level",
"action": "custom",
"script": |||
local hours = $.util.lookup_field($.input, 'time_logs.hours', 0);
local is_urgent = $.util.lookup_field($.input, 'priority', '') == 'urgent';
if is_urgent && hours > 2 then
"Critical"
else if is_urgent then
"High"
else if hours > 4 then
"Medium"
else
"Low"
|||
}Learn more about custom actions →
Configure separate mappings for each direction:
Inbound (External → Field Nation)
{
"source": "external_system.job_title",
"target": "workorder.title",
"action": "sync"
}Outbound (Field Nation → External)
{
"source": "workorder.status.name",
"target": "external_system.status",
"action": "array_map",
"mappings": [...]
}Use dot notation to access nested objects:
{
"source": "workorder.location.company.name",
"target": "company_name",
"action": "sync"
}Access array elements:
{
"source": "workorder.contacts[0].email",
"target": "primary_contact_email",
"action": "sync"
}Field Nation custom fields require special handling:
Mapping Custom Fields:
{
"action": "custom",
"target": "external_field",
"script": |||
$.util.lookup_custom_field('835', $.input, 'Default Value')
|||
}The lookup_custom_field function handles Field Nation's custom field structure automatically.
Keep Mappings Efficient:
Map bidirectional status values:
// Inbound: External → Field Nation
{
"source": "status",
"target": "status_id",
"action": "array_map",
"mappings": [
{ "compare": "New", "value": "1" },
{ "compare": "Assigned", "value": "2" },
{ "compare": "Completed", "value": "5" }
]
}
// Outbound: Field Nation → External
{
"source": "status.id",
"target": "external_status",
"action": "array_map",
"mappings": [
{ "compare": "1", "value": "Open" },
{ "compare": "2", "value": "In Progress" },
{ "compare": "5", "value": "Closed" }
]
}Combine or split contact fields:
// Combine first + last name
{
"target": "full_name",
"action": "concat",
"parts": [
{ "type": "field", "value": "user.first_name" },
{ "type": "static", "value": " " },
{ "type": "field", "value": "user.last_name" }
]
}
// Extract email domain
{
"action": "custom",
"target": "email_domain",
"script": |||
local email = $.util.lookup_field($.input, 'user.email', '');
local parts = std.split(email, '@');
if std.length(parts) > 1 then parts[1] else ''
|||
}Handle currency and decimal precision:
{
"source": "pay.amount",
"target": "cost",
"action": "custom",
"script": |||
local amount = $.util.lookup_field($.input, 'pay.amount', 0);
std.round(amount * 100) / 100 // Round to 2 decimal places
|||
}The Integration Broker automatically discovers available fields from external systems.
Last updated on