Release notes
A workflow can call your own system
Highlight
A workflow can call your own system. Workflows decide and then act, apply a dispatch strategy, tag the order, notify the team, hand a step to an agent. Every one of those actions lands inside Nash. But the next step in an operation usually isn't: mark the order picked in the warehouse system, open a ticket, tell the ERP the delivery failed. That handoff has been yours to build, a webhook subscriber, a queue, a service to keep running, even when the decision that triggered it was already made in Nash.
The Send HTTP request action makes the call from inside the workflow. It comes in two halves on purpose.
- An administrator owns the connection. A connection holds the HTTPS origin, the credentials, which methods are allowed, the path prefix requests have to sit under, and the names of the request fields a workflow may set. Credentials are write-only: they never appear in a workflow's definition, and they're kept out of request logs and error reporting. So the person wiring up a workflow doesn't need, and never sees, the secret.
- A workflow author shapes the request. On the node you set a relative path, query parameters, headers, a JSON body, a timeout, and what the workflow does when the call fails. Templates work here like anywhere else, so the body can carry the order's own values.
- The branch after it reads the answer. Pull a value out of the response with a JSON Pointer and downstream filters see it alongside the HTTP status, how long the call took, and any failure detail, so the workflow can act on what your system actually said, not just on whether it answered.
- Background and best-effort, deliberately. One attempt, carrying a stable idempotency key so your endpoint can recognize a repeat. It's a signal your system can act on, not a durable queue, and it can't hold up a synchronous run.
See Call your own system.
New & improved
Orchestration
- Four triggers that fire against an order's own windows:
order_pickup_start_time,order_pickup_end_time,order_dropoff_start_time, andorder_dropoff_end_time, each with a direction and an offset in minutes, "30 minutes before the dropoff window ends". These are the triggers for the order that hasn't moved: a pickup due shortly with no provider on it, a dropoff window closing on a store that hasn't packed. Move the window and Nash re-arms against the new time. See Fire against a pickup or dropoff window. - One vocabulary for every message a workflow sends. Email, SMS, Slack, Teams, and voice-agent actions now read the same template catalog the notification triggers use, customer contact and address, pickup and dropoff ETAs, instructions, proof-of-delivery and tracking links, the assigned provider's Slack destination, the customer feedback link. The catalog hydrates the destination and the subject as well as the body, so a Teams channel or an SMS recipient can be a variable instead of a hard-coded address, and the editor suggests only variables that could plausibly address the channel you're filling in. See Writing text with variables.
- Conditions on dates and times work as dates and times. Datetime fields carry their own operators, including relative windows and comparing one datetime field against another, and evaluation is time zone aware, conditions that had been quietly evaluating false now resolve. A dispatch strategy is a field you can branch on, and a variable with no value hydrates to empty text rather than the literal word
None. See Comparing times. - Point a workflow at a custom event definition instead of typing its name.
customEventDefinitionIdis accepted on a workflow trigger, on theemit_custom_eventaction, and onPOST /v1/order/{id}/eventsand its job equivalent, Nash stamps the definition's key as the event name, so the catalog entry and the string the runtime matches on can't drift apart. A definition something is still listening for can't be archived, whether the listener is a workflow or a plain notification. See Match an event from your catalog.
Dispatch
- Hold a delivery's price at the fee you first accepted. A dispatch strategy can cap every later quote for the same work at the fee selected on the first assignment, across single deliveries, batches, and routes. A reassignment can come in cheaper and the ceiling stays where it was, so a delivery reassigned twice can't ratchet its way up; a refused quote is recorded with its reason rather than disappearing. (Opt-in, per dispatch strategy.) See Cost controls.
Fleet
- Keep your driver roster in step from your own system.
PUT /v1/fleet/drivers/upsertcreates or updates a driver keyed on your ownexternalIdentifier, no separate create and update to choose between, and a field you leave out keeps the value it had. The same call links vehicles, store locations, and driver groups, and provisions a driver-app login when you send an email address. Take a driver off the road by upsertingisShiftActive: false. See Upsert Driver. - Drivers on routes see their pay. The delivery card in the driver app showed stops, distance, and duration but no pay for drivers on routes, which batch drivers had all along. The same figure is now on the REST job response as
bonusPayCents, where webhooks already carried it. - A driver's package list says which stop it belongs to. The routes package list carries a
Stop 4 — <customer name>header, so a driver scanning a shelf knows whose order they're holding. - Set the Start Route gate from the Portal. The number of minutes before the earliest pickup a driver can start a route is now editable under My Fleet and per driver group, rather than needing someone at Nash to set it. Leave it off and there's no gate.
- Set geofence auto-arrival distances per driver group. The pickup and dropoff arrival radiuses now sit under Fleet › Driver Group › Features › Geofence in plain meters, instead of arriving through a CSV an engineer had to upload. Leave one blank and it stays unconfigured.
- Maps stop working when they aren't on screen. The route map kept rendering and tracking location behind stop details, the item list, the scan view, and navigation, two maps alive at once in the worst case. Drivers reported hot phones and battery drain; the map now freezes when it isn't visible.
Platform API
GET /v1/routesis in the API reference. List and search routes by date, status, driver, or free text, with pagination and a payload slim enough for a list view. See List Routes.
Integrations
- Frayt requests are paced to the 60 requests per second Frayt allows, and a throttled response is handled as throttling rather than logged as a failure.
- DoorDash receives the weighted price you set for it. A per-provider
valueCentsPerMeasurementUniton an inventory item's provider configuration was being read from the base item instead, so DoorDash quoted the base rate for weighted goods.
Portal
- Driver calls appear on the delivery timeline. A call a driver places from a stop, to the customer, the pickup, or support, is recorded as an event and shows on the delivery timeline, so a support conversation about "did anyone try to reach them" has an answer. Calls from the routes stop sheet were the ones going unrecorded.
- Edit a job that's been sent to a provider or manifested. Both statuses sit in the same pre-running family as the ones the Portal already let you edit, and the server never refused the edit, only the Portal did.
- A dispatch-and-manifest activity row says which store and carrier it was for. The row used to read
61 ordersand nothing else; it now leads with the store location and the provider, and the store filter reaches it. - Choose whether duplicating a job carries its dispatch strategy over. A new organization preference controls it; leave it alone and a duplicate inherits the source job's strategy the way it always has.
Nash Agent
- Send a scheduled report into a Microsoft Teams channel. Pick a connected team and channel as a report destination and Nash uploads the report's files there and posts them as an attachment. Teams connections made before this need to be reconnected once, because their stored permission doesn't cover uploading files.
- Answers cite their sources. When Nash reads a web page to answer you, the message carries a Sources list of the URLs it used.
Fixes
Dispatch
- A route's job dispatches on the strategy its contract names. A route optimized onto a shift and pinned to that shift's contract could still be won by a different provider, and a sibling batch that split into single deliveries could find no provider at all, leaving the orders stranded.
- A dispatch-and-manifest batch that couldn't manifest every order is reported as failed. One order failing out of sixty-one finished green, and the activity's terminal status notified nobody, so a trigger watching for a failed manifest run had never fired.
- Moving an order between routes doesn't blank its route. Detaching an order from a route it had already left cleared the pointer to the route that actually owned it, leaving a dispatched order with no route on it.
- An order that reports its own total volume keeps it. A package with no per-item dimensions fell back to Nash's default box, so orders carrying an aggregate volume were measured as that default and failed contract size and weight eligibility.
Platform
- An order that supplied its own pickup address keeps it. Re-validating an order without resending the address, on autodispatch, on a delivery-window booking, on a workflow revalidation, replaced the caller's address block and coordinates with the store location's own, so the job dispatched to the registered store address rather than the one the order named.
- A manifest sent late can't move a finished delivery backwards. Re-manifesting a batch after its shipments had been delivered rewrote them to Manifested, cleared the delivery description, and emitted a post-delivery
manifestedwebhook. - Every delivery in a batch gets an ETA, even when one stop is mid-reassignment. A stop whose task had no delivery yet stopped the ETA refresh for the entire batch, so the Portal kept showing stale times for all of them.
- Metadata containing double quotes is stored as you sent it. The REST path rewrote inner
"to'onjobMetadata,orderMetadata,packageMetadata, and several other JSON fields. - Metadata written to a package reaches its order. A key added to a package after dispatch stayed on the package.
- Two not-dispatched reminders fire at their own times. An organization with a 60-minute and a 30-minute order not dispatched trigger had both fire at the 60-minute mark and nothing at 30.
- A workflow filter accepts a fractional number. Comparing a weight or dimension field against a value like
226.8was legal per the published schema but unrepresentable, so a workflow built through the API took the false branch every time and said nothing about it. Workflows built in the Portal were unaffected. - A shift template saved without a cadence generates daily. It was stored as daily and run hourly, which produced a duplicate shift every hour of every day.
- Completing a return closes the route. A return marked complete from the Portal's job page reopened the finished return stop and reopened the route with it, so the driver app never cleared the route and the Portal kept showing the return as pending.
Portal
- Driver groups list for organizations whose internal fleet is run by a separate provider organization. Fleet › Driver Groups rendered empty for them, and a group created there vanished on save.
- An organization preference can be zero. A numeric preference set to
0rendered as an empty field, which matters where zero and unset mean different things. - A stop's delay is measured in the right time zone. A stop that arrived 39 minutes early could read as more than two hours late, off by the viewer's own UTC offset, and the late text is now legible in both light and dark themes.
- The shift-template CSV preview accepts the columns the upload accepts. A valid file showed a wall of validation errors and then uploaded successfully, which is worse than either outcome on its own.
- Expanding Package details doesn't remount the page. The content region flashed its loading state and re-rendered, which read as the dashboard reloading.
Integrations
- Couriers Please bookings produce their manifest. The manifest call was failing on a missing pickup time and swallowing the error, so it returned no documents and marked nothing manifested, a wrong answer rather than a visible failure. A booking with no pickup time is now refused outright.
- Uber deliveries that end in a timeout after dropoff arrival, or in a merchant cancellation, are marked inactive. Three final-status branches settled the status without clearing the active flag, so the delivery read as still running.
- CBD webhooks reach their delivery again. A change to the reference Nash sends on each stop broke both lookup keys at once, so status updates from CBD were dropped from 20 August until this fix.
- A split Shopify cart is quoted once. Shopify prices a multi-location cart by asking per group and summing the answers, so a cart split three ways showed the customer three times the fee, and a free-delivery threshold was measured against one group rather than the whole cart, so carts over the threshold were charged.
- A Shopify pickup order uses the buyer's phone number. Pickup orders fell back to the store's own number, so notifications went to the merchant instead of the customer.
- DeliveryApp deliveries that end in a cancellation, failure, expiry, or return pick up their final pricing. The delayed pricing refresh only ran for completed dropoffs, so later fee changes on every other outcome were missed.
Fleet
- The routes list refreshes after you unassign a delivery. The screen kept showing the route as assigned until something else refetched it.
- A stop shows the order's external ID when it has no reference ID. Stop details rendered neither, so an order identified only by its external ID showed nothing to identify it by.
Nash Agent
- Elapsed times are computed against one clock. Two parts of the agent's own instructions disagreed about which timestamp counted as "now", so it could subtract a store-local time from a UTC clock and report an age off by the store's offset, differently from one run to the next.
- A scheduled watch serves a check that arrives mid-run. A wake landing while the watch's first run was still working was recorded and never served, so the follow-up waited out the full interval instead of running when it was due; stale ones are now swept up rather than left sitting.
- An agent named for the thing it does can finish its run. Guardrail keyword matching read an agent whose name contains a word like refund or cancel as taking a customer action and parked its own internal submission behind a confirmation nobody could answer, until the run ran out of time.
- A question or confirmation card stays at the end of the turn it belongs to, with its explanation above it, and answers you've already submitted survive the card re-rendering.