Jobs
A job is something that needs to happen at one location. For a simple visit (delivery, service call, inspection) place its visit fields directly on the job object. Pickup-then-delivery work uses a distinctshipments[] entry type instead — see Shipments.
- location — a
Place:{ "coordinate": [lon, lat] }(GeoJSON order), inline only — there is no reference into a separate locations/depot list. Omit it entirely for a virtual (location-less) job. - service_duration_s — nominal seconds spent at the location, excluding travel; scaled by the serving vehicle’s
service_factor. - time_windows — when the job can be served (ISO 8601
from/topairs). Hard by default. Lateness is softened fleet-wide viaobjective.costs.per_late_hour, per-task viatarget_arrival, or graded between a task’s own alternative windows viatime_windows[].cost— see Constraints for how the three compose. - demand — named capacity consumed, e.g.
{ "weight": 10 }. Matched againstvehicle.capacityby name. - skills — capability requirements, e.g.
[{ "name": "refrigerated" }]. A job can only be served by a vehicle that has all required skills; there is no soft-skill form. - mandatory — omit or set
trueto require the job be served (infeasible if it cannot be).falsemakes it droppable, and only means something together withdrop_fee(below) — a droppable task with no price is rejected. - drop_fee — what leaving the job unserved costs, in the objective’s currency. Replaces the removed
unassigned_costfield.
Shipments
A shipment is a bound pickup→delivery pair, expressed as its ownshipments[] entry (not a flag on a job):
relations[] entry. demand counts against capacity only between the two legs. mandatory/drop_fee/skills/eligible_vehicles apply to the pair as a whole (one decision, one fee).
Vehicles
A vehicle represents a driver or asset with capacity, skills, a cost model, and one or more working shifts. There is no vehicle-levelcount — fleet size is one entry per physical vehicle.
- capacity — named dimension limits matched against job/shipment
demandby name.{ "weight": 1000, "volume": 50 }is two independent caps. - skills — capability tags the vehicle provides. A vehicle can serve a job only when its skills are a superset of the job’s required skills.
- limits — optional hard route caps:
max_distance_mandmax_route_duration_s. The latter caps the whole-route span from shift departure to final arrival — travel, service, and wait all count, not pure driving time; there is no separate pure-drive-time cap. - shifts — working time windows (ISO 8601
from/to). At least one shift is required.startandendare the depotPlacefor this shift — set insideshifts, not at vehicle top-level; absent means an open start/end on that side.shifts[].max_taskscaps the number of stops in that shift;shifts[].breaks/shifts[].reloadsadd driver breaks and multi-trip depot reloads (see Constraints).
Distance matrices
V3 always fetches road-network distance and duration matrices from Solvice Maps — traffic-aware by default (historical-typical traffic for the shift’s departure time;options.runtime.traffic.departure_time overrides the lookup instant). There is no request field to supply a custom matrix; the API always routes through Solvice Maps. Road-network matrices are typically asymmetric (A→B time or distance ≠ B→A).
Constraints
The solver enforces a fixed, closed set of constraint types — each one hard (infeasible if violated) unless noted otherwise:
See the full Constraints guide for field-level detail on every one of these, including which are soft and how each soft mechanism is priced.
Objective
The solver ranks feasible solutions in two lexicographic tiers, not a Hard/Medium/Soft point score:- Drop penalty (tier 1) — the summed penalty of unassigned tasks. A must-serve task (the default) carries a large uniform internal penalty, so on a request with no
drop_feeset this tier is exactly “number of unassigned tasks” and always outranks cost. - Cost (tier 2) — the weighted currency sum of travel, waiting, overtime, soft lateness, preference violations, and the
drop_feeof every priced task the plan chose not to serve.
objective.minimize_vehicles (a bool, default true) is the one real degree of freedom on top of that: whether using fewer vehicles outranks minimising cost. It replaced an objective.priorities token list that could never actually be reordered. Omit the objective block entirely for “minimise travel cost, serve everything, use as few vehicles as it takes” — V3 seeds a realistic default travel baseline (€0.20/km, €35/travel-hour) in that case.
estimated_cost breakdown — travel and waiting are always reported; drop_fees/overtime appear only when priced — so you never need to recompute the objective yourself. See Objective Function for the full ranking and defaulting behaviour.
Relations
Relations express ordering, grouping, and synchronisation between jobs using a singlerelations array. Each relation is a tagged object with a type, and every relation is hard — there is no per-relation violation_cost.
See the full Constraints guide and The V3 API Model for field-level detail.