Skip to main content

Dispatch Routing GraphQL

Dispatch routing GraphQL covers route statuses, stop statuses, reusable route templates, daily dispatch routes, route stops, and scheduled template-to-route generation.

Enums

GraphQL enum values use PascalCase names:

  • DispatchRouteType: Delivery, Pickup
  • StatusStage: Pending, InProgress, Completed
  • DayOfWeek: Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday

Queries

query {
dispatchRouteStatuses(organizationId: 1, search: "Pending", orderBy: "priority") {
items { dispatchRouteStatusId statusName statusStage routeType priority color }
}

dispatchRouteStopStatuses(organizationId: 1, search: "Arrived", orderBy: "priority") {
items { dispatchRouteStopStatusId statusName statusStage stopType priority color }
}

dispatchRouteTemplates(organizationId: 1, search: "Monday", orderBy: "name") {
items {
dispatchRouteTemplateId
name
routeType
daysOfWeek
enabled
stops { dispatchRouteTemplateStopId sequence stopContactId stopType estimatedServiceMinutes }
}
}

dispatchRoutes(organizationId: 1, search: "Monday", orderBy: "routeDate") {
items {
dispatchRouteId
name
routeType
routeDate
isDraft
dispatchRouteStatus { statusName statusStage }
stops {
dispatchRouteStopId
plannedSequence
stopContactId
stopType
dispatchRouteStopStatusId
dispatchRouteStopStatus { statusName statusStage }
orderIds
trackingEvents {
eventDate
eventDefinition { name }
}
}
}
}
}

Stop Status Mutations

mutation {
createDispatchRouteStopStatus(input: {
organizationId: 1
values: {
statusName: "Arrived"
statusDescription: "Driver has arrived at the stop"
statusStage: InProgress
stopType: Delivery
priority: 20
color: "#22C55E"
}
}) {
dispatchRouteStopStatus { dispatchRouteStopStatusId statusName statusStage stopType priority }
}
}

mutation {
updateDispatchRouteStopStatus(input: {
organizationId: 1
dispatchRouteStopStatusId: 75
values: { statusName: "Completed", statusStage: Completed, priority: 30 }
}) {
dispatchRouteStopStatus { dispatchRouteStopStatusId statusName statusStage priority }
}
}

mutation {
deleteDispatchRouteStopStatus(input: { organizationId: 1, dispatchRouteStopStatusId: 75 }) {
deleteResult { rowsAffected }
}
}

Stop statuses are organization-scoped dictionaries. stopType can be Delivery, Pickup, or null for shared statuses. A status in use by any stop cannot be deleted.

Template Mutations

mutation {
createDispatchRouteTemplate(input: {
organizationId: 1
values: {
name: "Monday/Wednesday/Friday Route A"
routeType: Delivery
daysOfWeek: [Monday, Wednesday, Friday]
enabled: true
stops: [
{ stopContactId: 101, estimatedServiceMinutes: 15 }
{ stopContactId: 105, stopType: Pickup }
]
}
}) {
dispatchRouteTemplate { dispatchRouteTemplateId stops { sequence stopType } }
}
}

Stop maintenance uses dedicated mutations: addDispatchRouteTemplateStop, updateDispatchRouteTemplateStop, reorderDispatchRouteTemplateStop, and removeDispatchRouteTemplateStop. Dynamic template updates also accept a full replacement stops array: existing stop IDs are sparse-updated, new entries are inserted, omitted existing entries are soft-deleted, and sequences are reassigned from array order.

Route Mutations

mutation {
createDispatchRoute(input: {
organizationId: 1
values: {
name: "Monday Delivery Run"
routeType: Delivery
routeDate: "2026-06-16"
dispatchRouteStatusId: 50
driverContactId: 1001
equipmentId: 500
isDraft: true
stops: [
{ stopContactId: 101, estimatedServiceMinutes: 15, dispatchRouteStopStatusId: 75, orderMoveId: 410, orderIds: [9001] }
{ stopContactId: 105, stopType: Pickup, estimatedServiceMinutes: 10, orderIds: [9002, 9003] }
]
}
}) {
dispatchRoute {
dispatchRouteId
name
isDraft
stops {
plannedSequence
stopType
stopContactId
dispatchRouteStopStatus { statusName statusStage }
orderIds
orders { dispatchRouteStopOrderId orderId }
}
}
}
}

mutation {
activateDispatchRoute(input: { organizationId: 1, dispatchRouteId: 200 }) {
dispatchRoute { dispatchRouteId isDraft dispatchRouteStatus { statusName } }
}
}

Stop maintenance uses addDispatchRouteStop, updateDispatchRouteStop, reorderDispatchRouteStop, and removeDispatchRouteStop. updateDispatchRouteStop accepts a dynamic values map and changes only the supplied keys: explicit null clears nullable fields and omitted keys remain unchanged. In particular, callers can stamp or clear actualArrivalTime and actualCompletionTime independently. Unknown keys are rejected.

addDispatchRouteStop, updateDispatchRouteStop, route creation, and dynamic route updates accept dispatchRouteStopStatusId and orderIds on stop values. Route creation also accepts an optional orderMoveId for each nested stop, linking the newly created stop to the move it executes. A provided stop status is validated against the organization and stop type, while a provided orderIds list is validated against the organization and reconciles the stop's attached orders to exactly those IDs. Dynamic route updates also accept a full replacement stops array: existing stop IDs are sparse-updated, new entries are inserted, omitted existing entries are soft-deleted, and planned sequences are reassigned from array order.

A stop exposes its parent through the expandable dispatchRoute object. A stop tied to an order move also exposes both orderMoveId and the expandable orderMove object. The inverse orderMove.dispatchRouteStops navigation makes it possible to traverse from a planned move to all trip stops executing it, including stops on different routes.

mutation {
updateDispatchRouteStop(
organizationId: 1
dispatchRouteId: 200
dispatchRouteStopId: 301
values: {
actualArrivalTime: "2026-08-03T17:30:00Z"
actualCompletionTime: null
}
) {
dispatchRouteId
stops {
dispatchRouteStopId
actualArrivalTime
actualCompletionTime
}
}
}

Orders expose route links through relatedDispatchRoutes. Draft orders return an empty list.

query {
orders(organizationId: 1, filter: "orderId:9001") {
items {
orderId
orderNumber
relatedDispatchRoutes(orderBy: "routeDate") {
dispatchRouteId
name
routeDate
trackingEvents {
eventDate
eventDefinition { name }
}
stops {
dispatchRouteStopId
orderIds
trackingEvents {
eventDate
eventDefinition { name }
}
}
}
}
}
}

Orders also expose the raw stop membership links through dispatchRouteStopOrders, which is the path used by order filters such as dispatchRouteStopOrders.dispatchRouteStop.dispatchRouteStopStatus.statusStage:Completed.

query {
orders(
organizationId: 1
filter: "dispatchRouteStopOrders.dispatchRouteStop.dispatchRouteStopStatus.statusStage:Completed"
) {
items {
orderId
orderNumber
dispatchRouteStopOrders {
dispatchRouteStop {
dispatchRouteId
plannedSequence
trackingEvents { eventDate eventDefinition { name } }
}
}
}
}
}

Commodities expose route links through getRelatedDispatchRoutes(filter, orderBy). The resolver starts at the selected commodity, walks down its child commodity tree, finds all non-draft orders attached to that commodity or any descendant, and returns dispatch routes attached to those orders.

query {
commodities(organizationId: 1, filter: "commodityId:5001") {
items {
commodityId
description
getRelatedDispatchRoutes(orderBy: "routeDate") {
dispatchRouteId
name
routeDate
stops {
dispatchRouteStopId
orderIds
}
}
}
}
}

Daily Generation

mutation {
generateDispatchRoutes(input: {
organizationId: 1
values: {
routeDate: "2026-06-16"
dispatchRouteStatusId: 10
dispatchRouteTemplateId: 5
}
}) {
generateDispatchRoutesResult {
createdCount
skippedCount
createdRouteIds
}
}
}

Generation is idempotent per template and route date. Omit dispatchRouteTemplateId to generate from all enabled templates matching the date's day of week.