Skip to main content

Overview

The V3 Routing API is a ground-up rewrite with a new, faster solver engine replacing Timefold. The V2 endpoint (/v2/vrp/sync/solve) remains available for backwards compatibility — internally it maps to V3 and back.

Endpoint change

Request mapping

Vehicles (Resources → Vehicles)

Key differences:
  • nameid
  • shifts[].start/end move to inside shifts[] as a Place ({ "coordinate": [lon, lat] }) — this is still inside the shift in both V2 and V3, but the coordinate format changes
  • Coordinates: { "latitude", "longitude" } object → { "coordinate": [longitude, latitude] } Place (GeoJSON order, wrapped in object)
  • capacity: array [100] → named map { "weight": 100 } (dimension names must match job demand keys)
  • tagsskills (resource-level tags[] is mapped 1:1 via the V2 compat endpoint; only per-shift shifts[].tags — per-shift capability tags — has no V3 equivalent, since V3 skills are vehicle-level, not shift-level)
  • New: limits.max_distance_m, limits.max_route_duration_s for vehicle range constraints (max_route_duration_s caps the whole route span — travel + service + wait — not pure drive time; V3 has no pure-drive-time cap)

Jobs

Key differences:
  • nameid
  • location: { "latitude", "longitude" } → Place object { "coordinate": [longitude, latitude] }
  • durationservice_duration_s (still in seconds)
  • load array → demand named map (e.g. [10]{ "weight": 10 })
  • windowstime_windows (no hard flag — all time windows are hard in V3 Phase 1)
  • Skills: skills: [{ "name": "refrigerated" }] — supported today; all required skills must be present on the vehicle
  • Committed vehicle: a hard pin uses locked_vehicle (survives re-optimization). eligible_vehicles: { "allowed": [...] } is a different mechanism — an eligibility whitelist among several allowed vehicles, not a single-vehicle pin

Relations

V3 uses a tagged-union format with job_ids (not jobs). V2 relation types map as follows:
V2 has no dedicated “pin job first” relation type. To pin a job to the first position in a route, submit a SEQUENCE relation with a single job id in jobs — the V2 solver derives first-job placement from that single-entry sequence internally. The V3 equivalent is the same pattern: an ordered relation with a single entry in job_ids.
Note: V2’s resource field (pin relation to a specific vehicle) maps to locked_vehicle applied to every job in the relation — supported today, not a workaround.

Options

Key differences:
  • V2’s ?millis= query parameter (already in milliseconds) → options.runtime.time_limit_ms request body field (also milliseconds)
  • New: options.runtime.seed for reproducible results
  • New: options.runtime.matrix — supply custom distance/duration matrices (bypasses Solvice Maps)
  • Objective tuning (minimize time vs. distance) is configured via the objective field — Coming soon

Response mapping

Key differences:
  • tripsroutes; resourcevehicle (a plain vehicle-id string, e.g. "truck-1")
  • visitsstops (typed: start, job, end, etc.)
  • V3 stops carry type, id, arrival, departure, wait_s, service_s, travel_time_s, load_after (named map)
  • V3 routes use distance_m / duration_s (not bare distance / duration)
  • unserved (string list) → unassigned (objects with job_id and reasons[])
  • New summary block with jobs_assigned/jobs_unassigned, total_distance_m, total_duration_s, estimated_cost, elapsed_ms, iterations
  • Coordinates in response are bare [longitude, latitude] arrays

V2 features not mapped via compat endpoint

When using the V2 endpoint (/v2/vrp/sync/solve), the following V2 fields are silently dropped during conversion:
  • shifts[].tags (per-shift capability tags) — V3 skills are vehicle-level; split the resource into one V3 vehicle per differing shift to approximate this. (Resource-level resources[].tags itself is forwarded, via skills.)
  • windows[].hard: false + its per-window weight — V3 can price lateness fleet-wide via objective.costs.per_late_hour, but the per-window weight is lost; there is no per-window soft-cost equivalent
  • Per-visit serviceTime, travelTime, distance — not populated in the V2 response

Feature parity

Most of V2’s features already ship in V3 today, often via a different mechanism (currency-priced rather than ranked, or a coarser-grained workaround field). A handful remain genuine gaps.
V3 is under active development. The V2 endpoint (/v2/vrp/sync/solve) remains available and internally maps to the V3 solver — you get V3’s performance with the V2 API contract.