Routes
Plan a route
POST /dn/routes/plan creates a route or updates an existing one by name and date, then returns the optimized plan with sequenced jobs.
POST
/
dn
/
routes
/
plan
Plan a route
curl --request POST \
--url https://app.detrack.com/api/v2/dn/routes/plan \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <api-key>' \
--data '
{
"data": {
"name": "sample_run",
"date": "2026-09-15",
"vehicles": [
"Driver 1",
"Driver 2"
],
"job_ids": [
"<string>"
],
"depot_location": {
"id": "674ecabbe8ec54052f7ead41"
},
"end_depot_location": {
"id": "674ecabbe8ec54052f7ead41"
},
"mode": "drive",
"manual_time_windows": false,
"time_window_from": "07:00",
"time_window_to": "23:50",
"traffic": "free_flow",
"max_speed": 123,
"service_time": 123,
"manual_service_time": false,
"avoid_toll": false,
"manual_depot": false,
"manual_end_depot": false,
"retain_assignments": false,
"assign_route": false,
"vrp_exclude_send_driver": false
}
}
'import requests
url = "https://app.detrack.com/api/v2/dn/routes/plan"
payload = { "data": {
"name": "sample_run",
"date": "2026-09-15",
"vehicles": ["Driver 1", "Driver 2"],
"job_ids": ["<string>"],
"depot_location": { "id": "674ecabbe8ec54052f7ead41" },
"end_depot_location": { "id": "674ecabbe8ec54052f7ead41" },
"mode": "drive",
"manual_time_windows": False,
"time_window_from": "07:00",
"time_window_to": "23:50",
"traffic": "free_flow",
"max_speed": 123,
"service_time": 123,
"manual_service_time": False,
"avoid_toll": False,
"manual_depot": False,
"manual_end_depot": False,
"retain_assignments": False,
"assign_route": False,
"vrp_exclude_send_driver": False
} }
headers = {
"X-API-KEY": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-KEY': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
data: {
name: 'sample_run',
date: '2026-09-15',
vehicles: ['Driver 1', 'Driver 2'],
job_ids: ['<string>'],
depot_location: {id: '674ecabbe8ec54052f7ead41'},
end_depot_location: {id: '674ecabbe8ec54052f7ead41'},
mode: 'drive',
manual_time_windows: false,
time_window_from: '07:00',
time_window_to: '23:50',
traffic: 'free_flow',
max_speed: 123,
service_time: 123,
manual_service_time: false,
avoid_toll: false,
manual_depot: false,
manual_end_depot: false,
retain_assignments: false,
assign_route: false,
vrp_exclude_send_driver: false
}
})
};
fetch('https://app.detrack.com/api/v2/dn/routes/plan', 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://app.detrack.com/api/v2/dn/routes/plan",
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([
'data' => [
'name' => 'sample_run',
'date' => '2026-09-15',
'vehicles' => [
'Driver 1',
'Driver 2'
],
'job_ids' => [
'<string>'
],
'depot_location' => [
'id' => '674ecabbe8ec54052f7ead41'
],
'end_depot_location' => [
'id' => '674ecabbe8ec54052f7ead41'
],
'mode' => 'drive',
'manual_time_windows' => false,
'time_window_from' => '07:00',
'time_window_to' => '23:50',
'traffic' => 'free_flow',
'max_speed' => 123,
'service_time' => 123,
'manual_service_time' => false,
'avoid_toll' => false,
'manual_depot' => false,
'manual_end_depot' => false,
'retain_assignments' => false,
'assign_route' => false,
'vrp_exclude_send_driver' => false
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-KEY: <api-key>"
],
]);
$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://app.detrack.com/api/v2/dn/routes/plan"
payload := strings.NewReader("{\n \"data\": {\n \"name\": \"sample_run\",\n \"date\": \"2026-09-15\",\n \"vehicles\": [\n \"Driver 1\",\n \"Driver 2\"\n ],\n \"job_ids\": [\n \"<string>\"\n ],\n \"depot_location\": {\n \"id\": \"674ecabbe8ec54052f7ead41\"\n },\n \"end_depot_location\": {\n \"id\": \"674ecabbe8ec54052f7ead41\"\n },\n \"mode\": \"drive\",\n \"manual_time_windows\": false,\n \"time_window_from\": \"07:00\",\n \"time_window_to\": \"23:50\",\n \"traffic\": \"free_flow\",\n \"max_speed\": 123,\n \"service_time\": 123,\n \"manual_service_time\": false,\n \"avoid_toll\": false,\n \"manual_depot\": false,\n \"manual_end_depot\": false,\n \"retain_assignments\": false,\n \"assign_route\": false,\n \"vrp_exclude_send_driver\": false\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-KEY", "<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://app.detrack.com/api/v2/dn/routes/plan")
.header("X-API-KEY", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"data\": {\n \"name\": \"sample_run\",\n \"date\": \"2026-09-15\",\n \"vehicles\": [\n \"Driver 1\",\n \"Driver 2\"\n ],\n \"job_ids\": [\n \"<string>\"\n ],\n \"depot_location\": {\n \"id\": \"674ecabbe8ec54052f7ead41\"\n },\n \"end_depot_location\": {\n \"id\": \"674ecabbe8ec54052f7ead41\"\n },\n \"mode\": \"drive\",\n \"manual_time_windows\": false,\n \"time_window_from\": \"07:00\",\n \"time_window_to\": \"23:50\",\n \"traffic\": \"free_flow\",\n \"max_speed\": 123,\n \"service_time\": 123,\n \"manual_service_time\": false,\n \"avoid_toll\": false,\n \"manual_depot\": false,\n \"manual_end_depot\": false,\n \"retain_assignments\": false,\n \"assign_route\": false,\n \"vrp_exclude_send_driver\": false\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.detrack.com/api/v2/dn/routes/plan")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"data\": {\n \"name\": \"sample_run\",\n \"date\": \"2026-09-15\",\n \"vehicles\": [\n \"Driver 1\",\n \"Driver 2\"\n ],\n \"job_ids\": [\n \"<string>\"\n ],\n \"depot_location\": {\n \"id\": \"674ecabbe8ec54052f7ead41\"\n },\n \"end_depot_location\": {\n \"id\": \"674ecabbe8ec54052f7ead41\"\n },\n \"mode\": \"drive\",\n \"manual_time_windows\": false,\n \"time_window_from\": \"07:00\",\n \"time_window_to\": \"23:50\",\n \"traffic\": \"free_flow\",\n \"max_speed\": 123,\n \"service_time\": 123,\n \"manual_service_time\": false,\n \"avoid_toll\": false,\n \"manual_depot\": false,\n \"manual_end_depot\": false,\n \"retain_assignments\": false,\n \"assign_route\": false,\n \"vrp_exclude_send_driver\": false\n }\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "69001c6de8ec5410e2570bb3",
"name": "sample_run",
"date": "2026-09-15",
"mode": "drive",
"status": "to_be_confirm",
"message": "<string>",
"vehicle": {},
"job_ids": [
"<string>"
],
"depot_location": {
"id": "68f0d416e8ec54cbf4a04dba",
"name": "Main Depot",
"address": "SM Megamall, EDSA corner Doña Julia Vargas Ave, Mandaluyong, 1550 Metro Manila",
"addr_1": "<string>",
"addr_2": "<string>",
"addr_3": "<string>",
"zip_code": "<string>",
"country": "<string>",
"city": "<string>",
"state": "<string>",
"country_id": "<string>",
"location": [
121.055626,
14.583941
],
"address_lat": 14.583941,
"address_lng": 121.055626
},
"end_depot_location": {
"id": "68f0d416e8ec54cbf4a04dba",
"name": "Main Depot",
"address": "SM Megamall, EDSA corner Doña Julia Vargas Ave, Mandaluyong, 1550 Metro Manila",
"addr_1": "<string>",
"addr_2": "<string>",
"addr_3": "<string>",
"zip_code": "<string>",
"country": "<string>",
"city": "<string>",
"state": "<string>",
"country_id": "<string>",
"location": [
121.055626,
14.583941
],
"address_lat": 14.583941,
"address_lng": 121.055626
},
"total_distance": 15107,
"total_time": 4373.497,
"total_planned": 3,
"total_unplanned": 0,
"type": "balanced",
"jobs": [
{
"id": "68e0bac7e8ec545357500616",
"type": "Delivery",
"status": "dispatched",
"do_number": "DO-10001",
"address": "Vicente Sotto St, CCP Complex, Pasay 1307",
"deliver_to_collect_from": "<string>",
"phone_number": "<string>",
"time_window_from": "09:00",
"time_window_to": "12:00",
"job_sequence": 1,
"eta_time": "07:05",
"run_number": "1",
"service_time": 10,
"geocoded_lat": 14.5542,
"geocoded_lng": 120.9839,
"has_latlng": true
}
],
"planned_routes": [
{
"id": "69001c6fe8ec5410e2570bc0",
"vrp_id": "69001c6de8ec5410e2570bb3",
"name": "1",
"date": "2026-09-15",
"status": "to_be_confirm",
"vehicle": {},
"time_window_from": "07:00",
"time_window_to": "23:50",
"start_time": "07:00",
"completion_time": "08:12",
"total_distance": 15107,
"total_time": 4373.497,
"total_planned": 3,
"total_unplanned": 0,
"planned_jobs": [
{
"id": "68e0bac7e8ec545357500616",
"type": "Delivery",
"status": "dispatched",
"do_number": "DO-10001",
"address": "Vicente Sotto St, CCP Complex, Pasay 1307",
"deliver_to_collect_from": "<string>",
"phone_number": "<string>",
"time_window_from": "09:00",
"time_window_to": "12:00",
"job_sequence": 1,
"eta_time": "07:05",
"run_number": "1",
"service_time": 10,
"geocoded_lat": 14.5542,
"geocoded_lng": 120.9839,
"has_latlng": true
}
],
"unplanned_jobs": [
{
"id": "68e0bac7e8ec545357500616",
"type": "Delivery",
"status": "dispatched",
"do_number": "DO-10001",
"address": "Vicente Sotto St, CCP Complex, Pasay 1307",
"deliver_to_collect_from": "<string>",
"phone_number": "<string>",
"time_window_from": "09:00",
"time_window_to": "12:00",
"job_sequence": 1,
"eta_time": "07:05",
"run_number": "1",
"service_time": 10,
"geocoded_lat": 14.5542,
"geocoded_lng": 120.9839,
"has_latlng": true
}
]
}
],
"unplanned_jobs": [
{
"id": "68e0bac7e8ec545357500616",
"type": "Delivery",
"status": "dispatched",
"do_number": "DO-10001",
"address": "Vicente Sotto St, CCP Complex, Pasay 1307",
"deliver_to_collect_from": "<string>",
"phone_number": "<string>",
"time_window_from": "09:00",
"time_window_to": "12:00",
"job_sequence": 1,
"eta_time": "07:05",
"run_number": "1",
"service_time": 10,
"geocoded_lat": 14.5542,
"geocoded_lng": 120.9839,
"has_latlng": true
}
]
}
}{
"id": "69001c6de8ec5410e2570bb3",
"name": "sample_run",
"date": "2026-09-15",
"mode": "drive",
"status": "to_be_confirm",
"message": "<string>",
"vehicle": {},
"job_ids": [
"<string>"
],
"depot_location": {
"id": "68f0d416e8ec54cbf4a04dba",
"name": "Main Depot",
"address": "SM Megamall, EDSA corner Doña Julia Vargas Ave, Mandaluyong, 1550 Metro Manila",
"addr_1": "<string>",
"addr_2": "<string>",
"addr_3": "<string>",
"zip_code": "<string>",
"country": "<string>",
"city": "<string>",
"state": "<string>",
"country_id": "<string>",
"location": [
121.055626,
14.583941
],
"address_lat": 14.583941,
"address_lng": 121.055626
},
"end_depot_location": {
"id": "68f0d416e8ec54cbf4a04dba",
"name": "Main Depot",
"address": "SM Megamall, EDSA corner Doña Julia Vargas Ave, Mandaluyong, 1550 Metro Manila",
"addr_1": "<string>",
"addr_2": "<string>",
"addr_3": "<string>",
"zip_code": "<string>",
"country": "<string>",
"city": "<string>",
"state": "<string>",
"country_id": "<string>",
"location": [
121.055626,
14.583941
],
"address_lat": 14.583941,
"address_lng": 121.055626
},
"total_distance": 15107,
"total_time": 4373.497,
"total_planned": 3,
"total_unplanned": 0,
"type": "balanced",
"jobs": [
{
"id": "68e0bac7e8ec545357500616",
"type": "Delivery",
"status": "dispatched",
"do_number": "DO-10001",
"address": "Vicente Sotto St, CCP Complex, Pasay 1307",
"deliver_to_collect_from": "<string>",
"phone_number": "<string>",
"time_window_from": "09:00",
"time_window_to": "12:00",
"job_sequence": 1,
"eta_time": "07:05",
"run_number": "1",
"service_time": 10,
"geocoded_lat": 14.5542,
"geocoded_lng": 120.9839,
"has_latlng": true
}
],
"planned_routes": [
{
"id": "69001c6fe8ec5410e2570bc0",
"vrp_id": "69001c6de8ec5410e2570bb3",
"name": "1",
"date": "2026-09-15",
"status": "to_be_confirm",
"vehicle": {},
"time_window_from": "07:00",
"time_window_to": "23:50",
"start_time": "07:00",
"completion_time": "08:12",
"total_distance": 15107,
"total_time": 4373.497,
"total_planned": 3,
"total_unplanned": 0,
"planned_jobs": [
{
"id": "68e0bac7e8ec545357500616",
"type": "Delivery",
"status": "dispatched",
"do_number": "DO-10001",
"address": "Vicente Sotto St, CCP Complex, Pasay 1307",
"deliver_to_collect_from": "<string>",
"phone_number": "<string>",
"time_window_from": "09:00",
"time_window_to": "12:00",
"job_sequence": 1,
"eta_time": "07:05",
"run_number": "1",
"service_time": 10,
"geocoded_lat": 14.5542,
"geocoded_lng": 120.9839,
"has_latlng": true
}
],
"unplanned_jobs": [
{
"id": "68e0bac7e8ec545357500616",
"type": "Delivery",
"status": "dispatched",
"do_number": "DO-10001",
"address": "Vicente Sotto St, CCP Complex, Pasay 1307",
"deliver_to_collect_from": "<string>",
"phone_number": "<string>",
"time_window_from": "09:00",
"time_window_to": "12:00",
"job_sequence": 1,
"eta_time": "07:05",
"run_number": "1",
"service_time": 10,
"geocoded_lat": 14.5542,
"geocoded_lng": 120.9839,
"has_latlng": true
}
]
}
],
"unplanned_jobs": [
{
"id": "68e0bac7e8ec545357500616",
"type": "Delivery",
"status": "dispatched",
"do_number": "DO-10001",
"address": "Vicente Sotto St, CCP Complex, Pasay 1307",
"deliver_to_collect_from": "<string>",
"phone_number": "<string>",
"time_window_from": "09:00",
"time_window_to": "12:00",
"job_sequence": 1,
"eta_time": "07:05",
"run_number": "1",
"service_time": 10,
"geocoded_lat": 14.5542,
"geocoded_lng": 120.9839,
"has_latlng": true
}
]
}{
"code": "invalid_json_format"
}{
"code": "invalid_key",
"message": "Invalid key"
}{
"code": "forbidden"
}{
"code": "no_vehicles_found",
"message": "No Vehicles Found"
}Use this endpoint to build a new route or overwrite an existing route that shares the same
Each route has two levels:
See Errors for other status codes.
name and date. Detrack runs an optimization engine to sequence the supplied job_ids, compute ETAs, and return totals such as distance and duration. If the route already exists, it is replaced with the newly computed plan.
Known issues:
- If you re-plan with the same
nameanddateand the request fails validation, the existing plan has already been deleted and isn’t replaced. Check your request before re-planning (DTR-6207). - Each name in
vehiclesmatches any vehicle whose name contains it, ignoring case. For example,Driver 1also selectsDriver 10. Use vehicle names that aren’t contained in other names (DTR-6206).
Vehicle working hours (
from and to) are configured per driver inside the Detrack app; they are not part of the API request payload.- The plan (the top-level object) holds the plan’s
status, depot, and totals across all vehicles. planned_routeshas one entry per vehicle, with that vehicle’sstatus,start_time,completion_time, time window, and itsplanned_jobsin delivery order (job_sequence,eta_time).
unplanned_jobs. The plan-level vehicle shows one of the plan’s vehicles; use planned_routes[].vehicle to see which vehicle drives which route. See Route status for what each status value means.
Errors
Validation errors return422 with a code and message. The API checks the request in the order below and stops at the first failure.
code | When |
|---|---|
invalid_data | The request body has no data object. |
missing_name_or_date | data.name or data.date is missing. |
missing_jobs | data.job_ids is missing or empty. |
missing_vehicles | data.vehicles is missing or empty. |
error_vehicles | data.vehicles isn’t an array. |
no_vehicles_found | None of the names in data.vehicles match a vehicle in your account. |
validation_failed | The plan couldn’t be saved. The errors array lists each failing field and its codes. |
{
"code": "no_vehicles_found",
"message": "No Vehicles Found"
}
Plan a route
curl --request POST \
--url https://app.detrack.com/api/v2/dn/routes/plan \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <api-key>' \
--data '
{
"data": {
"name": "sample_run",
"date": "2026-09-15",
"vehicles": [
"Driver 1",
"Driver 2"
],
"job_ids": [
"<string>"
],
"depot_location": {
"id": "674ecabbe8ec54052f7ead41"
},
"end_depot_location": {
"id": "674ecabbe8ec54052f7ead41"
},
"mode": "drive",
"manual_time_windows": false,
"time_window_from": "07:00",
"time_window_to": "23:50",
"traffic": "free_flow",
"max_speed": 123,
"service_time": 123,
"manual_service_time": false,
"avoid_toll": false,
"manual_depot": false,
"manual_end_depot": false,
"retain_assignments": false,
"assign_route": false,
"vrp_exclude_send_driver": false
}
}
'import requests
url = "https://app.detrack.com/api/v2/dn/routes/plan"
payload = { "data": {
"name": "sample_run",
"date": "2026-09-15",
"vehicles": ["Driver 1", "Driver 2"],
"job_ids": ["<string>"],
"depot_location": { "id": "674ecabbe8ec54052f7ead41" },
"end_depot_location": { "id": "674ecabbe8ec54052f7ead41" },
"mode": "drive",
"manual_time_windows": False,
"time_window_from": "07:00",
"time_window_to": "23:50",
"traffic": "free_flow",
"max_speed": 123,
"service_time": 123,
"manual_service_time": False,
"avoid_toll": False,
"manual_depot": False,
"manual_end_depot": False,
"retain_assignments": False,
"assign_route": False,
"vrp_exclude_send_driver": False
} }
headers = {
"X-API-KEY": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-KEY': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
data: {
name: 'sample_run',
date: '2026-09-15',
vehicles: ['Driver 1', 'Driver 2'],
job_ids: ['<string>'],
depot_location: {id: '674ecabbe8ec54052f7ead41'},
end_depot_location: {id: '674ecabbe8ec54052f7ead41'},
mode: 'drive',
manual_time_windows: false,
time_window_from: '07:00',
time_window_to: '23:50',
traffic: 'free_flow',
max_speed: 123,
service_time: 123,
manual_service_time: false,
avoid_toll: false,
manual_depot: false,
manual_end_depot: false,
retain_assignments: false,
assign_route: false,
vrp_exclude_send_driver: false
}
})
};
fetch('https://app.detrack.com/api/v2/dn/routes/plan', 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://app.detrack.com/api/v2/dn/routes/plan",
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([
'data' => [
'name' => 'sample_run',
'date' => '2026-09-15',
'vehicles' => [
'Driver 1',
'Driver 2'
],
'job_ids' => [
'<string>'
],
'depot_location' => [
'id' => '674ecabbe8ec54052f7ead41'
],
'end_depot_location' => [
'id' => '674ecabbe8ec54052f7ead41'
],
'mode' => 'drive',
'manual_time_windows' => false,
'time_window_from' => '07:00',
'time_window_to' => '23:50',
'traffic' => 'free_flow',
'max_speed' => 123,
'service_time' => 123,
'manual_service_time' => false,
'avoid_toll' => false,
'manual_depot' => false,
'manual_end_depot' => false,
'retain_assignments' => false,
'assign_route' => false,
'vrp_exclude_send_driver' => false
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-KEY: <api-key>"
],
]);
$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://app.detrack.com/api/v2/dn/routes/plan"
payload := strings.NewReader("{\n \"data\": {\n \"name\": \"sample_run\",\n \"date\": \"2026-09-15\",\n \"vehicles\": [\n \"Driver 1\",\n \"Driver 2\"\n ],\n \"job_ids\": [\n \"<string>\"\n ],\n \"depot_location\": {\n \"id\": \"674ecabbe8ec54052f7ead41\"\n },\n \"end_depot_location\": {\n \"id\": \"674ecabbe8ec54052f7ead41\"\n },\n \"mode\": \"drive\",\n \"manual_time_windows\": false,\n \"time_window_from\": \"07:00\",\n \"time_window_to\": \"23:50\",\n \"traffic\": \"free_flow\",\n \"max_speed\": 123,\n \"service_time\": 123,\n \"manual_service_time\": false,\n \"avoid_toll\": false,\n \"manual_depot\": false,\n \"manual_end_depot\": false,\n \"retain_assignments\": false,\n \"assign_route\": false,\n \"vrp_exclude_send_driver\": false\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-KEY", "<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://app.detrack.com/api/v2/dn/routes/plan")
.header("X-API-KEY", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"data\": {\n \"name\": \"sample_run\",\n \"date\": \"2026-09-15\",\n \"vehicles\": [\n \"Driver 1\",\n \"Driver 2\"\n ],\n \"job_ids\": [\n \"<string>\"\n ],\n \"depot_location\": {\n \"id\": \"674ecabbe8ec54052f7ead41\"\n },\n \"end_depot_location\": {\n \"id\": \"674ecabbe8ec54052f7ead41\"\n },\n \"mode\": \"drive\",\n \"manual_time_windows\": false,\n \"time_window_from\": \"07:00\",\n \"time_window_to\": \"23:50\",\n \"traffic\": \"free_flow\",\n \"max_speed\": 123,\n \"service_time\": 123,\n \"manual_service_time\": false,\n \"avoid_toll\": false,\n \"manual_depot\": false,\n \"manual_end_depot\": false,\n \"retain_assignments\": false,\n \"assign_route\": false,\n \"vrp_exclude_send_driver\": false\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.detrack.com/api/v2/dn/routes/plan")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"data\": {\n \"name\": \"sample_run\",\n \"date\": \"2026-09-15\",\n \"vehicles\": [\n \"Driver 1\",\n \"Driver 2\"\n ],\n \"job_ids\": [\n \"<string>\"\n ],\n \"depot_location\": {\n \"id\": \"674ecabbe8ec54052f7ead41\"\n },\n \"end_depot_location\": {\n \"id\": \"674ecabbe8ec54052f7ead41\"\n },\n \"mode\": \"drive\",\n \"manual_time_windows\": false,\n \"time_window_from\": \"07:00\",\n \"time_window_to\": \"23:50\",\n \"traffic\": \"free_flow\",\n \"max_speed\": 123,\n \"service_time\": 123,\n \"manual_service_time\": false,\n \"avoid_toll\": false,\n \"manual_depot\": false,\n \"manual_end_depot\": false,\n \"retain_assignments\": false,\n \"assign_route\": false,\n \"vrp_exclude_send_driver\": false\n }\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "69001c6de8ec5410e2570bb3",
"name": "sample_run",
"date": "2026-09-15",
"mode": "drive",
"status": "to_be_confirm",
"message": "<string>",
"vehicle": {},
"job_ids": [
"<string>"
],
"depot_location": {
"id": "68f0d416e8ec54cbf4a04dba",
"name": "Main Depot",
"address": "SM Megamall, EDSA corner Doña Julia Vargas Ave, Mandaluyong, 1550 Metro Manila",
"addr_1": "<string>",
"addr_2": "<string>",
"addr_3": "<string>",
"zip_code": "<string>",
"country": "<string>",
"city": "<string>",
"state": "<string>",
"country_id": "<string>",
"location": [
121.055626,
14.583941
],
"address_lat": 14.583941,
"address_lng": 121.055626
},
"end_depot_location": {
"id": "68f0d416e8ec54cbf4a04dba",
"name": "Main Depot",
"address": "SM Megamall, EDSA corner Doña Julia Vargas Ave, Mandaluyong, 1550 Metro Manila",
"addr_1": "<string>",
"addr_2": "<string>",
"addr_3": "<string>",
"zip_code": "<string>",
"country": "<string>",
"city": "<string>",
"state": "<string>",
"country_id": "<string>",
"location": [
121.055626,
14.583941
],
"address_lat": 14.583941,
"address_lng": 121.055626
},
"total_distance": 15107,
"total_time": 4373.497,
"total_planned": 3,
"total_unplanned": 0,
"type": "balanced",
"jobs": [
{
"id": "68e0bac7e8ec545357500616",
"type": "Delivery",
"status": "dispatched",
"do_number": "DO-10001",
"address": "Vicente Sotto St, CCP Complex, Pasay 1307",
"deliver_to_collect_from": "<string>",
"phone_number": "<string>",
"time_window_from": "09:00",
"time_window_to": "12:00",
"job_sequence": 1,
"eta_time": "07:05",
"run_number": "1",
"service_time": 10,
"geocoded_lat": 14.5542,
"geocoded_lng": 120.9839,
"has_latlng": true
}
],
"planned_routes": [
{
"id": "69001c6fe8ec5410e2570bc0",
"vrp_id": "69001c6de8ec5410e2570bb3",
"name": "1",
"date": "2026-09-15",
"status": "to_be_confirm",
"vehicle": {},
"time_window_from": "07:00",
"time_window_to": "23:50",
"start_time": "07:00",
"completion_time": "08:12",
"total_distance": 15107,
"total_time": 4373.497,
"total_planned": 3,
"total_unplanned": 0,
"planned_jobs": [
{
"id": "68e0bac7e8ec545357500616",
"type": "Delivery",
"status": "dispatched",
"do_number": "DO-10001",
"address": "Vicente Sotto St, CCP Complex, Pasay 1307",
"deliver_to_collect_from": "<string>",
"phone_number": "<string>",
"time_window_from": "09:00",
"time_window_to": "12:00",
"job_sequence": 1,
"eta_time": "07:05",
"run_number": "1",
"service_time": 10,
"geocoded_lat": 14.5542,
"geocoded_lng": 120.9839,
"has_latlng": true
}
],
"unplanned_jobs": [
{
"id": "68e0bac7e8ec545357500616",
"type": "Delivery",
"status": "dispatched",
"do_number": "DO-10001",
"address": "Vicente Sotto St, CCP Complex, Pasay 1307",
"deliver_to_collect_from": "<string>",
"phone_number": "<string>",
"time_window_from": "09:00",
"time_window_to": "12:00",
"job_sequence": 1,
"eta_time": "07:05",
"run_number": "1",
"service_time": 10,
"geocoded_lat": 14.5542,
"geocoded_lng": 120.9839,
"has_latlng": true
}
]
}
],
"unplanned_jobs": [
{
"id": "68e0bac7e8ec545357500616",
"type": "Delivery",
"status": "dispatched",
"do_number": "DO-10001",
"address": "Vicente Sotto St, CCP Complex, Pasay 1307",
"deliver_to_collect_from": "<string>",
"phone_number": "<string>",
"time_window_from": "09:00",
"time_window_to": "12:00",
"job_sequence": 1,
"eta_time": "07:05",
"run_number": "1",
"service_time": 10,
"geocoded_lat": 14.5542,
"geocoded_lng": 120.9839,
"has_latlng": true
}
]
}
}{
"id": "69001c6de8ec5410e2570bb3",
"name": "sample_run",
"date": "2026-09-15",
"mode": "drive",
"status": "to_be_confirm",
"message": "<string>",
"vehicle": {},
"job_ids": [
"<string>"
],
"depot_location": {
"id": "68f0d416e8ec54cbf4a04dba",
"name": "Main Depot",
"address": "SM Megamall, EDSA corner Doña Julia Vargas Ave, Mandaluyong, 1550 Metro Manila",
"addr_1": "<string>",
"addr_2": "<string>",
"addr_3": "<string>",
"zip_code": "<string>",
"country": "<string>",
"city": "<string>",
"state": "<string>",
"country_id": "<string>",
"location": [
121.055626,
14.583941
],
"address_lat": 14.583941,
"address_lng": 121.055626
},
"end_depot_location": {
"id": "68f0d416e8ec54cbf4a04dba",
"name": "Main Depot",
"address": "SM Megamall, EDSA corner Doña Julia Vargas Ave, Mandaluyong, 1550 Metro Manila",
"addr_1": "<string>",
"addr_2": "<string>",
"addr_3": "<string>",
"zip_code": "<string>",
"country": "<string>",
"city": "<string>",
"state": "<string>",
"country_id": "<string>",
"location": [
121.055626,
14.583941
],
"address_lat": 14.583941,
"address_lng": 121.055626
},
"total_distance": 15107,
"total_time": 4373.497,
"total_planned": 3,
"total_unplanned": 0,
"type": "balanced",
"jobs": [
{
"id": "68e0bac7e8ec545357500616",
"type": "Delivery",
"status": "dispatched",
"do_number": "DO-10001",
"address": "Vicente Sotto St, CCP Complex, Pasay 1307",
"deliver_to_collect_from": "<string>",
"phone_number": "<string>",
"time_window_from": "09:00",
"time_window_to": "12:00",
"job_sequence": 1,
"eta_time": "07:05",
"run_number": "1",
"service_time": 10,
"geocoded_lat": 14.5542,
"geocoded_lng": 120.9839,
"has_latlng": true
}
],
"planned_routes": [
{
"id": "69001c6fe8ec5410e2570bc0",
"vrp_id": "69001c6de8ec5410e2570bb3",
"name": "1",
"date": "2026-09-15",
"status": "to_be_confirm",
"vehicle": {},
"time_window_from": "07:00",
"time_window_to": "23:50",
"start_time": "07:00",
"completion_time": "08:12",
"total_distance": 15107,
"total_time": 4373.497,
"total_planned": 3,
"total_unplanned": 0,
"planned_jobs": [
{
"id": "68e0bac7e8ec545357500616",
"type": "Delivery",
"status": "dispatched",
"do_number": "DO-10001",
"address": "Vicente Sotto St, CCP Complex, Pasay 1307",
"deliver_to_collect_from": "<string>",
"phone_number": "<string>",
"time_window_from": "09:00",
"time_window_to": "12:00",
"job_sequence": 1,
"eta_time": "07:05",
"run_number": "1",
"service_time": 10,
"geocoded_lat": 14.5542,
"geocoded_lng": 120.9839,
"has_latlng": true
}
],
"unplanned_jobs": [
{
"id": "68e0bac7e8ec545357500616",
"type": "Delivery",
"status": "dispatched",
"do_number": "DO-10001",
"address": "Vicente Sotto St, CCP Complex, Pasay 1307",
"deliver_to_collect_from": "<string>",
"phone_number": "<string>",
"time_window_from": "09:00",
"time_window_to": "12:00",
"job_sequence": 1,
"eta_time": "07:05",
"run_number": "1",
"service_time": 10,
"geocoded_lat": 14.5542,
"geocoded_lng": 120.9839,
"has_latlng": true
}
]
}
],
"unplanned_jobs": [
{
"id": "68e0bac7e8ec545357500616",
"type": "Delivery",
"status": "dispatched",
"do_number": "DO-10001",
"address": "Vicente Sotto St, CCP Complex, Pasay 1307",
"deliver_to_collect_from": "<string>",
"phone_number": "<string>",
"time_window_from": "09:00",
"time_window_to": "12:00",
"job_sequence": 1,
"eta_time": "07:05",
"run_number": "1",
"service_time": 10,
"geocoded_lat": 14.5542,
"geocoded_lng": 120.9839,
"has_latlng": true
}
]
}{
"code": "invalid_json_format"
}{
"code": "invalid_key",
"message": "Invalid key"
}{
"code": "forbidden"
}{
"code": "no_vehicles_found",
"message": "No Vehicles Found"
}