Skip to content

Advanced JSON

Three places in the workflow editor let you write a step’s data as JSON instead of filling in a form:

  • Edit input as JSON on an Invoke tool step: the full input the action receives.
  • Advanced JSON on a Transform step: the value the step produces.
  • Advanced column values (JSON) on a Write worksheet row step: the cells to write.

Use the form when it covers what you need. It checks each field as you go and shows references as chips. Use JSON for nested data, lists of objects, or fields the form doesn’t show.

The editor accepts standard JSON. That means:

  • Field names and text are in double quotes: "name": "Ada".
  • Numbers, true, false and null have no quotes.
  • No comments and no trailing commas.

A value from the workflow goes inside a quoted string as {{ }}. Type {{ or press Ctrl+Space to choose one. Outside a string, the editor adds the quotes for you.

{
"email": "{{input.email}}",
"greeting": "Hello {{input.name}}"
}

The braces can hold a whole formula, not only a reference. See the formula reference.

Where a {{ }} sits decides what comes out:

  • The whole string is one {{ }}. The value keeps its type. "{{input.quantity}}" gives the number 3, and "{{input.tags}}" gives a list.
  • The {{ }} sits inside other text. The value is written into the text. "Order of {{input.quantity}}" gives "Order of 3".

Even a single space around the braces makes it part of a sentence, so the value becomes text.

{
"to": "{{input.email.trim()}}",
"subject": "Your order of {{input.quantity}}",
"quantity": "{{input.quantity}}",
"tags": "{{input.tags}}",
"priority": "normal"
}

With the sample data, this gives:

{
"to": "Ada@Example.com",
"subject": "Your order of 3",
"quantity": 3,
"tags": [
"vip",
"beta"
],
"priority": "normal"
}

If a whole-value {{ }} has nothing in it when the step runs, its field is left out. Inside text, a missing value is written as nothing.

{
"name": "{{input.name}}",
"nickname": "{{input.nickname}}",
"note": "Nickname: {{input.nickname}}"
}

With the sample data, this gives:

{
"name": "Ada Lovelace",
"note": "Nickname: "
}

To always send the field, give it a fallback with has() and ? :. Inside a JSON string, quotes in the formula need a backslash:

{
"name": "{{input.name}}",
"nickname": "{{has(input.nickname) ? input.nickname : \"\"}}"
}

With the sample data, this gives:

{
"name": "Ada Lovelace",
"nickname": ""
}

On an Invoke tool step, open the Inputs tab and choose Edit input as JSON. The box shows the complete input the action will receive, including fields the form doesn’t have controls for.

  • It must be a JSON object, the same shape as the form: one field per action input.
  • The form and the JSON are the same data. A change in one shows in the other. Fields the form doesn’t know about are kept when you edit with the form.
  • Invalid JSON is never saved. The box says “Enter a valid JSON object. The last valid value is unchanged.” Fix it and the change saves.
  • Closing the box while the JSON is invalid asks whether to discard the text you typed. The last valid value stays.
  • The action checks its own fields when the step runs. If one is missing or the wrong type, the step fails with invalid_tool_input and the error names the field. Test the workflow to catch this before customers do.

When an action has no guided fields, or the saved input uses a format the form can’t show, the editor tells you to use Advanced JSON.

A new Transform step shows Output rows: one named output per row. Choose Advanced JSON to write the whole result as JSON instead.

The result can be any JSON value: an object, a list, text in quotes, a number, true, false or null. Later steps read it as result. If it’s an object, they can read its fields as result.email, result.total and so on.

An object:

{
"message": "Hello {{input.name}}",
"count": "{{input.quantity}}"
}

With the sample data, this gives:

{
"message": "Hello Ada Lovelace",
"count": 3
}

A single number:

"{{input.quantity * input.price}}"

With the sample data, this gives:

7.5

Text:

"Order for {{input.name}}"

With the sample data, this gives:

"Order for Ada Lovelace"

A list:

[
"{{input.email.trim().lowerAscii()}}",
"{{input.tags}}"
]

With the sample data, this gives:

[
"ada@example.com",
[
"vip",
"beta"
]
]

Nested data, with formulas:

{
"customer": {
"name": "{{input.name}}",
"email": "{{input.email.trim().lowerAscii()}}"
},
"order": {
"total": "{{input.quantity * input.price}}",
"summary": "{{input.quantity}} × {{input.price}}"
},
"vip": "{{\"vip\" in input.tags}}",
"status": "{{nodes.lookup.output.row.Status}}"
}

With the sample data, this gives:

{
"customer": {
"name": "Ada Lovelace",
"email": "ada@example.com"
},
"order": {
"total": 7.5,
"summary": "3 × 2.5"
},
"vip": true,
"status": "Active"
}
  • Rows to JSON keeps everything. If you switch a step that already has output rows, each row also stays available under its own name. Every row needs a unique name first. The editor asks for one with “Complete each output and give it a unique name before opening Advanced JSON.”
  • JSON to rows is offered only when the JSON is a flat object: each field is plain text, a number, true or false, or one whole {{ }}. Otherwise you keep editing JSON, and the editor says “This JSON has values that output rows cannot show.”
  • Text typed in a row stays text. A row set to Specific value that contains braces keeps them as typed in the JSON. Edit it in JSON to make it a formula.

Steps made before Transform had output rows show “This step uses older Transform settings.” They keep working as saved. Choose Switch to JSON to edit them here. Check the result first, because it may change.

On a Write worksheet row step, the column values can be JSON when the columns aren’t known until the workflow runs. Write one object: each key is a column heading, each value is what goes in that cell.

{
"Name": "{{input.name}}",
"Quantity": "{{input.quantity}}",
"Status": "New"
}

With the sample data, this gives:

{
"Name": "Ada Lovelace",
"Quantity": 3,
"Status": "New"
}

Or set Dynamic column values to an input or formula that returns such an object. When the JSON is a flat object of known columns, Use column rows switches back to the column list. See Google Sheets.

The editor checks the JSON as you type:

  • Not valid JSON. Nothing is saved. Your text stays in the box with the error, and the last valid value stays saved.
  • Valid JSON, but not the shape this box needs. Edit input as JSON needs an object. A Transform’s JSON can be any value.
  • A reference to something that no longer exists shows “This saved reference is no longer available” on the step’s form.

Problems inside a formula, such as dividing by zero, show up when the step runs. The step fails with an error code, and the run shows which step and why.