Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.spojit.com/llms.txt

Use this file to discover all available pages before exploring further.

The Transform node is a deterministic, AI-free utility for shaping data as it flows between steps. It has two modes — Structured for field-by-field output, and Plaintext for free-form templates — and an optional Iterate over field that runs the transform once per element of an input array. Use it when the shape you need is known and predictable. For shaping that requires LLM judgment (summarising, classifying, inferring missing fields), reach for an AI Connector node instead.

When to use

  • Rename or remap fields between connectors (e.g. firstNamefirst_name).
  • Extract a subset of fields from a larger object.
  • Build a JSON payload for a downstream HTTP/connector call.
  • Transform every element of an array in one step (map mode).
  • Combine values from multiple upstream nodes into a single object.

Templates

Field values are written using {{ var.path }} template syntax — the same syntax used everywhere else in the workflow editor. See Passing Data Between Nodes for the full reference.
TemplateWhat it references
{{ input.field }}A field from the trigger payload.
{{ stepOutput.field }}A field from an upstream step’s output (whatever you set as its Output Variable).
{{ item.field }} and {{ index }}Only available when Iterate over is set — the current element and its zero-based index.
A template that is the entire value of a field preserves the original type (numbers stay numbers, arrays stay arrays). Mixed templates like "Hi {{ name }}" are stringified.

Structured mode

Define your output shape field by field. Each leaf field carries a template that resolves at execution time.
  1. Click Add Field to add an output property.
  2. Pick a name and type (string, number, boolean, array, object).
  3. For leaves, fill in the template with {{ … }} references.
  4. For object, add nested children. For array, choose the item type — and for arrays of objects, define the per-item children.
  5. Toggle JSON (top right) to edit the schema as raw JSON when you’d rather paste a structure than click through it.
Example. Given an upstream connector with output variable order:
{
  "order": {
    "id": "12345",
    "customer": { "firstName": "Jane", "email": "jane@example.com" },
    "totalPrice": 99.95
  }
}
Structured fields:
  • id (string) → {{ order.id }}
  • customer_email (string) → {{ order.customer.email }}
  • amount (number) → {{ order.totalPrice }}
Resolves to:
{
  "id": "12345",
  "customer_email": "jane@example.com",
  "amount": 99.95
}
amount stays a number because the template is the entire field value.

Field types and value coercion

The declared field type controls how literal values you type are persisted:
  • String — the value is sent as-is.
  • Number — a literal like 42 is sent as the number 42. Non-numeric literals fall back to a string.
  • Booleantrue and false (case-insensitive) become the actual booleans true / false. Anything else falls back to a string.
  • Object / Array — shape is built from the children you define.
For template values (anything containing {{ … }}), the field type does not coerce — the engine returns whatever type the resolved expression produced. So a String field with template {{ item }} (where item is a user object) outputs the object, not a stringified one. Match the declared field type to what your template actually resolves to.

Plaintext mode

Paste any text or JSON template and substitute {{ … }} references inline. Use this when you’d rather write the payload as a literal block — useful for HTTP request bodies, Slack message text, or any sufficiently large object. The Output as JSON toggle controls how the rendered output is treated:
  • Off — the result is the rendered string verbatim.
  • On — the rendered string is parsed as JSON; the parsed object/array is what downstream nodes receive. If the rendered output isn’t valid JSON, the workflow fails with a clear error so the bug is caught at the transform, not three steps downstream.
Example. Template (with Output as JSON on):
{
  "summary": "Order {{ order.id }} for {{ order.customer.firstName }} totalling ${{ order.totalPrice }}",
  "orderId": "{{ order.id }}"
}
With the same order input as above, resolves to:
{
  "summary": "Order 12345 for Jane totalling $99.95",
  "orderId": "12345"
}

Iterate over (map mode)

Set Iterate over to a template expression that resolves to an array — the transform then runs once per element. Inside templates, {{ item }} is the current element and {{ index }} is its zero-based position. The transform’s Output Variable receives the array of all per-iteration results. Example. With users set to:
[
  { "first_name": "Jane", "email": "jane@example.com" },
  { "first_name": "Bob",  "email": "bob@example.com" }
]
Set Iterate over to {{ users }} and a structured field mapped (Object type) with the children name{{ item.first_name }} and email{{ item.email }}. The output variable holds:
[
  { "mapped": { "name": "Jane", "email": "jane@example.com" } },
  { "mapped": { "name": "Bob",  "email": "bob@example.com" } }
]
This is equivalent to wrapping the transform in a Loop node, but it’s a single node and doesn’t require Loop’s per-item connection wiring.

Drill into the upstream object to find the array

A common surprise: most upstream steps don’t return a bare array — they return an object that wraps the array. Common shapes:
  • AI Connector (agent mode) with a Response Schema → the step’s value is the schema object, e.g. { "users": [ … ] } → use {{ result_step1.users }}.
  • HTTP / direct connector → typically { "data": [ … ], "status": 200, "headers": { … } } (e.g. JSONPlaceholder) → use {{ result_step1.data }}.
If you point Iterate over at the wrapper instead of the inner array, the workflow fails fast with a clear error — forEach 'items' template "{{ result_step1 }}" must resolve to an array, got object (resolved object has keys: data, status, headers) — so you can spot the missing path segment immediately.

Output

The resolved value is bound to the Output Variable name (defaulting to result_<nodeId> when blank). Reference it from downstream nodes the same as any other step result — e.g. {{ shapedUser.email }}. For map mode, this name holds the full collected array.

Tips

  • Chain multiple transforms when reshaping in stages — it’s cheaper to read than one giant template.
  • For advanced operations like JSONPath queries, deep flattening, or merging nested objects, see the JSON Tools connector.
  • A template that points at nothing (e.g. a typoed variable name) resolves to null. Use the structured editor’s JSON view when debugging — it shows exactly the templates being sent to the engine.