unassigned[] diagnosis — see that
page.
The request schema rejects unknown fields. A field this page marks
Phase 1 (400) is accepted by the schema but rejected at request time with
an error naming the exact field — never a silently ignored option. A field
this page doesn’t mention at all is an unknown-field
422.Overview
Capacity
Every vehicle declares a multi-dimensionalcapacity; every job/shipment
declares a demand. Load never exceeds capacity on any named dimension, at
every point along the route.
400 — you never
get a silently-infeasible plan.
The response reports load_after (per stop) and load_peak (per route) as
the same named map ({ "weight": 30, "volume": 2 }).
Time windows
A job or shipment leg carries one or moretime_windows:
number
Grades which of a task’s own alternative windows is preferred — every
window stays hard on both sides. Needs at least two windows on the task,
and cannot be combined with
objective.costs.per_late_hour > 0 anywhere
in the request (400) — the two disagree about which window was paid for.number
Fleet-wide: makes lateness legal-but-priced on every window of every
task at once. An explicit
0.0 is rejected as ambiguous — omit the field
for hard windows.object
A per-task soft point deadline, independent of the two mechanisms above:
{ "at": "2026-04-01T10:00:00Z", "per_late_hour": 60.0 }. Arriving after
at is priced, never infeasible; arriving early never forces a wait. Jobs
only — 400 if set on a shipments[] entry.earliness_cost_per_hour / lateness_cost_per_hour pair on
time_windows[] — the mechanism above (a fleet-wide rate plus per-window
cost and the per-task target_arrival) is what actually ships today.
Shift hours and overtime
A vehicle works only within its shift’s[from, to]; the whole route —
including the return leg — must finish by to unless max_overtime_s
grants a costed extension.
objective.costs.per_overtime_hour (fleet-wide) —
components.overtime appears in the response only when that rate is set.
Multiple shifts[] on one vehicle model multi-day availability.
Skills
skills list is an ALL-subset test: the assigned vehicle must
provide every named skill. { "name": ... } is the only field on a skill
requirement — there is no soft-skill violation_cost, so every skill
requirement is hard.
Tags, serves_tags, and preferred_tags
Tags are a separate, ANY-overlap mechanism from skills — for zones and
territories rather than capabilities:
shift.serves_tags is hard: when set (non-empty), that shift serves only
tasks carrying at least one of the listed tags; untagged tasks remain
serveable everywhere. vehicle.preferred_tags is soft: serving a task
lacking a preferred tag costs that entry’s violation_cost; entries apply
independently, so lacking several preferred tags charges each.
Vehicle eligibility
locked_vehicle— hard-pins the task to one vehicle id; survives re-optimisation. Rejected with400if the id matches no vehicle.eligible_vehicles.{allowed,excluded}— hard whitelist/blacklist, mutually exclusive.preferences— soft. Each{ vehicle, violation_cost }entry is priced independently: a task listing several preferred vehicles pays every entry whose vehicle didn’t serve it, even if one of the others did.
Route limits
limits.max_distance_m and limits.max_route_duration_s are hard,
per-vehicle. There is no separate pure-drive-time cap — max_route_duration_s
caps the whole-route span: travel, service, and wait all count. Stop-count
is a separate cap, on the shift: shifts[].max_tasks.
Relations
relations[] expresses inter-task ordering, grouping, and synchronisation.
All four variants are hard — there is no violation_cost on a relation.
ordered— members appear in this order on one route (gaps allowed). Select viajob_ids, or a cross-groupgroupslist of tag labels wheregroups[0]precedesgroups[1], and so on (a tag naming a shipment there is400).same_resource— members served by the same vehicle across shifts/days.same_day— members land on the same calendar day.synchronized— listedtasksstart withinmax_wait_sof each other, across vehicles.
same_resource/same_day select members via job_ids or a single group
tag (mutually exclusive). The consecutive and same_route relation types
were considered and removed from the schema entirely — an unknown relation
type is an unknown-field rejection, not a 400.
Shipments
shipments[] entry’s delivery leg is only ever inserted after its pickup
leg, on the same route — same-vehicle and ordering are implicit, never a
separate relations[] entry. mandatory/drop_fee/eligible_vehicles
apply to the pair as a whole. target_arrival is 400 on shipments today.
Driver breaks
Break is a tagged union: floating (bounded by exactly one windows
entry or a drive/duty trigger — EU 561/2006’s 4h30 drive rule is
{ "after": "drive", "threshold_s": 16200 }) and fixed (a mandatory
off-duty interval at a fixed from/to). Breaks are injected into the
route timeline and appear as break stops in the response.
Phase 1 (400): multiple windows entries on one break, a location on
a triggered or fixed break (only windowed breaks may pin one),
windows+trigger together, neither on a floating break, and
trigger.resets_accumulator: false.
Multi-trip reloads
reloads[] depot mid-shift to reset its load and
start a fresh trip. max_trips caps trips (reloads_used + 1) across all
reload depots in that shift; a single reload depot can be revisited at most
8 times regardless of max_trips. All reloads[] entries in one shift must
currently share the same service_duration_s and cost_per_visit — a
per-depot difference is 400. initial_load declares stock already on the
vehicle at shift start (occupies capacity on the first trip only, flushed at
the first reload).
Reachability
There is no request field for this one: when the fetched distance matrix reports a pair as unreachable (no road connection), the solver activates a constraint that forbids any route from using that leg. A task only reachable through such a leg comes back unassigned withUNREACHABLE_LOCATION.
Constraint System
The full constraint model, evaluation order, and how to read
unassigned[].The V3 API Model
How the full request is structured.
Objective Function
How the soft mechanisms above are priced and ranked.
API Reference
The
POST /v3/routing/solve schema.