Suggest
Rank the best feasible insertion positions for new jobs in an existing plan
curl --request POST \
--url https://api.solvice.io/v3/routing/suggest \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"options": {
"max_suggestions": 5
},
"plan": {
"routes": [
{
"shift": "mon",
"stops": [
{
"id": "job-1",
"type": "job"
}
],
"vehicle": "v1"
}
]
},
"problem": {
"jobs": [
{
"id": "job-1",
"location": [
3.725,
51.05
],
"pickup": {
"weight": 10
},
"service_duration_s": 300
},
{
"id": "job-2",
"location": [
3.71,
51.06
],
"pickup": {
"weight": 10
},
"service_duration_s": 300
}
],
"vehicles": [
{
"capacity": {
"weight": 500
},
"id": "v1",
"shifts": [
{
"end": {
"location": [
3.7174,
51.0543
]
},
"from": "2026-07-01T08:00:00+02:00",
"id": "mon",
"start": {
"location": [
3.7174,
51.0543
]
},
"to": "2026-07-01T17:00:00+02:00"
}
]
}
]
}
}
'import requests
url = "https://api.solvice.io/v3/routing/suggest"
payload = {
"options": { "max_suggestions": 5 },
"plan": { "routes": [
{
"shift": "mon",
"stops": [
{
"id": "job-1",
"type": "job"
}
],
"vehicle": "v1"
}
] },
"problem": {
"jobs": [
{
"id": "job-1",
"location": [3.725, 51.05],
"pickup": { "weight": 10 },
"service_duration_s": 300
},
{
"id": "job-2",
"location": [3.71, 51.06],
"pickup": { "weight": 10 },
"service_duration_s": 300
}
],
"vehicles": [
{
"capacity": { "weight": 500 },
"id": "v1",
"shifts": [
{
"end": { "location": [3.7174, 51.0543] },
"from": "2026-07-01T08:00:00+02:00",
"id": "mon",
"start": { "location": [3.7174, 51.0543] },
"to": "2026-07-01T17:00:00+02:00"
}
]
}
]
}
}
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({
options: {max_suggestions: 5},
plan: {routes: [{shift: 'mon', stops: [{id: 'job-1', type: 'job'}], vehicle: 'v1'}]},
problem: {
jobs: [
{
id: 'job-1',
location: [3.725, 51.05],
pickup: {weight: 10},
service_duration_s: 300
},
{
id: 'job-2',
location: [3.71, 51.06],
pickup: {weight: 10},
service_duration_s: 300
}
],
vehicles: [
{
capacity: {weight: 500},
id: 'v1',
shifts: [
{
end: {location: [3.7174, 51.0543]},
from: '2026-07-01T08:00:00+02:00',
id: 'mon',
start: {location: [3.7174, 51.0543]},
to: '2026-07-01T17:00:00+02:00'
}
]
}
]
}
})
};
fetch('https://api.solvice.io/v3/routing/suggest', 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/suggest",
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([
'options' => [
'max_suggestions' => 5
],
'plan' => [
'routes' => [
[
'shift' => 'mon',
'stops' => [
[
'id' => 'job-1',
'type' => 'job'
]
],
'vehicle' => 'v1'
]
]
],
'problem' => [
'jobs' => [
[
'id' => 'job-1',
'location' => [
3.725,
51.05
],
'pickup' => [
'weight' => 10
],
'service_duration_s' => 300
],
[
'id' => 'job-2',
'location' => [
3.71,
51.06
],
'pickup' => [
'weight' => 10
],
'service_duration_s' => 300
]
],
'vehicles' => [
[
'capacity' => [
'weight' => 500
],
'id' => 'v1',
'shifts' => [
[
'end' => [
'location' => [
3.7174,
51.0543
]
],
'from' => '2026-07-01T08:00:00+02:00',
'id' => 'mon',
'start' => [
'location' => [
3.7174,
51.0543
]
],
'to' => '2026-07-01T17:00:00+02:00'
]
]
]
]
]
]),
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/suggest"
payload := strings.NewReader("{\n \"options\": {\n \"max_suggestions\": 5\n },\n \"plan\": {\n \"routes\": [\n {\n \"shift\": \"mon\",\n \"stops\": [\n {\n \"id\": \"job-1\",\n \"type\": \"job\"\n }\n ],\n \"vehicle\": \"v1\"\n }\n ]\n },\n \"problem\": {\n \"jobs\": [\n {\n \"id\": \"job-1\",\n \"location\": [\n 3.725,\n 51.05\n ],\n \"pickup\": {\n \"weight\": 10\n },\n \"service_duration_s\": 300\n },\n {\n \"id\": \"job-2\",\n \"location\": [\n 3.71,\n 51.06\n ],\n \"pickup\": {\n \"weight\": 10\n },\n \"service_duration_s\": 300\n }\n ],\n \"vehicles\": [\n {\n \"capacity\": {\n \"weight\": 500\n },\n \"id\": \"v1\",\n \"shifts\": [\n {\n \"end\": {\n \"location\": [\n 3.7174,\n 51.0543\n ]\n },\n \"from\": \"2026-07-01T08:00:00+02:00\",\n \"id\": \"mon\",\n \"start\": {\n \"location\": [\n 3.7174,\n 51.0543\n ]\n },\n \"to\": \"2026-07-01T17:00:00+02:00\"\n }\n ]\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/suggest")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"options\": {\n \"max_suggestions\": 5\n },\n \"plan\": {\n \"routes\": [\n {\n \"shift\": \"mon\",\n \"stops\": [\n {\n \"id\": \"job-1\",\n \"type\": \"job\"\n }\n ],\n \"vehicle\": \"v1\"\n }\n ]\n },\n \"problem\": {\n \"jobs\": [\n {\n \"id\": \"job-1\",\n \"location\": [\n 3.725,\n 51.05\n ],\n \"pickup\": {\n \"weight\": 10\n },\n \"service_duration_s\": 300\n },\n {\n \"id\": \"job-2\",\n \"location\": [\n 3.71,\n 51.06\n ],\n \"pickup\": {\n \"weight\": 10\n },\n \"service_duration_s\": 300\n }\n ],\n \"vehicles\": [\n {\n \"capacity\": {\n \"weight\": 500\n },\n \"id\": \"v1\",\n \"shifts\": [\n {\n \"end\": {\n \"location\": [\n 3.7174,\n 51.0543\n ]\n },\n \"from\": \"2026-07-01T08:00:00+02:00\",\n \"id\": \"mon\",\n \"start\": {\n \"location\": [\n 3.7174,\n 51.0543\n ]\n },\n \"to\": \"2026-07-01T17:00:00+02:00\"\n }\n ]\n }\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.solvice.io/v3/routing/suggest")
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 \"options\": {\n \"max_suggestions\": 5\n },\n \"plan\": {\n \"routes\": [\n {\n \"shift\": \"mon\",\n \"stops\": [\n {\n \"id\": \"job-1\",\n \"type\": \"job\"\n }\n ],\n \"vehicle\": \"v1\"\n }\n ]\n },\n \"problem\": {\n \"jobs\": [\n {\n \"id\": \"job-1\",\n \"location\": [\n 3.725,\n 51.05\n ],\n \"pickup\": {\n \"weight\": 10\n },\n \"service_duration_s\": 300\n },\n {\n \"id\": \"job-2\",\n \"location\": [\n 3.71,\n 51.06\n ],\n \"pickup\": {\n \"weight\": 10\n },\n \"service_duration_s\": 300\n }\n ],\n \"vehicles\": [\n {\n \"capacity\": {\n \"weight\": 500\n },\n \"id\": \"v1\",\n \"shifts\": [\n {\n \"end\": {\n \"location\": [\n 3.7174,\n 51.0543\n ]\n },\n \"from\": \"2026-07-01T08:00:00+02:00\",\n \"id\": \"mon\",\n \"start\": {\n \"location\": [\n 3.7174,\n 51.0543\n ]\n },\n \"to\": \"2026-07-01T17:00:00+02:00\"\n }\n ]\n }\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"elapsed_ms": 8,
"suggestions": [
{
"insertions": [
{
"delta": {
"cost": 12.4,
"distance_m": 2400,
"duration_s": 240
},
"placements": [
{
"arrival": "2026-07-01T09:30:00+02:00",
"id": "job-2",
"latest_arrival": "2026-07-01T10:15:00+02:00",
"shift": "mon",
"type": "job",
"vehicle": "v1"
}
],
"routes": [
{
"shift": "mon",
"stops": [
{
"id": "job-1",
"type": "job"
},
{
"id": "job-2",
"type": "job"
}
],
"vehicle": "v1"
}
]
}
],
"job_id": "job-2"
}
],
"truncated": false
}{
"code": "invalid_request",
"errors": [
{
"code": "out_of_range",
"message": "depot 'gent': service_duration_s must be >= 0, got -60",
"pointer": "/problem/depots/0/service_duration_s"
}
],
"message": "depot 'gent': service_duration_s must be >= 0, got -60",
"request_id": "req_7f3a2c90d1e4b5a6",
"status": "BAD_REQUEST"
}{
"code": "feature_not_enabled",
"message": "travel.engine: 'tomtom_real_time' is not enabled for this account; use engine 'tomtom'",
"request_id": "req_7f3a2c90d1e4b5a6",
"status": "FORBIDDEN"
}{
"code": "payload_too_large",
"message": "Request body exceeds 10485760 bytes",
"request_id": "req_7f3a2c90d1e4b5a6",
"status": "PAYLOAD_TOO_LARGE"
}{
"code": "unsupported_media_type",
"message": "Expected request with `Content-Type: application/json`",
"request_id": "req_7f3a2c90d1e4b5a6",
"status": "UNSUPPORTED_MEDIA_TYPE"
}{
"code": "invalid_request",
"errors": [
{
"code": "out_of_range",
"message": "depot 'gent': service_duration_s must be >= 0, got -60",
"pointer": "/problem/depots/0/service_duration_s"
}
],
"message": "depot 'gent': service_duration_s must be >= 0, got -60",
"request_id": "req_7f3a2c90d1e4b5a6",
"status": "BAD_REQUEST"
}{
"code": "invalid_request",
"errors": [
{
"code": "out_of_range",
"message": "depot 'gent': service_duration_s must be >= 0, got -60",
"pointer": "/problem/depots/0/service_duration_s"
}
],
"message": "depot 'gent': service_duration_s must be >= 0, got -60",
"request_id": "req_7f3a2c90d1e4b5a6",
"status": "BAD_REQUEST"
}{
"code": "overloaded",
"message": "All solver slots are busy, try again later",
"request_id": "req_7f3a2c90d1e4b5a6",
"status": "SERVICE_UNAVAILABLE"
}Authorizations
Query Parameters
Check the request without fetching a matrix or searching. 200
{"valid": true, "warnings": []}, or a 400 for the problem, options
and caps; plan is matched against the problem only by the real call,
after the fetch (suggest's check that plan leaves a task to place
does run here).
Any other query parameter is rejected with a 400 unknown_field, as in
the body: a misspelt validateOnly must not fall through to a billed
solve.
Body
Request body for POST /v3/routing/suggest.
The same body as POST /v3/routing/evaluate, plus optional options.
Given the committed plan over problem, ranks the feasible insertion
positions for every task of problem that is not in plan — the tasks a
solve would place and an evaluate would report as unassigned. Each task
(or unit — a shipment, or tasks tied by one sequence/same_vehicle/
same_day/same_route relation) is ranked independently against the same
committed plan; the plan is never modified.
The committed plan. Never modified, never reordered. On suggest,
locked_count keeps insertions after a route's dispatched prefix.
Show child attributes
Show child attributes
Problem definition — identical to POST /v3/routing/solve. Every task
of it that is not in plan is a task to place.
Show child attributes
Show child attributes
{
"depots": [
{
"id": "gent",
"location": [3.7174, 51.0543]
}
],
"jobs": [
{
"id": "job-1",
"location": [3.725, 51.05],
"pickup": { "weight": 20 },
"service_duration_s": 300
}
],
"vehicles": [
{
"capacity": { "weight": 500 },
"id": "v1",
"shifts": [
{
"end": { "depot": "gent" },
"from": "2026-07-01T08:00:00+02:00",
"id": "mon",
"start": { "depot": "gent" },
"to": "2026-07-01T17:00:00+02:00"
}
]
}
]
}
Suggest options. Absent: the defaults.
Show child attributes
Show child attributes
{ "max_suggestions": 5, "time_limit_s": 2 }
Response
Suggestions computed. With ?validate_only=true: a ValidateOnlyResponse, {"valid": true, "warnings": []}, without a matrix fetch or a search, not billed.
- Option 1
- Option 2
The 200 body of solve, evaluate and suggest: the call's result, or with
?validate_only=true the validation verdict (ValidateOnlyResponse).
Wall-clock time taken by the request, in milliseconds.
x >= 08
One entry per unit of tasks outside plan, in problem order (jobs,
then shipments; a relation group sorts at its first-listed member).
Show child attributes
Show child attributes
true when options.time_limit_s cut the search short, or a
multi-member unit came back empty after the search had discarded
candidates (an inconclusive "not found"; its reason_code is
candidates_exhausted). Lists may then be incomplete or missing the
best insertion. A single visit's only level is never pruned, so its
empty list is proof of infeasibility unless the budget cut it, and its
reason_code is then time_limit.
Was this page helpful?
curl --request POST \
--url https://api.solvice.io/v3/routing/suggest \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"options": {
"max_suggestions": 5
},
"plan": {
"routes": [
{
"shift": "mon",
"stops": [
{
"id": "job-1",
"type": "job"
}
],
"vehicle": "v1"
}
]
},
"problem": {
"jobs": [
{
"id": "job-1",
"location": [
3.725,
51.05
],
"pickup": {
"weight": 10
},
"service_duration_s": 300
},
{
"id": "job-2",
"location": [
3.71,
51.06
],
"pickup": {
"weight": 10
},
"service_duration_s": 300
}
],
"vehicles": [
{
"capacity": {
"weight": 500
},
"id": "v1",
"shifts": [
{
"end": {
"location": [
3.7174,
51.0543
]
},
"from": "2026-07-01T08:00:00+02:00",
"id": "mon",
"start": {
"location": [
3.7174,
51.0543
]
},
"to": "2026-07-01T17:00:00+02:00"
}
]
}
]
}
}
'import requests
url = "https://api.solvice.io/v3/routing/suggest"
payload = {
"options": { "max_suggestions": 5 },
"plan": { "routes": [
{
"shift": "mon",
"stops": [
{
"id": "job-1",
"type": "job"
}
],
"vehicle": "v1"
}
] },
"problem": {
"jobs": [
{
"id": "job-1",
"location": [3.725, 51.05],
"pickup": { "weight": 10 },
"service_duration_s": 300
},
{
"id": "job-2",
"location": [3.71, 51.06],
"pickup": { "weight": 10 },
"service_duration_s": 300
}
],
"vehicles": [
{
"capacity": { "weight": 500 },
"id": "v1",
"shifts": [
{
"end": { "location": [3.7174, 51.0543] },
"from": "2026-07-01T08:00:00+02:00",
"id": "mon",
"start": { "location": [3.7174, 51.0543] },
"to": "2026-07-01T17:00:00+02:00"
}
]
}
]
}
}
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({
options: {max_suggestions: 5},
plan: {routes: [{shift: 'mon', stops: [{id: 'job-1', type: 'job'}], vehicle: 'v1'}]},
problem: {
jobs: [
{
id: 'job-1',
location: [3.725, 51.05],
pickup: {weight: 10},
service_duration_s: 300
},
{
id: 'job-2',
location: [3.71, 51.06],
pickup: {weight: 10},
service_duration_s: 300
}
],
vehicles: [
{
capacity: {weight: 500},
id: 'v1',
shifts: [
{
end: {location: [3.7174, 51.0543]},
from: '2026-07-01T08:00:00+02:00',
id: 'mon',
start: {location: [3.7174, 51.0543]},
to: '2026-07-01T17:00:00+02:00'
}
]
}
]
}
})
};
fetch('https://api.solvice.io/v3/routing/suggest', 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/suggest",
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([
'options' => [
'max_suggestions' => 5
],
'plan' => [
'routes' => [
[
'shift' => 'mon',
'stops' => [
[
'id' => 'job-1',
'type' => 'job'
]
],
'vehicle' => 'v1'
]
]
],
'problem' => [
'jobs' => [
[
'id' => 'job-1',
'location' => [
3.725,
51.05
],
'pickup' => [
'weight' => 10
],
'service_duration_s' => 300
],
[
'id' => 'job-2',
'location' => [
3.71,
51.06
],
'pickup' => [
'weight' => 10
],
'service_duration_s' => 300
]
],
'vehicles' => [
[
'capacity' => [
'weight' => 500
],
'id' => 'v1',
'shifts' => [
[
'end' => [
'location' => [
3.7174,
51.0543
]
],
'from' => '2026-07-01T08:00:00+02:00',
'id' => 'mon',
'start' => [
'location' => [
3.7174,
51.0543
]
],
'to' => '2026-07-01T17:00:00+02:00'
]
]
]
]
]
]),
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/suggest"
payload := strings.NewReader("{\n \"options\": {\n \"max_suggestions\": 5\n },\n \"plan\": {\n \"routes\": [\n {\n \"shift\": \"mon\",\n \"stops\": [\n {\n \"id\": \"job-1\",\n \"type\": \"job\"\n }\n ],\n \"vehicle\": \"v1\"\n }\n ]\n },\n \"problem\": {\n \"jobs\": [\n {\n \"id\": \"job-1\",\n \"location\": [\n 3.725,\n 51.05\n ],\n \"pickup\": {\n \"weight\": 10\n },\n \"service_duration_s\": 300\n },\n {\n \"id\": \"job-2\",\n \"location\": [\n 3.71,\n 51.06\n ],\n \"pickup\": {\n \"weight\": 10\n },\n \"service_duration_s\": 300\n }\n ],\n \"vehicles\": [\n {\n \"capacity\": {\n \"weight\": 500\n },\n \"id\": \"v1\",\n \"shifts\": [\n {\n \"end\": {\n \"location\": [\n 3.7174,\n 51.0543\n ]\n },\n \"from\": \"2026-07-01T08:00:00+02:00\",\n \"id\": \"mon\",\n \"start\": {\n \"location\": [\n 3.7174,\n 51.0543\n ]\n },\n \"to\": \"2026-07-01T17:00:00+02:00\"\n }\n ]\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/suggest")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"options\": {\n \"max_suggestions\": 5\n },\n \"plan\": {\n \"routes\": [\n {\n \"shift\": \"mon\",\n \"stops\": [\n {\n \"id\": \"job-1\",\n \"type\": \"job\"\n }\n ],\n \"vehicle\": \"v1\"\n }\n ]\n },\n \"problem\": {\n \"jobs\": [\n {\n \"id\": \"job-1\",\n \"location\": [\n 3.725,\n 51.05\n ],\n \"pickup\": {\n \"weight\": 10\n },\n \"service_duration_s\": 300\n },\n {\n \"id\": \"job-2\",\n \"location\": [\n 3.71,\n 51.06\n ],\n \"pickup\": {\n \"weight\": 10\n },\n \"service_duration_s\": 300\n }\n ],\n \"vehicles\": [\n {\n \"capacity\": {\n \"weight\": 500\n },\n \"id\": \"v1\",\n \"shifts\": [\n {\n \"end\": {\n \"location\": [\n 3.7174,\n 51.0543\n ]\n },\n \"from\": \"2026-07-01T08:00:00+02:00\",\n \"id\": \"mon\",\n \"start\": {\n \"location\": [\n 3.7174,\n 51.0543\n ]\n },\n \"to\": \"2026-07-01T17:00:00+02:00\"\n }\n ]\n }\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.solvice.io/v3/routing/suggest")
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 \"options\": {\n \"max_suggestions\": 5\n },\n \"plan\": {\n \"routes\": [\n {\n \"shift\": \"mon\",\n \"stops\": [\n {\n \"id\": \"job-1\",\n \"type\": \"job\"\n }\n ],\n \"vehicle\": \"v1\"\n }\n ]\n },\n \"problem\": {\n \"jobs\": [\n {\n \"id\": \"job-1\",\n \"location\": [\n 3.725,\n 51.05\n ],\n \"pickup\": {\n \"weight\": 10\n },\n \"service_duration_s\": 300\n },\n {\n \"id\": \"job-2\",\n \"location\": [\n 3.71,\n 51.06\n ],\n \"pickup\": {\n \"weight\": 10\n },\n \"service_duration_s\": 300\n }\n ],\n \"vehicles\": [\n {\n \"capacity\": {\n \"weight\": 500\n },\n \"id\": \"v1\",\n \"shifts\": [\n {\n \"end\": {\n \"location\": [\n 3.7174,\n 51.0543\n ]\n },\n \"from\": \"2026-07-01T08:00:00+02:00\",\n \"id\": \"mon\",\n \"start\": {\n \"location\": [\n 3.7174,\n 51.0543\n ]\n },\n \"to\": \"2026-07-01T17:00:00+02:00\"\n }\n ]\n }\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"elapsed_ms": 8,
"suggestions": [
{
"insertions": [
{
"delta": {
"cost": 12.4,
"distance_m": 2400,
"duration_s": 240
},
"placements": [
{
"arrival": "2026-07-01T09:30:00+02:00",
"id": "job-2",
"latest_arrival": "2026-07-01T10:15:00+02:00",
"shift": "mon",
"type": "job",
"vehicle": "v1"
}
],
"routes": [
{
"shift": "mon",
"stops": [
{
"id": "job-1",
"type": "job"
},
{
"id": "job-2",
"type": "job"
}
],
"vehicle": "v1"
}
]
}
],
"job_id": "job-2"
}
],
"truncated": false
}{
"code": "invalid_request",
"errors": [
{
"code": "out_of_range",
"message": "depot 'gent': service_duration_s must be >= 0, got -60",
"pointer": "/problem/depots/0/service_duration_s"
}
],
"message": "depot 'gent': service_duration_s must be >= 0, got -60",
"request_id": "req_7f3a2c90d1e4b5a6",
"status": "BAD_REQUEST"
}{
"code": "feature_not_enabled",
"message": "travel.engine: 'tomtom_real_time' is not enabled for this account; use engine 'tomtom'",
"request_id": "req_7f3a2c90d1e4b5a6",
"status": "FORBIDDEN"
}{
"code": "payload_too_large",
"message": "Request body exceeds 10485760 bytes",
"request_id": "req_7f3a2c90d1e4b5a6",
"status": "PAYLOAD_TOO_LARGE"
}{
"code": "unsupported_media_type",
"message": "Expected request with `Content-Type: application/json`",
"request_id": "req_7f3a2c90d1e4b5a6",
"status": "UNSUPPORTED_MEDIA_TYPE"
}{
"code": "invalid_request",
"errors": [
{
"code": "out_of_range",
"message": "depot 'gent': service_duration_s must be >= 0, got -60",
"pointer": "/problem/depots/0/service_duration_s"
}
],
"message": "depot 'gent': service_duration_s must be >= 0, got -60",
"request_id": "req_7f3a2c90d1e4b5a6",
"status": "BAD_REQUEST"
}{
"code": "invalid_request",
"errors": [
{
"code": "out_of_range",
"message": "depot 'gent': service_duration_s must be >= 0, got -60",
"pointer": "/problem/depots/0/service_duration_s"
}
],
"message": "depot 'gent': service_duration_s must be >= 0, got -60",
"request_id": "req_7f3a2c90d1e4b5a6",
"status": "BAD_REQUEST"
}{
"code": "overloaded",
"message": "All solver slots are busy, try again later",
"request_id": "req_7f3a2c90d1e4b5a6",
"status": "SERVICE_UNAVAILABLE"
}