How to Build a SmartFreight Carrier Cost Comparison Report

Build a Spojit workflow that runs on a weekly schedule, compares carrier costs across your recent SmartFreight consignments, writes a CSV summary, uploads it to an FTP server, and emails the finance team a link with the Resend connector.

What This Integration Does

If you ship with multiple carriers through SmartFreight, the cheapest carrier varies consignment by consignment, depending on destination, weight, and dimensions. Manually pulling cost comparisons for every shipment is slow, so most teams never check whether they are paying more than they need to. This Spojit workflow does it for you: every week it finds your recent consignments, asks SmartFreight to compare carrier costs for each one, rolls the numbers into a single CSV, parks that CSV on your FTP server, and emails finance a short note with where to find it. Finance gets a recurring, auditable freight-cost report without anyone touching SmartFreight directly.

The workflow is started by a Schedule trigger on a weekly cron. On each run it queries SmartFreight for recent consignments, loops over them calling the SmartFreight cost-comparison tool, transforms the per-consignment results into rows, builds a CSV with the csv connector, uploads that file to FTP with a date-stamped name, and sends one email through the Resend connector. Each run leaves a new timestamped CSV on the FTP server and one email in the finance inbox, so re-runs never overwrite history: a re-run for the same week simply produces a fresh file alongside the previous one (or overwrites it if you reuse the exact same filename).

Prerequisites

  • A SmartFreight connection in Spojit (Connections -> Add connection -> SmartFreight) with valid API credentials, and at least a few consignments already created in SmartFreight so there is data to compare.
  • An FTP connection with write access to the directory where reports should land (for example /reports/freight/).
  • A Resend connection with a verified sending domain, so emails can be sent from your own address.
  • The finance recipients' email addresses, and a known FTP path or download URL convention you can reference in the email body.
  • Familiarity with which SmartFreight consignment field identifies "recent" shipments for your account (for example a receiver account number, or a status field) so the search returns the right set.

Step 1: Add the Schedule trigger

Start a new workflow and set its Trigger node type to Schedule. A Schedule trigger uses a 5-field Unix cron expression plus an IANA timezone. For a Monday 7am weekly run in Sydney, use:

0 7 * * 1
Australia/Sydney

The cron 0 7 * * 1 fires at 07:00 every Monday. The trigger output is { scheduledAt }, which you can reference downstream as {{ trigger.scheduledAt }} when you want the run date in the filename or email. A single Schedule trigger can hold more than one schedule if you later want a second cadence.

Step 2: Find recent consignments in SmartFreight

Add a Connector node in Direct mode, choose the SmartFreight connector, and select the find-consignment tool. This searches consignments by a field name and value and returns matching consignment IDs. Set xmlfield to the SmartFreight field that identifies your set (for example recaccno for a receiver account number) and fieldvalue to the value to match:

xmlfield:   recaccno
fieldvalue: 100245

Map the node's output to a variable such as foundConsignments. You will iterate over the returned consignment IDs in the next step. If your account distinguishes "recent" shipments by a status or date field instead, search on that field name instead, since find-consignment accepts any consignment field name.

Step 3: Loop over consignments and run the cost comparison

Add a Loop node set to ForEach and point it at the list of consignment IDs from {{ foundConsignments }}. Inside the loop body, add a Connector node in Direct mode using the SmartFreight connector and the cost-comparison tool. This compares shipping costs across multiple carriers for a single consignment.

The cost-comparison tool takes a consignment object (the connote fields, including receiver address and freight details). If your search returned only IDs, add a Connector node before it using the SmartFreight get-consignment tool, passing the loop item as conid, to fetch the full consignment detail, then feed that detail into cost-comparison:

// get-consignment
conid: {{ item.conid }}

// cost-comparison
consignment: {{ getConsignmentResult.data }}

Map the comparison output to a per-iteration variable such as comparison. Collect each iteration's result so the whole set is available after the loop completes.

Step 4: Transform the results into report rows

After the loop, add a Transform node to reshape the collected comparison results into a flat array of objects, one row per consignment, with the columns finance cares about. Pull the carrier names and quoted costs out of each comparison result and pick the cheapest. A representative shape:

[
  {
    "consignmentId": "C-100245-001",
    "receiver": "Acme Pty Ltd",
    "cheapestCarrier": "Carrier A",
    "cheapestCost": 18.40,
    "highestCost": 27.10,
    "potentialSaving": 8.70
  }
]

Keep the field names stable, since they become the CSV header in the next step. If you prefer, you can do the shaping with the json connector's pick and merge tools instead of a Transform node, but a single Transform node keeps the mapping readable in one place.

Step 5: Build the CSV file

Add a Connector node in Direct mode, choose the csv connector, and select the from-json tool to convert your array of row objects into CSV text. Pass the transformed rows as the input. The object keys become the header row and each object becomes a data row.

// csv from-json
input: {{ reportRows }}

Map the output (the CSV text) to a variable such as csvText. If you want to sort the report so the largest potential savings appear first, run the csv sort tool on the result before uploading, sorting by the potentialSaving column in descending order.

Step 6: Upload the CSV to FTP

Add a Connector node in Direct mode with the FTP connector and the upload-file tool. Set path to a date-stamped destination so each run lands a distinct file, set content to the CSV text, and use the default utf8 encoding since CSV is text:

path:     /reports/freight/cost-comparison-{{ trigger.scheduledAt }}.csv
content:  {{ csvText }}
encoding: utf8

To build a clean date string for the filename, run the date connector's format tool on {{ trigger.scheduledAt }} first (for example a YYYY-MM-DD pattern) and reference that formatted value in path. The upload-file tool overwrites if the file already exists, so a unique date in the name preserves history across weeks.

Step 7: Email finance with the Resend connector

Add a final Connector node in Direct mode, choose the Resend connector, and select the send-email tool. Resend sends from your own verified domain. Set from to your finance-report sender, to to the finance recipients, a clear subject, and an html body that points to the uploaded file:

from:    Freight Reports <reports@yourdomain.com>
to:      finance@yourcompany.com
subject: Weekly carrier cost comparison - {{ reportDate }}
html:    <p>This week's SmartFreight carrier cost comparison is ready.</p>
         <p>File: /reports/freight/cost-comparison-{{ reportDate }}.csv</p>

If your team prefers a direct download link rather than an FTP path, include the URL convention your FTP host exposes in the body. Resend's send-email also supports cc, reply_to, and attachments, so you can attach the CSV directly instead of, or in addition to, linking it. If you would rather send from Spojit's built-in mail service without a Resend connection, you can swap this step for a Send Email node, though that requires external recipients to be on your org allowlist.

Tips

  • Use a date format step once near the top and reuse the formatted value in both the FTP path and the email subject, so the filename and the email always agree.
  • Sort the CSV by potential saving descending so the rows worth acting on are at the top of finance's report.
  • If you have many consignments, keep the loop body lean: only call get-consignment when find-consignment returns IDs rather than full records, and avoid re-fetching the same consignment twice.
  • Ask Miraxa, the intelligent layer across your automation, to scaffold this for you with a prompt like "Build a weekly Schedule workflow that loops SmartFreight consignments, runs cost-comparison, writes a CSV, uploads it to FTP, and emails finance with Resend," then fine-tune each node in the properties panel.

Common Pitfalls

  • Empty search results. If find-consignment returns nothing, the report and email will be empty. Add a Condition node after the search to skip the email when the consignment list is empty, or send a "no consignments this week" note instead.
  • Timezone drift. The Schedule cron runs in the IANA timezone you set, not the viewer's. Confirm the timezone (for example Australia/Sydney) so the weekly run and the date in the filename line up with your finance week.
  • Overwritten files. The FTP upload-file tool overwrites an existing path. If your filename is not unique per run, last week's report is lost: always include the run date in path.
  • Unverified Resend domain. Resend will not deliver from a domain that is not verified. Confirm your sending domain is verified on the connection before relying on the weekly email.

Testing

Before turning on the weekly schedule, validate on a small scope. Temporarily narrow the find-consignment search to a single known consignment, then use the Run button to execute the workflow once on demand. Check the run history to confirm the loop produced one comparison, the csv step generated readable rows, the file appeared on FTP at the expected path, and finance received the email. Once the single-consignment run looks correct end to end, widen the search back to your full recent set and let the Schedule trigger take over.

Learn More

Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.