When to Use
- Transform API response to internal schema: A third-party CRM API returns fields like
contact.full_name and contact.email_address. Map them to your internal schema fields customerName and email with a single DataMapping node, applying trim and lowercase transforms.
- Map CSV column names to DB field names: An imported CSV uses human-readable headers like "First Name", "Date of Birth". Map these to database column names like
first_name, dob with appropriate type transforms.
- Normalize data from multiple sources into one schema: Orders arrive from Shopify, Magento, and a bespoke ERP — each with different field names. A DataMapping node per source normalizes each to a single internal
OrderDTO structure for consistent downstream processing.
- Extract specific fields from a deeply nested object: An API response contains
response.data.attributes.billing.address.city. Map it to a flat billingCity field without writing any code — just use dot-notation in SourceField.
- Convert date strings to a standard format: An integration partner sends dates as
MM/DD/YYYY. Use the toDate or toDateTime transform to normalize to ISO 8601 before storing in the database.
Configuration
| Setting | Required | Description |
Source |
Optional |
An inline JSON string representing the source object. Use this for mapping static or test data. If provided, takes precedence over SourceOutput. Supports BizFirst expressions. |
SourceOutput |
Optional |
The node key of a previous node whose output should be used as the source. Example: "httpRequestNode". The full output data of that node becomes the source object for mapping. |
Mappings |
Required |
A JSON array of DataMappingRule objects. Each rule defines one field mapping. Must contain at least one rule. Order matters — rules execute top to bottom. |
DataMappingRule fields
| Field | Required | Description |
SourceField |
Required |
Path to the field in the source object. Supports dot notation (user.address.city) and array indexing (items[0].price). Use the root path . to select the entire source object. |
TargetField |
Required |
The field name in the output mapped_data object where the mapped (and optionally transformed) value is written. Simple identifier, no nesting supported in target. |
Transform |
Optional |
Optional transform to apply to the source value before writing to the target. See the transforms table below. |
Supported Transforms
| Transform | Input Type | Output |
uppercase | string | Converts all characters to uppercase. "london" → "LONDON" |
lowercase | string | Converts all characters to lowercase. "SMITH" → "smith" |
trim | string | Removes leading and trailing whitespace. |
toString | any | Converts any value to its string representation. |
toInt | string / number | Parses to integer. "42.9" → 42 |
toDecimal | string / number | Parses to decimal (double). "19.99" → 19.99 |
toBoolean | string / number | Parses truthy values. "true", "1", "yes" → true; others → false |
toFloat | string / number | Parses to floating-point number. |
toDate | string | Parses a date string and returns ISO date (YYYY-MM-DD). |
toDateTime | string | Parses a datetime string and returns full ISO 8601 datetime. |
base64Encode | string | Encodes the string as Base64. |
base64Decode | string | Decodes a Base64 string to plain text. |
jsonStringify | object / array | Serializes an object or array to a JSON string. |
jsonParse | string | Deserializes a JSON string to an object or array. |
nullToEmpty | null / undefined | Converts null or undefined to an empty string "". |
emptyToNull | string | Converts an empty string "" to null. |
Source Resolution Order
The node resolves the source data in this order (first available wins):
InputData["source"] — if the preceding node outputs a field named source, it is used as the source object.
Settings.Source — the inline JSON string configured in settings.
SourceOutput node lookup — the full output of the named upstream node.
Output Ports
| Port | When It Fires |
success | All mapping rules executed without error. The mapped_data object is available downstream. |
error | A mapping rule fails (e.g., type conversion error, invalid source path) or the Mappings array is empty. Error details include the failing rule index and the error reason. |
Output Fields
| Field | Type | Description |
mapped_data | object | The constructed target object containing all successfully mapped fields. Only explicitly mapped fields are present — no unmapped source fields are copied. Access individual mapped fields via {{ $output.dataMappingNode.mapped_data.fieldName }}. |
Validation
The node validates on execution (not on save):
Mappings is required and must be a non-empty array.
- Each rule must have both
SourceField and TargetField non-empty strings.
- If a
Transform is specified, it must be one of the 16 supported values listed above.
- Type conversion failures (e.g.,
toInt applied to a non-numeric string) route to the error port with a descriptive message.
Sample Configuration
{
"nodeType": "data-mapping",
"settings": {
"SourceOutput": "crmApiNode",
"Mappings": [
{ "SourceField": "contact.full_name", "TargetField": "customerName", "Transform": "trim" },
{ "SourceField": "contact.email_address", "TargetField": "email", "Transform": "lowercase" },
{ "SourceField": "contact.address.city", "TargetField": "city", "Transform": "uppercase" },
{ "SourceField": "contact.created_at", "TargetField": "createdDate", "Transform": "toDate" },
{ "SourceField": "contact.annual_spend", "TargetField": "annualSpend", "Transform": "toDecimal" },
{ "SourceField": "contact.is_active", "TargetField": "isActive", "Transform": "toBoolean" },
{ "SourceField": "contact.external_id", "TargetField": "externalId", "Transform": "toString" }
]
}
}
Sample Output
Success Port
{
"mappedRecord": {
"contact_id": "SF-00123456",
"first_name": "Michael",
"last_name": "Torres",
"email_address": "m.torres@company.com",
"phone_number": "+1-415-555-0182",
"company_name": "Meridian Logistics",
"job_title": "Supply Chain Manager",
"lead_source": "Website",
"created_date": "2025-03-15"
},
"_fieldsProcessed": 9,
"_nullFieldsSkipped": 2,
"_transformsApplied": ["concatenate", "format_date", "normalize_phone"]
}
Expression Reference
| Expression | Value |
{{ $output.dataMappingNode.mapped_data.customerName }} | The trimmed customer name from the mapped output. |
{{ $output.dataMappingNode.mapped_data.city }} | The uppercased city value. |
{{ $output.dataMappingNode.mapped_data.annualSpend }} | The annual spend as a decimal number. |
Node Policies & GuardRails
| Policy | Rationale |
| Prefer DataMapping over CodeExecute for field renaming and type conversion | DataMapping is declarative, auditable, and readable by non-developers. CodeExecute is appropriate for logic that cannot be expressed as per-field transforms — not for renaming fields. |
Always handle the error port | Type conversion failures (e.g., applying toInt to a non-numeric API value) route to the error port silently if it is unconnected. Connect it to a notification or dead-letter queue node. |
Use SourceOutput rather than Source (inline JSON) in production | Inline JSON in the Source field is static — it does not change with incoming data. For live workflow data, always reference the output of an upstream node via SourceOutput. |
Only explicitly mapped fields appear in mapped_data | DataMapping is non-passthrough. Fields not listed in Mappings are absent from the output. If you need to pass additional unmapped fields, add explicit mapping rules for each one or combine with a JsonTransform merge operation. |
Pattern Examples
Pattern 1 — Normalize CRM API Response to Internal Order Schema
{
"SourceOutput": "crmApiNode",
"Mappings": [
{ "SourceField": "data.contact.id", "TargetField": "customerId" },
{ "SourceField": "data.contact.name", "TargetField": "customerName", "Transform": "trim" },
{ "SourceField": "data.contact.email", "TargetField": "email", "Transform": "lowercase" },
{ "SourceField": "data.billing.address.city", "TargetField": "billingCity", "Transform": "uppercase" },
{ "SourceField": "data.billing.total", "TargetField": "totalAmount", "Transform": "toDecimal" },
{ "SourceField": "data.order.created_at", "TargetField": "orderDate", "Transform": "toDateTime" }
]
}
Pattern 2 — Flatten Nested API Response for Database Insert
An API returns a nested structure. The DataMapping node flattens it to individual columns ready for a DB insert node.
{
"SourceOutput": "apiResponseNode",
"Mappings": [
{ "SourceField": "payload.user.id", "TargetField": "userId" },
{ "SourceField": "payload.user.profile.age", "TargetField": "age", "Transform": "toInt" },
{ "SourceField": "payload.user.profile.country", "TargetField": "country", "Transform": "uppercase" },
{ "SourceField": "payload.subscription.plan", "TargetField": "plan", "Transform": "lowercase" },
{ "SourceField": "payload.subscription.expires", "TargetField": "expiryDate", "Transform": "toDate" },
{ "SourceField": "payload.metadata", "TargetField": "metaJson", "Transform": "jsonStringify" }
]
}
Pattern 3 — Webhook Payload Validation and Normalization
Immediately after a WebhookTrigger, validate and normalize the inbound payload to ensure all downstream nodes receive clean, typed data.
{
"SourceOutput": "webhookTriggerNode",
"Mappings": [
{ "SourceField": "event", "TargetField": "eventType", "Transform": "lowercase" },
{ "SourceField": "data.orderId", "TargetField": "orderId", "Transform": "toString" },
{ "SourceField": "data.amount", "TargetField": "amountCents", "Transform": "toInt" },
{ "SourceField": "data.currency","TargetField": "currency", "Transform": "uppercase" },
{ "SourceField": "timestamp", "TargetField": "eventTime", "Transform": "toDateTime" }
]
}