Skip to content

Transform data between steps ​

Data rarely arrives in the shape the next step wants. A date is in the wrong format, a list needs filtering, or a field has the wrong name. This guide shows four ways to reshape data, from the lightest to the most flexible, with an example for each.

Choose a tool ​

You want to…Use
Change one value on its way into a field: upper-case it, count a list, add up pricesAn expression in the field itself
Do a common conversion without writing code: format a date, parse JSON, map a code to a labelA Formatter step
Keep only the items of a list that match conditionsA Filter step
Anything else: reshape objects, combine several steps' data, custom logicA Code step

Start with the lightest option that does the job. A field expression adds no step to the canvas, and a Formatter step is easier for someone else to read than code.

The examples on this page use an earlier HTTP step, Get orders, whose output body is:

json
{
  "orders": [
    { "id": "A-1", "customer": "Aiko Tanaka", "total": 4200, "status": "paid", "created_at": "2026-10-26T01:30:00Z" },
    { "id": "A-2", "customer": "Ken Sato", "total": 900, "status": "refunded", "created_at": "2026-10-26T03:10:00Z" }
  ]
}

Expressions ​

When a field's whole value starts with a function, AI Studio evaluates it as an expression. Expressions use JSONata, so you can do a lot in one line:

GoalField valueResult
Count the orders$count($.<Get orders>.output.body.orders)2
Add up the totals$sum($.<Get orders>.output.body.orders.total)5100
List the customer names$join($.<Get orders>.output.body.orders.customer, ", ")Aiko Tanaka, Ken Sato
Keep only paid orders$filter($.<Get orders>.output.body.orders, function($v) { $v.status = "paid" })The first order
Rename fields$map($.<Get orders>.output.body.orders, function($v) { {"orderId": $v.id, "amount": $v.total} })[{"orderId": "A-1", "amount": 4200}, …]
Today's date in Japan time$now("[Y0001]-[M01]-[D01]", "+0900")2026-10-27

Replace <Get orders> with the step's ID. Pick it from the $ list or use the copy button next to the step.

Two rules catch people out:

  • The function must be the whole field. In Total: $sum(...) the function stays as text. To mix an expression with text, build the text inside a function: $join(["Total: ", $string($sum(...))]).
  • The result keeps its type. $filter(...) gives a list, so it can go straight into a Loop's Value.

The Functions tab of the data picker lists the common functions. See Expressions for all of them.

Formatter ​

The Formatter node does common conversions with settings instead of code. Click Add Step, open Built-in, choose Formatter, and pick an action. Some useful ones:

ActionExample
DateTime Format2026-10-26T01:30:00Z to 2026/10/26 10:30:00: set To Format to Japanese DateTime and To Timezone to Asia/Tokyo. The result is formatted_date.
DateTime AddA due date 14 days after an order.
Number Currency Format4200 to ¥4,200.
Text Parse JSONTurn JSON that arrived as text, for example from an LLM or a form field, into an object later steps can go into. The result is result.
Lookup TableMap codes to labels: with Table {"paid": "Paid", "refunded": "Refunded"} and Key the order's status, value is the label. Set Default for unknown codes.
Text Split / Text JoinTurn "a, b, c" into a list, or back.
HTML to Markdown / Text Remove HTMLClean up email or web content before sending it to an LLM.

Each action works on one value. To format every item of a list, put the Formatter inside a Loop, or use an expression or Code instead.

The Formatter reference lists all 27 actions.

Filter ​

The Filter node keeps the items of a list that match your conditions:

  1. Click Add Step, open Built-in, choose Filter.
  2. Input Data: a reference to the list, alone in the field, such as $.<Get orders>.output.body.orders.
  3. Filter Conditions: add conditions on the items' fields, such as status equals paid. Conditions in a group must all match (AND), and groups are alternatives (OR), as in a Path.
  4. Decide what happens when nothing matches. By default the run stops. Turn on Continue on Empty Results to carry on with an empty list.

The matching items are in the step's filtered output.

Code ​

When the other options get awkward, write a few lines of JavaScript in a Code step:

  1. Click Add Step, open Built-in, choose Code, then Run JavaScript.

  2. Under Input Params, add one entry per value the code needs. The key is the variable name in your code, and the value is a reference, alone in the field so that lists and objects keep their type:

    KeyValue
    orders$.<Get orders>.output.body.orders
  3. Write the code. Each input is already a variable. Whatever you return becomes the step's output:

    js
    const paid = orders.filter((o) => o.status === "paid");
    return {
      count: paid.length,
      total: paid.reduce((sum, o) => sum + o.total, 0),
      customers: paid.map((o) => o.customer),
    };

Later steps read the result from the step's results, for example $.<Code step>.output.results.total.

Things to know:

  • Don't put references in the code itself. Pass them in through Input Params.
  • Input variables can't be reassigned. Copy one first: let list = [...orders];.
  • console.log(...) lines appear in the step's logs, which helps when debugging in Executions.
  • The libraries radash, dateFns, dateFnsTz, Decimal and nanoid are available without importing them.
  • Code must finish within 30 seconds. Call APIs with an HTTP step, not from code.
  • If the code throws an error, the step fails. See Handle errors and retries.

If you find yourself pasting the same code into several flows, save it once as a Function instead.