What makes this vertical distinctive
- Skill preference — a senior technician is preferred on demanding jobs, without excluding a generalist when the senior isn’t available.
- Opportunistic scheduling — lower-priority jobs stay optional and only get planned when the route has capacity left.
- Travel-distance cap between jobs — a technician’s hops from one job to the next stay under a set distance.
- Home start/end — every route starts and ends at the technician’s own home, not a shared depot.
Combined example
Skill preference
technician-senior.preferredStopTags: ["tag:senior-preferred"] is matched against the same tag on stop-demanding-client. See Driver skills and qualifications — the exact worked example this pattern follows.
Opportunistic scheduling
order-routine-job sets optional: true with a positive priority (lower numbers matter more, so 5 ranks it below the default 0), so the engine only plans it once every mandatory and preferred stop is already placed, via the maximizeOptionalStops objective. A higher priority number pushes a job further down the queue relative to other optional orders. See Soft constraints.
Travel-distance cap between jobs
technician-senior.maxInterStopDistanceInKm bounds each leg of the tour independently: firstTravel/lastTravel (home to first job, last job to home) get a looser cap than interStop (job to job), keeping consecutive appointments close together without also restricting how far the day’s first and last jobs can be from home.
Home start/end
Each technician’sdeparture/arrival points to its own position rather than a shared depot — technician-senior and technician-junior don’t share coordinates. See Depot vs. position for how a “depot” is just a resource’s departure/arrival, not a first-class object.
Full payload
Full payload — ready to submit as POST /plans
Full payload — ready to submit as POST /plans
The preceding example isolates the four mechanisms this vertical needs; this expands it to the scale of a real working day — a full fleet schedule (
workingTimeWindow, departure, arrival), the complete objectives list, and enough jobs to look like an actual route rather than a minimal illustration. Submit it as-is via POST /plans — the service assigns the plan’s id, so don’t include one of your own.See also
- Modeling advanced constraints —
preferredStopTagsandrequiredSkills, hard vs. soft. - Data model — how per-resource
departure/arrivalrepresents a home or depot. ordersin the API reference —optional,priority, and the rest of the order/stop shape.

