How to Export Daily Shipment Reports to CSV via FTP
Generate daily shipping reports in CSV format and upload them to your FTP server.
What This Integration Does
Operations teams, finance, and 3PL partners often need a daily shipment manifest delivered as a CSV. Pulling it manually from a shipping platform every morning is tedious and skip-prone. This workflow queries the shipping platform for the previous day's shipments, flattens them into a CSV, and uploads the file to an FTP drop folder so downstream systems can ingest it on their own schedule.
The workflow is schedule-driven and stateless. Each run computes its own date window, fetches the shipments inside that window, and writes a dated CSV. Re-running for the same window just produces the same file (with a different upload timestamp if your filename pattern includes the run time), so backfills are safe.
Prerequisites
- A ShipStation connection, or a DHL Express connection for direct-from-carrier reporting.
- An FTP connection with write access to the destination directory.
- An agreed column schema with whoever consumes the CSV (finance, BI, 3PL).
Step 1: Schedule Trigger
Add a Trigger node and set its type to Schedule. 06:00 store-local is a typical cadence - it gives your warehouse all night to scan packages and ensures the file is on the FTP server before downstream jobs kick off. The trigger's now value is the anchor for the rest of the workflow's date math.
Step 2: Compute the Report Window
Drop a Transform node to compute the previous day's bounds. Use the date connector's subtract and start-of / end-of tools:
reportDay-{{ trigger.now }}minus one day.windowStart-start-ofday onreportDay.windowEnd-end-ofday onreportDay.
Step 3: Fetch Shipments
Add a Connector node pointing at shipstation and pick the list-shipments tool. Configure:
shipDateStart:{{ windowStart }}shipDateEnd:{{ windowEnd }}pageSize:500
For DHL-only reporting, use a Connector node on dhl-express with the track-shipment tool against each tracking number you have on file - typically driven from a list pulled from your order database. ShipStation is the simpler option if it already aggregates your carriers.
Step 4: Flatten for Reporting
Add a Transform node to project each shipment into a flat row matching the consumer's schema:
{
"ship_date": "{{ shipment.shipDate }}",
"order_number": "{{ shipment.orderNumber }}",
"carrier": "{{ shipment.carrierCode }}",
"service": "{{ shipment.serviceCode }}",
"tracking_number": "{{ shipment.trackingNumber }}",
"weight_oz": "{{ shipment.weight.value }}",
"shipping_cost": "{{ shipment.shipmentCost }}",
"destination_country": "{{ shipment.shipTo.country }}"
}
Step 5: Convert to CSV
Add a Connector node pointing at csv and pick the from-json tool. Pass the array from Step 4 and set includeHeaders to true. Capture the output string as csvBody.
Step 6: Upload via FTP
Add a Connector node pointing at ftp and pick the upload-file tool. Configure:
remotePath:/reports/shipments/shipments-{{ reportDay | date "YYYY-MM-DD" }}.csvcontent:{{ csvBody }}
Wire a Condition node on the response. On failure, branch to slack send-message with the error details so the team can replay before downstream jobs miss the file.
Tips
- One run, one file - dated filenames make missed days obvious. Avoid a single
shipments.csvthat gets overwritten every day. - Empty days happen - quiet weekends produce zero shipments. Decide up front whether to skip the upload or write a headers-only file; either is valid as long as the consumer agrees.
- Match carrier codes - downstream finance systems often map carrier codes to GL accounts. Lock the mapping early so it doesn't drift.
Common Pitfalls
- Timezone slips - ShipStation's
shipDateis account-local. If you pass a UTC window you'll either over-report or under-report by a few hours' worth of shipments. - Pagination - busy days exceed a single page. Loop the
list-shipmentscall until the result page returns fewer rows thanpageSize. - CSV character encoding - some FTP consumers expect Windows-1252; the csv
from-jsontool emits UTF-8. Convert with the encoding connector if the partner insists.
Testing
Run the workflow manually for yesterday's date and download the file from the FTP server. Open it in a spreadsheet and reconcile a sample of rows against ShipStation's UI. Once the totals match, turn the schedule on.