Routing and Fulfillment Actions

Karl Falconer ·

These are the actions that direct where and when an order ships. They’re the workhorses of order routing.

Action Purpose
route Send the order (or a single line) to a specific warehouse.
bundle Group orders together and ship them as a bundle.
hold Delay an order until a future time or duration.
split Break an order into multiple orders based on a condition.

route

route sends an order or line item to a specific warehouse in your account, optionally specifying a facility within that warehouse.

Build route rules in the visual editor. It shows your warehouses by name in a dropdown, so you pick the destination directly. Writing route by hand in the code editor isn’t recommended.

A typical routing rule, as the editor produces it:

when
  order.shipping_address.country is "CA"
then
  route order to warehouse 2
end

In the visual editor, the “warehouse 2” part appears as a dropdown of named warehouses — you choose “Canadian Warehouse” (or whatever you’ve named yours) and the editor handles the rest.

For warehouse platforms that support multiple facilities, you can target a specific facility:

when
  order has any order_lines with (order_line.gift_wrap)
then
  route order to warehouse 2 / "Gift Wrap Station"
end

The facility name (here "Gift Wrap Station") is platform-specific and must match the value the warehouse platform expects. Different platforms encode facilities differently — check the warehouse’s connection settings in DropStream for the supported values.

You can also route a single line item rather than a whole order, which is how you split fulfillment across multiple warehouses. See the combinations example below.

bundle

bundle groups multiple orders together so they can ship as one shipment. You give it a key (orders with the same key bundle together) and a duration to wait for more orders before shipping.

bundle order using order.customer_email waiting 1h

This says: hold the order, wait up to 1 hour, and ship it together with any other orders from the same customer email that arrive in that window.

You can also specify a sort order within the bundle:

bundle order using order.shipping_address.postal_code waiting 2h sequencing order.ordered_at

The sequencing clause sorts the bundled orders by the named field — useful when warehouse processing should follow a specific order (oldest first, by time, etc.).

The full form is:

bundle <model> using <key_expression> waiting <duration> [sequencing <field_expression>]
Part Meaning
using <expr> The key. Orders with the same key value bundle together.
waiting <duration> How long to wait for additional orders before sending the bundle. Units like 1h, 2D (see Dates and Times).
sequencing <expr> Optional. Sort the bundled orders by this expression.

hold

hold delays an order until a future time or for a duration.

Hold until a specific time:

hold order until 1D after @now
hold order until order.requested_ship_date
hold order until @monday at @T08:00:00

Hold for a duration:

hold order waiting 2h
hold order waiting 1D

The two forms aren’t interchangeable — until takes a date/time, waiting takes a duration.

A common use is to align order release with a fulfillment schedule:

when
  order.ordered_at is_on @friday
  and order.shipping_carrier_service_level is "Standard"
then
  hold order until @monday at @T08:00:00
end

Friday standard orders wait until Monday morning.

For date literals (@now, @today, @monday, etc.) and durations (1h, 2D, etc.), see Dates and Times.

split

split breaks one order into multiple orders based on a condition. Items where the condition is true go to one new order; items where it’s false stay on the original.

when true then
  split order with order_line.gift_wrap
end

This produces two orders: one containing all the gift-wrap items, and the original (now stripped of those items).

Splitting is useful when different parts of an order need to ship separately — items needing special handling to one warehouse, regular items to another, or items with different ship dates.

Splitting is generally a last resort because it creates additional records to manage. Where possible, prefer routing different lines to different warehouses within a single order.

Combinations

Routing actions can combine with each other and with filter actions:

rule "Inventory-aware routing"
  for order_lines in order
    for inventories in order_line
      when
        inventory.available >= order_line.qty_ordered
        and inventory.warehouse_id is "PRIMARY"
      then
        route order_line to warehouse inventory.warehouse_id
        accept order_line
      end
    end
  end

  default reject order_line
end

For each line, find a warehouse with enough inventory and route there. Anything we didn’t route, reject.

This pattern works directly in the code editor because the warehouse comes from the inventory record (inventory.warehouse_id) — you’re not picking it by hand, you’re using whichever warehouse the inventory is at.

Tips

  • Build route rules in the visual editor. It picks warehouses from a named dropdown — quicker, and you don’t have to look anything up.
  • Facility codes are platform-specific. The / "facility" part is only used by warehouse platforms that expose multiple facilities, and the value must match the platform’s exact coded name. Check the warehouse’s connection settings for the supported values.
  • bundle is timed. The waiting duration is real-world time. A short value (e.g. 5m) creates near-immediate bundles; a longer one (e.g. 1D) creates batched shipments.
  • hold blocks fulfillment. Use it sparingly — held orders aren’t visible in the warehouse’s queue until the hold expires.
  • Test routing decisions in the trace harness. It’s the fastest way to confirm the rule routed an order the way you expected — the trace shows the resolved warehouse ID and lets you sanity-check it.
Was this article helpful?
0 out of 0 found this helpful

Comments

0 comments

Please sign in to leave a comment.