Open a Transform node and click Select Transform to browse the catalog. Each type has its own configuration fields. This page documents every transform and what you configure.
See also: Transform Node for overview and chaining patterns · Function Node when you need custom JavaScript or Python instead of a catalog step.
How transform configuration works
| Concept | Description |
|---|---|
| Input | Data from the previous connected node (lastOutput) |
| Output | Whatever the transform produces — becomes lastOutput for the next node |
| Fields | Type-specific settings shown in the node panel after you pick a transform |
| Variables | Click Variables on any field to insert {{lastOutput}}, {{context.nodeId.output}}, or {{variables.key}} |
Most transforms run on the output of the node directly upstream. Filters and list transforms expect an array; field editors expect an object or array of objects.
Popular
AI Transform
Describe changes in plain English. The AI rewrites or restructures the incoming data according to your instructions.
| Field | Description |
|---|---|
| Instructions | What to do with the data (required) |
Example instructions: “Extract email, name, and company from each item and return a JSON array.”
Code
Run a short JavaScript expression on the input. Lighter than a Function node — best for one-off reshaping.
| Field | Description |
|---|---|
| Language | JavaScript (Python is not supported yet) |
| Code | Must return a value. Scope: lastOutput, inputs, variables, context |
return (lastOutput?.records || []).filter((row) => row.status === 'active');
Date & Time
Format, add, subtract, or extract parts from a date field on each item.
| Field | Description |
|---|---|
| Date field | Property name containing the date |
| Operation | Format, add, subtract, or extract |
| Output format | ISO, YYYY-MM-DD, custom, etc. |
| Amount / unit | For add/subtract operations |
Edit Fields (Set)
Rename, add, or remove fields using a key-value list. Leave a value empty to remove a field.
| Field | Description |
|---|---|
| Fields | Rows of field name → value (supports {{templates}}) |
Sheet to Rows
Converts Google Sheets read output into one object per row, using row 1 as column names.
| Field | Description |
|---|---|
| Header row | Which row has column names (usually 1) |
| Include row number | Adds rowNumber for Update Row steps |
Place after Google Sheets → Read or any step that returns a values grid.
Sheet & email sequences
Built-in transforms for the Gmail Sheet Outreach pattern and similar multi-step campaigns. These use workflow variables like emailSequence, contactList, scanIndex, and sentEmails.
Filter Sequence Due
Keeps only contacts due today for their current step in variables.emailSequence (day 0 intro, day 3 follow-up, day 7 last try, etc.). Skips contacts who already received the intro or are marked active at step 0.
| Field | Default | Description |
|---|---|---|
| Status field | status | Column/property for contact status |
| Step field | step | Current sequence step (0 = intro, 1 = first follow-up, …) |
| First emailed field | first_emailed | Date intro was sent; used for follow-up timing |
| Exclude statuses | replied,unsubscribed,bounced | Never send to these statuses |
| Skip intro if already emailed | on | Step 0 requires empty first-emailed date |
| Skip intro if status is active | on | Step 0 skips rows already marked active |
Also requires variables.emailSequence on the workflow.
Expects an array of row objects from Sheet to Rows or similar upstream step.
Apply Sequence Copy
Applies subject and body from variables.emailSequence for the row’s current step, with {{name}}, {{company}}, etc. placeholders filled from the row.
| Field | Configuration |
|---|---|
| (none) | Requires variables.emailSequence |
Output includes subject, body, nextStep, needReplyCheck, and related fields.
Check Thread Reply
Detects whether a Gmail thread already has a reply from the contact’s email. Use before sending follow-ups.
| Field | Description |
|---|---|
| Contact email | Email to look for in thread From headers |
| Row number | Optional sheet row for downstream updates |
Input is usually the output of Gmail → Get Thread.
Scan Sequence Contact
Loop body for sheet-based email sequences. Walks a contact list by index and picks the next row due for its sequence step.
| Field | Description |
|---|---|
| Contact list from | Dropdown — upstream filter (e.g. Due for Sequence) |
These are set automatically (you do not configure them manually):
contactList,scanIndex,sentEmailsworkflow variables- Scan state tied to this node
Connect as the first output of a Loop node (loop body). The loop re-invokes this node until someone is ready to send or every row is checked.
Patch Sequence Scan
Runs after each send (and optional reply mark). Updates the in-memory contact list and advances the scan cursor, then loops back.
| Field | Description |
|---|---|
| Contact list from | Same source as Scan Sequence Contact |
Auto-wired from the canvas when possible:
- Pick contact node (Scan Sequence Contact)
- Send email node (Gmail → Send Email)
- Reply check node (Check Thread Reply)
- Restart from node → scan loop
Enable Restart from node on this transform (auto-enabled when the loop is detected). See Execution → Restart from a node.
Add or remove items
| Transform | What it does | Key fields |
|---|---|---|
| First Item | Pass only the first list item | — |
| Filter | Keep rows matching a condition | Property, operator, value |
| Filter Exclude From Variable | Remove rows whose property appears in a workflow variable list | Property, list variable (e.g. sentEmails) |
| Limit | Take first N items | Max items |
| Remove Duplicates | Deduplicate by fields | Compare fields, keep first/last |
| Split Out | Explode a nested array field into separate items | Field name |
Combine items
| Transform | What it does | Key fields |
|---|---|---|
| Aggregate List | Sum, average, count, min, max over a numeric field | Field, operation |
| Merge | Combine multiple inputs | Mode: append, merge by key, multiplex |
| Summarize | Group and aggregate (like pivot) | Group by, operations |
Convert data
| Transform | What it does | Key fields |
|---|---|---|
| Compression | Compress or decompress | Operation, format |
| Convert to File | Build file content from data | Format, filename |
| Crypto | Hash, HMAC, encrypt/decrypt | Algorithm, secret |
| Edit Image | Resize, crop, format conversion | Dimensions, format |
| Extract from File | Parse binary/file input | Format |
| HTML | HTML ↔ text conversions | Operation |
| Markdown | Markdown ↔ HTML | Operation |
| XML | Parse or build XML | Operation, paths |
| Rename Keys | Bulk-rename object keys | Key mappings |
| Sort | Sort array by field | Field, direction, type |
| Validate | Schema validation | Schema type, required fields |
| Sanitize | Trim strings, remove nulls/empties | Options toggles |
Choosing a transform
| I need to… | Use |
|---|---|
| Rename JSON fields | Edit Fields (Set) |
| Filter an array | Filter |
| Parse sheet rows | Sheet to Rows |
| Run custom JS on input | Code (simple) or Function (complex) |
| Email sequence from a sheet | Filter Sequence Due → Loop → Scan Sequence Contact → send → Patch Sequence Scan |
| AI-driven reshape | AI Transform |
| Validate API payload | Validate |
Sheet outreach pattern (no code)
The Gmail Sheet Outreach (No Code) template uses these transforms in order:
Read Sheet → Sheet to Rows → filters → Filter Sequence Due
→ Loop (Scan Contacts)
→ Scan Sequence Contact (loop body)
→ Contact Found? → Send Email → Update Row → Patch Sequence Scan (restart → loop)
Workflow variables to define in Settings → Variables:
{
"contactList": [],
"scanIndex": 0,
"sentEmails": [],
"emailSequence": [
{ "day": 0, "subject": "...", "body": "..." },
{ "day": 3, "subject": "...", "body": "..." },
{ "day": 7, "subject": "...", "body": "..." }
]
}
See the Cookbook for more end-to-end recipes.