File step
Write or fetch CSV and JSON files, in cloud storage or over FTP, FTPS and SFTP.
The File step writes a CSV or JSON file and uploads it to cloud storage or to your own FTP, FTPS or SFTP server. It can also fetch a file and read it into a variable. Use it for nightly exports, supplier feeds and anything else that's easier to hand over as a file.
Operations
| Operation | What it does |
|---|---|
| Write | Builds the whole file from a variable and uploads it in one go. |
| Open | Starts a file you'll add to over several steps. Give it a Handle. |
| Append | Adds rows from a variable to an open file. |
| Close | Finishes an open file and uploads it. |
| Fetch | Downloads a CSV or JSON file from a URL or an FTP, FTPS or SFTP server and reads it into the response variable. |
Open, Append and Close let you stream big exports: open the file, let Fetch all pages write each page into it through its File handle, then close it.
Set it up
| In the app | data field | What it does |
|---|---|---|
| Operation | operation | Write, Open, Append, Close or Fetch. |
| Handle | handle | Open, Append, Close: the name later steps use for this file, like orders_csv. |
| Format | format | CSV, JSON (one array) or NDJSON (one object per line). Fetch also has Auto. |
| Source | source | Write, Append: the variable or dot path holding the rows, like rows or orders.items. |
| Columns | columns | CSV: the columns in order. Each has a Path, plus an optional Header and Join (for arrays, like , ). Leave empty to use the first row's fields. |
| Explode array path | explode | Append: one row per element of this array on each row. |
| Keep rows with no lines | explode_keep_empty | With Explode array path, keeps a row whose array is empty. |
| No header row | no_header | CSV: leave out the header row (or, for Fetch, don't expect one). |
| Destination | destination | Cloud storage (the default), FTP, FTPS or SFTP. Fetch also has URL. |
| Filename | filename | The file name or remote path. Liquid works, so a script can build it and you put {{ filename }} here. |
| Content type | content_type | Cloud storage only. |
| Host, Port, Username, Password | host, port, username, password | FTP, FTPS and SFTP. Port defaults to 21 (22 for SFTP). |
| Private key, Private key passphrase | private_key, private_key_passphrase | SFTP key login. |
| Host key | host_key | SFTP: the server's key or SHA256: fingerprint. Leave it empty on the first run and the step warns with the server's fingerprint, ready to copy in. |
| Skip TLS verify | tls_skip_verify | FTPS only, for servers with a self-signed certificate. |
| Response variable | response_variable | Saves the result. |
Keep logins in private dataDon't type passwords or keys into the step. Store them in private data, read them with an API Request (Get Private Data) and a Script step, and use
{{ ftp_password }}in the field.
What it saves
- Write and Close save
{destination, path, rows, bytes}, plusurlfor cloud storage orhostfor FTP, FTPS and SFTP. - Fetch saves what it read: for CSV, an array with one object per row, keyed by the header (or one array per row with No header row); for JSON and NDJSON, the parsed data. With Auto, a
.csvname is read as CSV, and anything starting with[or{as JSON.
Limits
- Files can be up to 10 MB.
- Explode array path can produce up to 100,000 rows in one step. More fails with
explode: more than 100000 rows in one step. - A handle has to be opened before you append to or close it, and each handle can only be open once.
How retries work
Write and Close are the steps that publish the file. A top-level Write or Close that already succeeded isn't repeated when the job is retried, and nor are the steps that fed that file. Open and Append run again, and an upload that was never closed is thrown away rather than half-published.
Example 1: Export open order lines
Trigger: Scheduled.
- Shopify GraphQL: Fetch every order page, with Fetch all pages on, Response variable
orders(see Fetch all pages). - Transform Data: Keep the open lines, Source
orders.items, with a Filter and a Map that buildsorder,skuandquantity. Response variablelines. - File: Write the export, Operation Write, Format CSV, Source
lines, Columnsorder,sku,quantity, Destination Cloud storage, Filenameopen-lines.csv, Response variableexport. - Send Notification: Send a Slack message with
Open lines: {{ export.url }}.
Example 2: Send every product or sale to your FTP server
This is the nightly FTP export pattern: get the login from private data, open the file, stream every page into it, then close it.
Trigger: Scheduled.
-
API Request: Get Private Data, Key
ftp_export, Response variableftp_res. Store JSON like{"host": "ftp.example.com", "username": "export", "password": "…"}there. -
Script: Build the request
var ftp = JSON.parse(JSON.parse($.ftp_res.body).ftp_export); $.ftp_host = ftp.host; $.ftp_user = ftp.username; $.ftp_password = ftp.password; $.filename = "sales-" + new Date().toISOString().slice(0, 10) + ".csv"; -
File: Open the export, Operation Open, Handle
export, Format CSV, Columnsid,receipt_number,store_id,total_price, Destination FTP (or FTPS or SFTP), Host{{ ftp_host }}, Username{{ ftp_user }}, Password{{ ftp_password }}, Filename{{ filename }}. -
API Request: Fetch every page, endpoint List Sales (or Get Products for a product export), Fetch all pages on, File handle
export. Each page is appended to the file as it arrives. -
File: Close the export, Operation Close, Handle
export, Response variableexport_res. -
If Condition: If the file has rows, Condition
$.export_res.rows > 0, with a Send Notification under THEN.
To get one row per sale line, set Explode array path to lines on the fetch step, and use columns like id, lines.item_id and lines.quantity.
Updated about 23 hours ago
