Skip to content

Time windows

~3 min read · Recipes

Add serviceWindows to a task to control when that stop may be served. The engine will sequence and time the route so each stop is reached inside its window (waiting if it arrives early).

A window is a two-element [start, end] array, and serviceWindows wraps it in a list, so a stop's window looks like [[start, end]]. Each stop takes exactly one window; multiple windows per stop aren't supported yet.

{
  "id": 102,
  "deliveries": [{
    "id": 1002,
    "location": [49.24660, -123.06340],
    "duration": 300,
    "serviceWindows": [
      ["2026-07-31T09:00:00-07:00", "2026-07-31T11:00:00-07:00"]
    ]
  }]
}

Every task needs a window

serviceWindows is effectively mandatory. A task without one is rejected with 400 Cannot read property 'timeRange' of undefined. When a stop can genuinely be served any time, give it the vehicle's whole shift window rather than leaving it out.

A window that has already closed is rejected

Submitting a pickup whose window ended before the current time returns error 10405, "This trip's pickup window has already passed". This bites hardest when you build a problem for today from a full day of historical stops: everything earlier than the moment you press send is discarded. Date the problem for tomorrow.

  • Give each stop exactly one window. A stop with two or more windows makes the whole request fail with 400 Task … has multiple serviceWindows, this is not yet supported.
  • If a stop is reached before its window opens, the stop's waitTime (in the solution) shows the idle seconds.
  • If no vehicle can reach a stop within its window, it is placed in unassigned with the reason TIME_WINDOW.

Windows must be reachable

Very tight windows across distant stops are the most common cause of unassigned jobs. Widen the window, add a vehicle, or check the depot/shift times.

Related: Skills and matching · The Problem object · Enums, limits and rules