Core Concepts
Request model
Section titled “Request model”Every request has two required arrays:
vehicles— the fleet. Each vehicle represents one route. Vehicles have astartlocation (the depot), optionalendlocation (defaults tostart), optionalcapacity, and optional constraints (time windows, skills, max distance).jobs— the stops to visit. Each job has alocationand optionaldemand,service_duration,time_windows, andskills.
The depot is not a special entity — it’s simply the vehicle’s start (and end) coordinate. There’s no depot_id or shared depot field.
Coordinates
Section titled “Coordinates”All coordinates are [longitude, latitude] arrays following the GeoJSON convention. Longitude comes first.
{ "start": [-0.1278, 51.5074] }Capacity
Section titled “Capacity”Capacity is multi-dimensional. A vehicle with capacity: [100, 50] has two bins; jobs must fit within both. For standard single-dimension routing, use a single-element array: capacity: [100], demand: [10].
Problem types
Section titled “Problem types”CVRP — Capacitated VRP
Section titled “CVRP — Capacitated VRP”Set capacity on vehicles and demand on jobs. The solver finds routes that serve all jobs without exceeding any vehicle’s capacity.
VRPTW — VRP with Time Windows
Section titled “VRPTW — VRP with Time Windows”Set time_windows on vehicles (working hours) and/or jobs (service windows). All times use ISO 8601 with timezone:
{ "time_windows": [{ "start": "2024-01-15T09:00:00Z", "end": "2024-01-15T11:00:00Z" }]}service_duration (seconds) is the time spent at a job stop.
When time windows are active, the response includes arrival and departure ISO 8601 timestamps on each stop.
TSP — Travelling Salesman
Section titled “TSP — Travelling Salesman”One vehicle, no capacity constraint. The solver finds the shortest tour through all jobs.
Skills
Section titled “Skills”Vehicles and jobs can both carry skills (string labels). A job with skills: ["refrigerated"] can only be served by a vehicle that also has "refrigerated" in its skills list. Unmatched jobs appear in unassigned with reason: "SKILLS_MISMATCH".
Distance matrix
Section titled “Distance matrix”The solver needs pairwise distances and travel times between all locations. Two options:
- OSRM (default): omit
options.matrix. The solver calls a routing engine automatically using the coordinates in your request. - Custom matrix: supply
options.matrix.distances(metres) andoptions.matrix.durations(seconds) as n×n arrays, where n = the number of unique locations (vehicle starts/ends + job locations, deduplicated by coordinate).
The response
Section titled “The response”{ "summary": { ... }, "routes": [ ... ], "unassigned": [ ... ]}summary
Section titled “summary”Fleet-wide totals and solver stats:
| Field | Description |
|---|---|
status | Always "completed" for a successful run |
total_distance | Sum of all route distances (metres) |
total_duration | Sum of all route travel times (seconds) |
total_cost | Sum of all vehicle costs |
vehicles_used | Number of vehicles with at least one stop |
jobs_assigned | Jobs successfully routed |
jobs_unassigned | Jobs that couldn’t be placed |
elapsed_ms | Actual solver wall-clock time |
iterations | ALNS iterations completed |
routes
Section titled “routes”One entry per vehicle used. Each route has:
stops— ordered stops (depot is implicit, not listed). Each stop hasjob_id,location,load_after, and optionallyarrival/departure(ISO 8601) when time windows are active.distance— route distance in metresduration— route travel time in secondscost— vehicle’s fixed cost + distance × per_km rate
unassigned
Section titled “unassigned”Each unassigned job has a reason code:
| Reason | Meaning |
|---|---|
CAPACITY_EXCEEDED | Job demand exceeds every vehicle’s remaining capacity |
TIME_WINDOW_VIOLATED | No vehicle can reach the job within its time window |
SKILLS_MISMATCH | No vehicle has all required skills |
VEHICLE_RANGE_EXCEEDED | Adding job would exceed vehicle’s max distance |
VEHICLE_LIMIT_EXHAUSTED | All vehicle capacity is used; one more vehicle would help |
ALL_ROUTES_BLOCKED | Every route has a mix of capacity and/or TW conflicts |
The objective
Section titled “The objective”The solver minimises a lexicographic objective:
- Unassigned jobs — always minimised first (hard constraint)
- Vehicles used × 1,000,000 (default weight)
- Total route distance × 1 (default weight)
Override the weights via options.objectives.vehicle_cost and options.objectives.distance_cost.
Solver options
Section titled “Solver options”| Option | Default | Description |
|---|---|---|
time_limit | 10 | Solver budget in seconds |
seed | 42 | RNG seed for reproducible results |
matrix | — | Custom distance/duration matrix |
objectives | — | Override objective weights |