Validate
Pre-matrix check of request shape, referential integrity and unsupported features — no matrix fetch, no solve
curl --request POST \
--url https://api.solvice.io/v3/routing/validate \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"jobs": [
{
"demand": {
"weight": 20
},
"id": "job-1",
"location": {
"coordinate": [
3.725,
51.05
]
},
"service_duration_s": 300,
"skills": [
{
"name": "fridge"
}
],
"time_windows": [
{
"from": "2026-07-01T09:00:00+02:00",
"to": "2026-07-01T12:00:00+02:00"
}
]
},
{
"demand": {
"weight": 35
},
"id": "job-2",
"location": {
"coordinate": [
3.71,
51.06
]
},
"service_duration_s": 600
}
],
"objective": {
"costs": {
"currency": "EUR",
"per_travel_hour": 3600
},
"minimize_vehicles": true
},
"options": {
"runtime": {
"seed": 42,
"time_limit_s": 5
}
},
"vehicles": [
{
"capacity": {
"weight": 500
},
"id": "v1",
"profile": "car",
"shifts": [
{
"end": {
"coordinate": [
3.7174,
51.0543
]
},
"from": "2026-07-01T08:00:00+02:00",
"start": {
"coordinate": [
3.7174,
51.0543
]
},
"to": "2026-07-01T17:00:00+02:00"
}
],
"skills": [
"fridge"
]
}
]
}
'import requests
url = "https://api.solvice.io/v3/routing/validate"
payload = {
"jobs": [
{
"demand": { "weight": 20 },
"id": "job-1",
"location": { "coordinate": [3.725, 51.05] },
"service_duration_s": 300,
"skills": [{ "name": "fridge" }],
"time_windows": [
{
"from": "2026-07-01T09:00:00+02:00",
"to": "2026-07-01T12:00:00+02:00"
}
]
},
{
"demand": { "weight": 35 },
"id": "job-2",
"location": { "coordinate": [3.71, 51.06] },
"service_duration_s": 600
}
],
"objective": {
"costs": {
"currency": "EUR",
"per_travel_hour": 3600
},
"minimize_vehicles": True
},
"options": { "runtime": {
"seed": 42,
"time_limit_s": 5
} },
"vehicles": [
{
"capacity": { "weight": 500 },
"id": "v1",
"profile": "car",
"shifts": [
{
"end": { "coordinate": [3.7174, 51.0543] },
"from": "2026-07-01T08:00:00+02:00",
"start": { "coordinate": [3.7174, 51.0543] },
"to": "2026-07-01T17:00:00+02:00"
}
],
"skills": ["fridge"]
}
]
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
jobs: [
{
demand: {weight: 20},
id: 'job-1',
location: {coordinate: [3.725, 51.05]},
service_duration_s: 300,
skills: [{name: 'fridge'}],
time_windows: [{from: '2026-07-01T09:00:00+02:00', to: '2026-07-01T12:00:00+02:00'}]
},
{
demand: {weight: 35},
id: 'job-2',
location: {coordinate: [3.71, 51.06]},
service_duration_s: 600
}
],
objective: {costs: {currency: 'EUR', per_travel_hour: 3600}, minimize_vehicles: true},
options: {runtime: {seed: 42, time_limit_s: 5}},
vehicles: [
{
capacity: {weight: 500},
id: 'v1',
profile: 'car',
shifts: [
{
end: {coordinate: [3.7174, 51.0543]},
from: '2026-07-01T08:00:00+02:00',
start: {coordinate: [3.7174, 51.0543]},
to: '2026-07-01T17:00:00+02:00'
}
],
skills: ['fridge']
}
]
})
};
fetch('https://api.solvice.io/v3/routing/validate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.solvice.io/v3/routing/validate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'jobs' => [
[
'demand' => [
'weight' => 20
],
'id' => 'job-1',
'location' => [
'coordinate' => [
3.725,
51.05
]
],
'service_duration_s' => 300,
'skills' => [
[
'name' => 'fridge'
]
],
'time_windows' => [
[
'from' => '2026-07-01T09:00:00+02:00',
'to' => '2026-07-01T12:00:00+02:00'
]
]
],
[
'demand' => [
'weight' => 35
],
'id' => 'job-2',
'location' => [
'coordinate' => [
3.71,
51.06
]
],
'service_duration_s' => 600
]
],
'objective' => [
'costs' => [
'currency' => 'EUR',
'per_travel_hour' => 3600
],
'minimize_vehicles' => true
],
'options' => [
'runtime' => [
'seed' => 42,
'time_limit_s' => 5
]
],
'vehicles' => [
[
'capacity' => [
'weight' => 500
],
'id' => 'v1',
'profile' => 'car',
'shifts' => [
[
'end' => [
'coordinate' => [
3.7174,
51.0543
]
],
'from' => '2026-07-01T08:00:00+02:00',
'start' => [
'coordinate' => [
3.7174,
51.0543
]
],
'to' => '2026-07-01T17:00:00+02:00'
]
],
'skills' => [
'fridge'
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.solvice.io/v3/routing/validate"
payload := strings.NewReader("{\n \"jobs\": [\n {\n \"demand\": {\n \"weight\": 20\n },\n \"id\": \"job-1\",\n \"location\": {\n \"coordinate\": [\n 3.725,\n 51.05\n ]\n },\n \"service_duration_s\": 300,\n \"skills\": [\n {\n \"name\": \"fridge\"\n }\n ],\n \"time_windows\": [\n {\n \"from\": \"2026-07-01T09:00:00+02:00\",\n \"to\": \"2026-07-01T12:00:00+02:00\"\n }\n ]\n },\n {\n \"demand\": {\n \"weight\": 35\n },\n \"id\": \"job-2\",\n \"location\": {\n \"coordinate\": [\n 3.71,\n 51.06\n ]\n },\n \"service_duration_s\": 600\n }\n ],\n \"objective\": {\n \"costs\": {\n \"currency\": \"EUR\",\n \"per_travel_hour\": 3600\n },\n \"minimize_vehicles\": true\n },\n \"options\": {\n \"runtime\": {\n \"seed\": 42,\n \"time_limit_s\": 5\n }\n },\n \"vehicles\": [\n {\n \"capacity\": {\n \"weight\": 500\n },\n \"id\": \"v1\",\n \"profile\": \"car\",\n \"shifts\": [\n {\n \"end\": {\n \"coordinate\": [\n 3.7174,\n 51.0543\n ]\n },\n \"from\": \"2026-07-01T08:00:00+02:00\",\n \"start\": {\n \"coordinate\": [\n 3.7174,\n 51.0543\n ]\n },\n \"to\": \"2026-07-01T17:00:00+02:00\"\n }\n ],\n \"skills\": [\n \"fridge\"\n ]\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.solvice.io/v3/routing/validate")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"jobs\": [\n {\n \"demand\": {\n \"weight\": 20\n },\n \"id\": \"job-1\",\n \"location\": {\n \"coordinate\": [\n 3.725,\n 51.05\n ]\n },\n \"service_duration_s\": 300,\n \"skills\": [\n {\n \"name\": \"fridge\"\n }\n ],\n \"time_windows\": [\n {\n \"from\": \"2026-07-01T09:00:00+02:00\",\n \"to\": \"2026-07-01T12:00:00+02:00\"\n }\n ]\n },\n {\n \"demand\": {\n \"weight\": 35\n },\n \"id\": \"job-2\",\n \"location\": {\n \"coordinate\": [\n 3.71,\n 51.06\n ]\n },\n \"service_duration_s\": 600\n }\n ],\n \"objective\": {\n \"costs\": {\n \"currency\": \"EUR\",\n \"per_travel_hour\": 3600\n },\n \"minimize_vehicles\": true\n },\n \"options\": {\n \"runtime\": {\n \"seed\": 42,\n \"time_limit_s\": 5\n }\n },\n \"vehicles\": [\n {\n \"capacity\": {\n \"weight\": 500\n },\n \"id\": \"v1\",\n \"profile\": \"car\",\n \"shifts\": [\n {\n \"end\": {\n \"coordinate\": [\n 3.7174,\n 51.0543\n ]\n },\n \"from\": \"2026-07-01T08:00:00+02:00\",\n \"start\": {\n \"coordinate\": [\n 3.7174,\n 51.0543\n ]\n },\n \"to\": \"2026-07-01T17:00:00+02:00\"\n }\n ],\n \"skills\": [\n \"fridge\"\n ]\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.solvice.io/v3/routing/validate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"jobs\": [\n {\n \"demand\": {\n \"weight\": 20\n },\n \"id\": \"job-1\",\n \"location\": {\n \"coordinate\": [\n 3.725,\n 51.05\n ]\n },\n \"service_duration_s\": 300,\n \"skills\": [\n {\n \"name\": \"fridge\"\n }\n ],\n \"time_windows\": [\n {\n \"from\": \"2026-07-01T09:00:00+02:00\",\n \"to\": \"2026-07-01T12:00:00+02:00\"\n }\n ]\n },\n {\n \"demand\": {\n \"weight\": 35\n },\n \"id\": \"job-2\",\n \"location\": {\n \"coordinate\": [\n 3.71,\n 51.06\n ]\n },\n \"service_duration_s\": 600\n }\n ],\n \"objective\": {\n \"costs\": {\n \"currency\": \"EUR\",\n \"per_travel_hour\": 3600\n },\n \"minimize_vehicles\": true\n },\n \"options\": {\n \"runtime\": {\n \"seed\": 42,\n \"time_limit_s\": 5\n }\n },\n \"vehicles\": [\n {\n \"capacity\": {\n \"weight\": 500\n },\n \"id\": \"v1\",\n \"profile\": \"car\",\n \"shifts\": [\n {\n \"end\": {\n \"coordinate\": [\n 3.7174,\n 51.0543\n ]\n },\n \"from\": \"2026-07-01T08:00:00+02:00\",\n \"start\": {\n \"coordinate\": [\n 3.7174,\n 51.0543\n ]\n },\n \"to\": \"2026-07-01T17:00:00+02:00\"\n }\n ],\n \"skills\": [\n \"fridge\"\n ]\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"code": "VALIDATION_ERROR",
"field": "/vehicles",
"message": "At least one vehicle is required",
"status": "BAD_REQUEST"
}{
"code": "VALIDATION_ERROR",
"field": "/vehicles",
"message": "At least one vehicle is required",
"status": "BAD_REQUEST"
}{
"code": "VALIDATION_ERROR",
"field": "/vehicles",
"message": "At least one vehicle is required",
"status": "BAD_REQUEST"
}Authorizations
Body
Top-level request body for POST /v3/routing/solve (schema v2).
Available vehicles.
Show child attributes
Show child attributes
Warm-start: route assignments the search starts from instead of
constructing from scratch (re-optimization). Unknown vehicle/job ids
are rejected with HTTP 400. See [RouteAssignment::locked_count] for
freezing a dispatched prefix. Accepted for solve-payload compatibility
on /v3/routing/evaluate and /v3/routing/suggest and ignored there
— routes is the input on those endpoints.
Show child attributes
Show child attributes
Single-stop visits to serve.
Show child attributes
Show child attributes
Objective configuration.
Show child attributes
Show child attributes
{
"costs": {
"currency": "EUR",
"per_travel_hour": 3600
},
"minimize_vehicles": true
}
Solver runtime options.
Show child attributes
Show child attributes
{
"runtime": { "seed": 42, "time_limit_s": 5 }
}
Ordering, grouping, and synchronization constraints.
A hard constraint between tasks. Tagged union; each variant carries only its valid fields.
All four variants are wired: ordered (via job_ids or groups),
same_resource, same_day, and synchronized. Member selection is
either explicit job_ids or a group tag (same_resource/
same_day; validated not-both) — ordered uses job_ids or the
cross-group groups list.
(The never-wired consecutive and same_route variants, the per-relation
id and soft violation_cost fields, ordered's group/min_interval_s/
max_interval_s/measure_from, and synchronized.tasks[*].vehicles were
removed: every one was rejected with HTTP 400 on any value. Each can return
as a new field/variant once its core primitive exists — relations are
hard-only until then.)
- Ordered
- Same resource
- Same day
- Synchronized
Show child attributes
Show child attributes
{
"job_ids": ["job-1", "job-2"],
"type": "ordered"
}
Bound pickup→delivery shipments to serve.
Show child attributes
Show child attributes
Response
Request is valid
Was this page helpful?
curl --request POST \
--url https://api.solvice.io/v3/routing/validate \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"jobs": [
{
"demand": {
"weight": 20
},
"id": "job-1",
"location": {
"coordinate": [
3.725,
51.05
]
},
"service_duration_s": 300,
"skills": [
{
"name": "fridge"
}
],
"time_windows": [
{
"from": "2026-07-01T09:00:00+02:00",
"to": "2026-07-01T12:00:00+02:00"
}
]
},
{
"demand": {
"weight": 35
},
"id": "job-2",
"location": {
"coordinate": [
3.71,
51.06
]
},
"service_duration_s": 600
}
],
"objective": {
"costs": {
"currency": "EUR",
"per_travel_hour": 3600
},
"minimize_vehicles": true
},
"options": {
"runtime": {
"seed": 42,
"time_limit_s": 5
}
},
"vehicles": [
{
"capacity": {
"weight": 500
},
"id": "v1",
"profile": "car",
"shifts": [
{
"end": {
"coordinate": [
3.7174,
51.0543
]
},
"from": "2026-07-01T08:00:00+02:00",
"start": {
"coordinate": [
3.7174,
51.0543
]
},
"to": "2026-07-01T17:00:00+02:00"
}
],
"skills": [
"fridge"
]
}
]
}
'import requests
url = "https://api.solvice.io/v3/routing/validate"
payload = {
"jobs": [
{
"demand": { "weight": 20 },
"id": "job-1",
"location": { "coordinate": [3.725, 51.05] },
"service_duration_s": 300,
"skills": [{ "name": "fridge" }],
"time_windows": [
{
"from": "2026-07-01T09:00:00+02:00",
"to": "2026-07-01T12:00:00+02:00"
}
]
},
{
"demand": { "weight": 35 },
"id": "job-2",
"location": { "coordinate": [3.71, 51.06] },
"service_duration_s": 600
}
],
"objective": {
"costs": {
"currency": "EUR",
"per_travel_hour": 3600
},
"minimize_vehicles": True
},
"options": { "runtime": {
"seed": 42,
"time_limit_s": 5
} },
"vehicles": [
{
"capacity": { "weight": 500 },
"id": "v1",
"profile": "car",
"shifts": [
{
"end": { "coordinate": [3.7174, 51.0543] },
"from": "2026-07-01T08:00:00+02:00",
"start": { "coordinate": [3.7174, 51.0543] },
"to": "2026-07-01T17:00:00+02:00"
}
],
"skills": ["fridge"]
}
]
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
jobs: [
{
demand: {weight: 20},
id: 'job-1',
location: {coordinate: [3.725, 51.05]},
service_duration_s: 300,
skills: [{name: 'fridge'}],
time_windows: [{from: '2026-07-01T09:00:00+02:00', to: '2026-07-01T12:00:00+02:00'}]
},
{
demand: {weight: 35},
id: 'job-2',
location: {coordinate: [3.71, 51.06]},
service_duration_s: 600
}
],
objective: {costs: {currency: 'EUR', per_travel_hour: 3600}, minimize_vehicles: true},
options: {runtime: {seed: 42, time_limit_s: 5}},
vehicles: [
{
capacity: {weight: 500},
id: 'v1',
profile: 'car',
shifts: [
{
end: {coordinate: [3.7174, 51.0543]},
from: '2026-07-01T08:00:00+02:00',
start: {coordinate: [3.7174, 51.0543]},
to: '2026-07-01T17:00:00+02:00'
}
],
skills: ['fridge']
}
]
})
};
fetch('https://api.solvice.io/v3/routing/validate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.solvice.io/v3/routing/validate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'jobs' => [
[
'demand' => [
'weight' => 20
],
'id' => 'job-1',
'location' => [
'coordinate' => [
3.725,
51.05
]
],
'service_duration_s' => 300,
'skills' => [
[
'name' => 'fridge'
]
],
'time_windows' => [
[
'from' => '2026-07-01T09:00:00+02:00',
'to' => '2026-07-01T12:00:00+02:00'
]
]
],
[
'demand' => [
'weight' => 35
],
'id' => 'job-2',
'location' => [
'coordinate' => [
3.71,
51.06
]
],
'service_duration_s' => 600
]
],
'objective' => [
'costs' => [
'currency' => 'EUR',
'per_travel_hour' => 3600
],
'minimize_vehicles' => true
],
'options' => [
'runtime' => [
'seed' => 42,
'time_limit_s' => 5
]
],
'vehicles' => [
[
'capacity' => [
'weight' => 500
],
'id' => 'v1',
'profile' => 'car',
'shifts' => [
[
'end' => [
'coordinate' => [
3.7174,
51.0543
]
],
'from' => '2026-07-01T08:00:00+02:00',
'start' => [
'coordinate' => [
3.7174,
51.0543
]
],
'to' => '2026-07-01T17:00:00+02:00'
]
],
'skills' => [
'fridge'
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.solvice.io/v3/routing/validate"
payload := strings.NewReader("{\n \"jobs\": [\n {\n \"demand\": {\n \"weight\": 20\n },\n \"id\": \"job-1\",\n \"location\": {\n \"coordinate\": [\n 3.725,\n 51.05\n ]\n },\n \"service_duration_s\": 300,\n \"skills\": [\n {\n \"name\": \"fridge\"\n }\n ],\n \"time_windows\": [\n {\n \"from\": \"2026-07-01T09:00:00+02:00\",\n \"to\": \"2026-07-01T12:00:00+02:00\"\n }\n ]\n },\n {\n \"demand\": {\n \"weight\": 35\n },\n \"id\": \"job-2\",\n \"location\": {\n \"coordinate\": [\n 3.71,\n 51.06\n ]\n },\n \"service_duration_s\": 600\n }\n ],\n \"objective\": {\n \"costs\": {\n \"currency\": \"EUR\",\n \"per_travel_hour\": 3600\n },\n \"minimize_vehicles\": true\n },\n \"options\": {\n \"runtime\": {\n \"seed\": 42,\n \"time_limit_s\": 5\n }\n },\n \"vehicles\": [\n {\n \"capacity\": {\n \"weight\": 500\n },\n \"id\": \"v1\",\n \"profile\": \"car\",\n \"shifts\": [\n {\n \"end\": {\n \"coordinate\": [\n 3.7174,\n 51.0543\n ]\n },\n \"from\": \"2026-07-01T08:00:00+02:00\",\n \"start\": {\n \"coordinate\": [\n 3.7174,\n 51.0543\n ]\n },\n \"to\": \"2026-07-01T17:00:00+02:00\"\n }\n ],\n \"skills\": [\n \"fridge\"\n ]\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.solvice.io/v3/routing/validate")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"jobs\": [\n {\n \"demand\": {\n \"weight\": 20\n },\n \"id\": \"job-1\",\n \"location\": {\n \"coordinate\": [\n 3.725,\n 51.05\n ]\n },\n \"service_duration_s\": 300,\n \"skills\": [\n {\n \"name\": \"fridge\"\n }\n ],\n \"time_windows\": [\n {\n \"from\": \"2026-07-01T09:00:00+02:00\",\n \"to\": \"2026-07-01T12:00:00+02:00\"\n }\n ]\n },\n {\n \"demand\": {\n \"weight\": 35\n },\n \"id\": \"job-2\",\n \"location\": {\n \"coordinate\": [\n 3.71,\n 51.06\n ]\n },\n \"service_duration_s\": 600\n }\n ],\n \"objective\": {\n \"costs\": {\n \"currency\": \"EUR\",\n \"per_travel_hour\": 3600\n },\n \"minimize_vehicles\": true\n },\n \"options\": {\n \"runtime\": {\n \"seed\": 42,\n \"time_limit_s\": 5\n }\n },\n \"vehicles\": [\n {\n \"capacity\": {\n \"weight\": 500\n },\n \"id\": \"v1\",\n \"profile\": \"car\",\n \"shifts\": [\n {\n \"end\": {\n \"coordinate\": [\n 3.7174,\n 51.0543\n ]\n },\n \"from\": \"2026-07-01T08:00:00+02:00\",\n \"start\": {\n \"coordinate\": [\n 3.7174,\n 51.0543\n ]\n },\n \"to\": \"2026-07-01T17:00:00+02:00\"\n }\n ],\n \"skills\": [\n \"fridge\"\n ]\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.solvice.io/v3/routing/validate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"jobs\": [\n {\n \"demand\": {\n \"weight\": 20\n },\n \"id\": \"job-1\",\n \"location\": {\n \"coordinate\": [\n 3.725,\n 51.05\n ]\n },\n \"service_duration_s\": 300,\n \"skills\": [\n {\n \"name\": \"fridge\"\n }\n ],\n \"time_windows\": [\n {\n \"from\": \"2026-07-01T09:00:00+02:00\",\n \"to\": \"2026-07-01T12:00:00+02:00\"\n }\n ]\n },\n {\n \"demand\": {\n \"weight\": 35\n },\n \"id\": \"job-2\",\n \"location\": {\n \"coordinate\": [\n 3.71,\n 51.06\n ]\n },\n \"service_duration_s\": 600\n }\n ],\n \"objective\": {\n \"costs\": {\n \"currency\": \"EUR\",\n \"per_travel_hour\": 3600\n },\n \"minimize_vehicles\": true\n },\n \"options\": {\n \"runtime\": {\n \"seed\": 42,\n \"time_limit_s\": 5\n }\n },\n \"vehicles\": [\n {\n \"capacity\": {\n \"weight\": 500\n },\n \"id\": \"v1\",\n \"profile\": \"car\",\n \"shifts\": [\n {\n \"end\": {\n \"coordinate\": [\n 3.7174,\n 51.0543\n ]\n },\n \"from\": \"2026-07-01T08:00:00+02:00\",\n \"start\": {\n \"coordinate\": [\n 3.7174,\n 51.0543\n ]\n },\n \"to\": \"2026-07-01T17:00:00+02:00\"\n }\n ],\n \"skills\": [\n \"fridge\"\n ]\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"code": "VALIDATION_ERROR",
"field": "/vehicles",
"message": "At least one vehicle is required",
"status": "BAD_REQUEST"
}{
"code": "VALIDATION_ERROR",
"field": "/vehicles",
"message": "At least one vehicle is required",
"status": "BAD_REQUEST"
}{
"code": "VALIDATION_ERROR",
"field": "/vehicles",
"message": "At least one vehicle is required",
"status": "BAD_REQUEST"
}