Skip to content

Stops & Tracks

Stops and tracks define the structure and flow of your routes. Understanding how they work together is key to building effective workflows.

Stops

A stop is an instance of visiting a station within a route. While a station is a reusable definition, a stop is the actual occurrence in a specific route.

type Stop {
id: ID!
type: StopType
stationId: ID
name: String
status: String
station: Station
asynchronousChildren: Boolean
}

Stop Types

TypeDescription
stationA regular station stop
portalA connection to an external system
routeA reference to another route

Stop Status

Stops track their completion status:

  • Pending: Not yet completed
  • Completed: Marked as done

Tracks

The track is a JSON structure that defines how stops are connected and ordered. It represents the “railway” that connects all the stops in your route.

# The track field in Route and RouteTemplate
track: AWSJSON

The track structure supports:

  • Linear sequences: Stops that must be completed in order
  • Parallel branches: Stops that can be completed simultaneously
  • Nested structures: Complex hierarchies of stops

Building Route Structures

Linear Route

A simple sequence where each stop follows the previous:

mutation CreateLinearRoute {
addRoute(input: {
name: "Linear Process"
instructions: [
{
trackType: stop
action: startWith
actionStationOrRouteTemplateId: "step-1-station"
},
{
trackType: stop
action: addAfter
actionStationOrRouteTemplateId: "step-2-station"
actionTargetStopId: "step-1-stop-id"
},
{
trackType: stop
action: addAfter
actionStationOrRouteTemplateId: "step-3-station"
actionTargetStopId: "step-2-stop-id"
}
]
}) {
id
track
}
}

Visual representation:

[Step 1] → [Step 2] → [Step 3]

Parallel Branches

Create branches where multiple stops can be completed independently:

mutation CreateParallelRoute {
addRoute(input: {
name: "Parallel Review"
instructions: [
{
trackType: stop
action: startWith
actionStationOrRouteTemplateId: "start-station"
enableAsynchronousChildren: true
},
{
trackType: stop
action: addAsFirstChild
actionStationOrRouteTemplateId: "review-a-station"
actionTargetStopId: "start-stop-id"
},
{
trackType: stop
action: addAsLastChild
actionStationOrRouteTemplateId: "review-b-station"
actionTargetStopId: "start-stop-id"
},
{
trackType: stop
action: addAsLastChild
actionStationOrRouteTemplateId: "review-c-station"
actionTargetStopId: "start-stop-id"
}
]
}) {
id
track
}
}

Visual representation:

┌→ [Review A]
[Start] ───┼→ [Review B]
└→ [Review C]

Mixed Structure

Combine linear and parallel sections:

mutation CreateMixedRoute {
addRoute(input: {
name: "Mixed Workflow"
instructions: [
{
trackType: stop
action: startWith
actionStationOrRouteTemplateId: "intake-station"
},
{
trackType: stop
action: addAfter
actionStationOrRouteTemplateId: "triage-station"
actionTargetStopId: "intake-stop"
enableAsynchronousChildren: true
},
{
trackType: stop
action: addAsFirstChild
actionStationOrRouteTemplateId: "tech-review-station"
actionTargetStopId: "triage-stop"
},
{
trackType: stop
action: addAsLastChild
actionStationOrRouteTemplateId: "legal-review-station"
actionTargetStopId: "triage-stop"
},
{
trackType: stop
action: addAfter
actionStationOrRouteTemplateId: "final-approval-station"
actionTargetStopId: "triage-stop"
}
]
}) {
id
track
}
}

Visual representation:

┌→ [Tech Review] ──┐
[Intake] → [Triage] ┤ ├→ [Final Approval]
└→ [Legal Review] ─┘

Instruction Actions Reference

startWith

Creates the first stop in a route. Every route must have exactly one startWith instruction.

{
trackType: stop
action: startWith
actionStationOrRouteTemplateId: "station-id"
}

addAfter

Adds a stop immediately after another stop in the sequence.

{
trackType: stop
action: addAfter
actionStationOrRouteTemplateId: "station-id"
actionTargetStopId: "target-stop-id"
}

addBefore

Adds a stop immediately before another stop.

{
trackType: stop
action: addBefore
actionStationOrRouteTemplateId: "station-id"
actionTargetStopId: "target-stop-id"
}

addAsFirstChild

Adds a stop as the first child of a parent stop (for parallel execution).

{
trackType: stop
action: addAsFirstChild
actionStationOrRouteTemplateId: "station-id"
actionTargetStopId: "parent-stop-id"
}

addAsLastChild

Adds a stop as the last child of a parent stop.

{
trackType: stop
action: addAsLastChild
actionStationOrRouteTemplateId: "station-id"
actionTargetStopId: "parent-stop-id"
}

replace

Replaces an existing stop with a different station.

{
trackType: stop
action: replace
actionStationOrRouteTemplateId: "new-station-id"
actionTargetStopId: "stop-to-replace-id"
}

remove

Removes a stop from the route.

{
trackType: stop
action: remove
actionTargetStopId: "stop-to-remove-id"
}

Asynchronous Children

The enableAsynchronousChildren flag on a stop indicates that its children can be completed in any order or simultaneously.

{
trackType: stop
action: startWith
actionStationOrRouteTemplateId: "station-id"
enableAsynchronousChildren: true # Children are parallel
}

Without this flag, children must be completed in order (first child before second child, etc.).

Stop Data in Queries

When querying routes, you can access detailed stop information:

query GetRouteStops {
getRoute(id: "route-123") {
stops {
id
name
type
status
stationId
asynchronousChildren
station {
id
name
description
remotePortalId
}
}
}
}

Completing Stops

Mark Complete

mutation MarkComplete {
markStopCompleted(
routeId: "route-123"
stopId: "stop-456"
) {
stops {
id
status
}
}
}

Revert Completion

mutation RevertComplete {
unMarkStopCompleted(
routeId: "route-123"
stopId: "stop-456"
) {
stops {
id
status
}
}
}

Best Practices

Keep Tracks Simple

Start with simple linear tracks and add complexity only when needed. Overly complex track structures can be difficult to manage and understand.

Use Meaningful Stop Names

Stops inherit names from their stations, but you can query the full station details for more context.

Monitor Parallel Progress

When using asynchronous children, query the route regularly or use subscriptions to track which parallel branches have completed.

Plan for Modifications

Design your tracks with potential changes in mind. Using addAfter and addBefore makes it easier to insert new stops later.