{
  "resources": [
    {
      "name": "courier-1",
      "shifts": [
        {
          "from": "2024-03-15T08:00:00Z",
          "to": "2024-03-15T18:00:00Z",
          "start": {
            "name": "Depot",
            "latitude": 52.5200,
            "longitude": 13.4050
          },
          "end": {
            "name": "Depot",
            "latitude": 52.5200,
            "longitude": 13.4050
          }
        }
      ],
      "capacity": [50]
    }
  ],
  "jobs": [
    {
      "name": "delivery-1",
      "location": {
        "name": "Customer A - Alexanderplatz",
        "latitude": 52.5219,
        "longitude": 13.4132
      },
      "duration": 300,
      "load": [5]
    },
    {
      "name": "delivery-2",
      "location": {
        "name": "Customer B - Potsdamer Platz",
        "latitude": 52.5096,
        "longitude": 13.3761
      },
      "duration": 300,
      "load": [8]
    },
    {
      "name": "delivery-3",
      "location": {
        "name": "Customer C - Brandenburger Tor",
        "latitude": 52.5163,
        "longitude": 13.3777
      },
      "duration": 300,
      "load": [6]
    },
    {
      "name": "delivery-4",
      "location": {
        "name": "Customer D - Checkpoint Charlie",
        "latitude": 52.5075,
        "longitude": 13.3903
      },
      "duration": 300,
      "load": [4]
    },
    {
      "name": "delivery-5",
      "location": {
        "name": "Customer E - Berlin Cathedral",
        "latitude": 52.5191,
        "longitude": 13.4011
      },
      "duration": 300,
      "load": [7]
    }
  ],
  "options": {
    "routingEngine": "OSM",
    "euclidian": false,
    "traffic": 1.0
  }
}
{
  "id": "vrp_job_123456",
  "status": "SOLVED",
  "solution": {
    "routes": [
      {
        "resource": "courier-1",
        "jobs": [
          {
            "job": "delivery-5",
            "arrival": "2024-03-15T08:12:00Z",
            "departure": "2024-03-15T08:17:00Z",
            "travelTime": 720,
            "distance": 2847
          },
          {
            "job": "delivery-1",
            "arrival": "2024-03-15T08:21:00Z",
            "departure": "2024-03-15T08:26:00Z",
            "travelTime": 240,
            "distance": 1123
          },
          {
            "job": "delivery-4",
            "arrival": "2024-03-15T08:34:00Z",
            "departure": "2024-03-15T08:39:00Z",
            "travelTime": 480,
            "distance": 2256
          },
          {
            "job": "delivery-2",
            "arrival": "2024-03-15T08:47:00Z",
            "departure": "2024-03-15T08:52:00Z",
            "travelTime": 480,
            "distance": 2103
          },
          {
            "job": "delivery-3",
            "arrival": "2024-03-15T08:54:00Z",
            "departure": "2024-03-15T08:59:00Z",
            "travelTime": 120,
            "distance": 534
          }
        ],
        "summary": {
          "totalTravelTime": 3240,
          "totalDistance": 12684,
          "totalDuration": 5340,
          "totalJobs": 5,
          "departureTime": "2024-03-15T08:00:00Z",
          "arrivalTime": "2024-03-15T09:18:00Z"
        }
      }
    ],
    "unassigned": [],
    "metrics": {
      "totalTravelTime": 3240,
      "totalDistance": 12684,
      "totalJobs": 5,
      "assignedJobs": 5,
      "unassignedJobs": 0
    }
  }
}

Basic Routing

This example demonstrates how to solve a simple vehicle routing problem with real road distances using OpenStreetMap (OSM) data. We’ll route a single vehicle to visit 5 delivery locations in Berlin, Germany.

Business Scenario

A local courier company needs to deliver packages to 5 customers in Berlin. They want to:
  • Find the most efficient route visiting all customers
  • Use actual road distances, not straight-line distances
  • Start and end at their depot
  • Complete all deliveries in one trip

Complete Request

{
  "resources": [
    {
      "name": "courier-1",
      "shifts": [
        {
          "from": "2024-03-15T08:00:00Z",
          "to": "2024-03-15T18:00:00Z",
          "start": {
            "name": "Depot",
            "latitude": 52.5200,
            "longitude": 13.4050
          },
          "end": {
            "name": "Depot",
            "latitude": 52.5200,
            "longitude": 13.4050
          }
        }
      ],
      "capacity": [50]
    }
  ],
  "jobs": [
    {
      "name": "delivery-1",
      "location": {
        "name": "Customer A - Alexanderplatz",
        "latitude": 52.5219,
        "longitude": 13.4132
      },
      "duration": 300,
      "load": [5]
    },
    {
      "name": "delivery-2",
      "location": {
        "name": "Customer B - Potsdamer Platz",
        "latitude": 52.5096,
        "longitude": 13.3761
      },
      "duration": 300,
      "load": [8]
    },
    {
      "name": "delivery-3",
      "location": {
        "name": "Customer C - Brandenburger Tor",
        "latitude": 52.5163,
        "longitude": 13.3777
      },
      "duration": 300,
      "load": [6]
    },
    {
      "name": "delivery-4",
      "location": {
        "name": "Customer D - Checkpoint Charlie",
        "latitude": 52.5075,
        "longitude": 13.3903
      },
      "duration": 300,
      "load": [4]
    },
    {
      "name": "delivery-5",
      "location": {
        "name": "Customer E - Berlin Cathedral",
        "latitude": 52.5191,
        "longitude": 13.4011
      },
      "duration": 300,
      "load": [7]
    }
  ],
  "options": {
    "routingEngine": "OSM",
    "euclidian": false,
    "traffic": 1.0
  }
}

Key Configuration Choices

Routing Engine

"options": {
  "routingEngine": "OSM",
  "euclidian": false
}
Distance Calculation Methods:
  • "routingEngine": "OSM" - Uses OpenStreetMap for real road distances
  • "euclidian": true - Would use straight-line distances (faster but less accurate)
  • Other engines: "TOMTOM", "GOOGLE", "ANYMAP"

Location Details

Each location includes:
  • Name: Human-readable identifier for clarity
  • Coordinates: Latitude/longitude for geocoding
  • Duration: Service time at each stop (5 minutes)
  • Load: Package size/weight

Vehicle Configuration

  • Shift: 10-hour working day (8 AM - 6 PM)
  • Start/End: Same depot location (round trip)
  • Capacity: 50 units (sum of all loads = 30 units)

Expected Response

{
  "id": "vrp_job_123456",
  "status": "SOLVED",
  "solution": {
    "routes": [
      {
        "resource": "courier-1",
        "jobs": [
          {
            "job": "delivery-5",
            "arrival": "2024-03-15T08:12:00Z",
            "departure": "2024-03-15T08:17:00Z",
            "travelTime": 720,
            "distance": 2847
          },
          {
            "job": "delivery-1",
            "arrival": "2024-03-15T08:21:00Z",
            "departure": "2024-03-15T08:26:00Z",
            "travelTime": 240,
            "distance": 1123
          },
          {
            "job": "delivery-4",
            "arrival": "2024-03-15T08:34:00Z",
            "departure": "2024-03-15T08:39:00Z",
            "travelTime": 480,
            "distance": 2256
          },
          {
            "job": "delivery-2",
            "arrival": "2024-03-15T08:47:00Z",
            "departure": "2024-03-15T08:52:00Z",
            "travelTime": 480,
            "distance": 2103
          },
          {
            "job": "delivery-3",
            "arrival": "2024-03-15T08:54:00Z",
            "departure": "2024-03-15T08:59:00Z",
            "travelTime": 120,
            "distance": 534
          }
        ],
        "summary": {
          "totalTravelTime": 3240,
          "totalDistance": 12684,
          "totalDuration": 5340,
          "totalJobs": 5,
          "departureTime": "2024-03-15T08:00:00Z",
          "arrivalTime": "2024-03-15T09:18:00Z"
        }
      }
    ],
    "unassigned": [],
    "metrics": {
      "totalTravelTime": 3240,
      "totalDistance": 12684,
      "totalJobs": 5,
      "assignedJobs": 5,
      "unassignedJobs": 0
    }
  }
}

Understanding the Results

Route Sequence

The optimized route visits customers in this order:
  1. DepotCustomer E (Berlin Cathedral)
  2. Customer A (Alexanderplatz)
  3. Customer D (Checkpoint Charlie)
  4. Customer B (Potsdamer Platz)
  5. Customer C (Brandenburger Tor)
  6. Depot

Distance Comparison

To see the difference real distances make, compare with Euclidean distances:
{
  "options": {
    "routingEngine": "OSM",
    "euclidian": false
  }
}
// Total distance: ~12.7 km
// Accounts for: one-way streets, roads, traffic rules
Real road distances are typically 20-50% longer than straight-line distances in urban areas due to the road network structure.

Try It Yourself

1

Get API Access

Obtain your API key from the Solvice Dashboard
2

Send Request

curl -X POST 'https://api.solvice.io/v2/vrp/solve' \
  -H 'Authorization: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "resources": [{
      "name": "courier-1",
      "shifts": [{
        "from": "2024-03-15T08:00:00Z",
        "to": "2024-03-15T18:00:00Z",
        "start": {"latitude": 52.5200, "longitude": 13.4050},
        "end": {"latitude": 52.5200, "longitude": 13.4050}
      }],
      "capacity": [50]
    }],
    "jobs": [
      {"name": "delivery-1", "location": {"latitude": 52.5219, "longitude": 13.4132}, "duration": 300, "load": [5]},
      {"name": "delivery-2", "location": {"latitude": 52.5096, "longitude": 13.3761}, "duration": 300, "load": [8]},
      {"name": "delivery-3", "location": {"latitude": 52.5163, "longitude": 13.3777}, "duration": 300, "load": [6]},
      {"name": "delivery-4", "location": {"latitude": 52.5075, "longitude": 13.3903}, "duration": 300, "load": [4]},
      {"name": "delivery-5", "location": {"latitude": 52.5191, "longitude": 13.4011}, "duration": 300, "load": [7]}
    ],
    "options": {"routingEngine": "OSM"}
  }'
3

Check Status

curl -X GET 'https://api.solvice.io/v2/vrp/jobs/{job_id}/status' \
  -H 'Authorization: YOUR_API_KEY'
4

Get Solution

curl -X GET 'https://api.solvice.io/v2/vrp/jobs/{job_id}/solution' \
  -H 'Authorization: YOUR_API_KEY'

Next Steps

Now that you understand basic routing with real distances: