FleetWorkAPI Docs

API Reference

Tài liệu kỹ thuật cho dịch vụ tối ưu lộ trình Optimize tại https://live.fleetwork.vn/api/v1/optimize.


Base Path

POST https://live.fleetwork.vn/api/v1/optimize
Content-Type: application/json
X-API-Key: <your_api_key>

API này nhận payload JSON theo format đầu vào và trả về kết quả tối ưu dưới dạng JSON.


Phạm vi tài liệu

Tài liệu này mô tả:

  • schema request cho bài toán Vehicle Routing Problem (Optimize)
  • schema response của kết quả tối ưu
  • ý nghĩa các object, field và ràng buộc dữ liệu
  • các quy ước đơn vị đo và format thời gian

Tài liệu mô tả 2 chế độ xử lý:

  • Solving mode: tối ưu lộ trình mặc định
  • Plan mode: tính ETA cho route đã được mô tả trước

Tài liệu này tập trung vào payload contract dùng chung cho hai chế độ. Cách backend /api/v1/optimize chọn mode thực thi phụ thuộc implementation của dịch vụ triển khai.


Authentication

API xác thực qua request header:

HeaderGiá trị
X-API-KeyAPI key của account
Content-Typeapplication/json

⚠️ Không cần truyền X-Internal-Token hay X-Account-Id — gateway tự inject.

Sai hoặc thiếu key sẽ trả về 401 Unauthorized (no body — ASP.NET default).


Quy ước dữ liệu

Quy ướcGiá trị
Thứ tự tọa độ[lon, lat]
Thời gianseconds
Khoảng cáchmeters
time_window[start, end] với cả 2 đầu mút đều inclusive
cost trong outputcost nội bộ dùng cho objective optimization
taskcó thể là job, pickup hoặc delivery

Mục lục


1. Request Overview

Request body là JSON object mô tả bài toán tối ưu.

KeyRequiredTypeMô tả
jobsNojob[]Danh sách điểm giao việc độc lập.
shipmentsNoshipment[]Danh sách cặp pickup-delivery.
vehiclesYesvehicle[]Danh sách xe khả dụng để tối ưu.
matricesNoobjectCustom matrices theo từng profile.
matrixNonumber[][]Legacy field đã deprecated.

Ví dụ request tối thiểu

{
  "jobs": [
    {
      "id": 1,
      "location": [106.70098, 10.77689],
      "service": 300
    }
  ],
  "vehicles": [
    {
      "id": 1,
      "start": [106.66017, 10.76262],
      "end": [106.66017, 10.76262]
    }
  ]
}

Validation cơ bản

  • vehicles phải có ít nhất 1 phần tử
  • id của job không được trùng nhau
  • pickup.iddelivery.id trong shipments không được trùng nhau cùng loại
  • nếu dùng custom matrices thì phải khai báo *_index tương ứng
  • nếu không dùng custom matrices thì phải khai báo tọa độ thật qua location, start, end

2. Jobs

job mô tả một điểm công việc độc lập cần được một xe ghé qua.

FieldRequiredTypeMô tả
idYesintegerID duy nhất của job.
descriptionNostringMô tả job.
locationCond.[lon, lat]Tọa độ job. Bắt buộc nếu không dùng custom matrix.
location_indexCond.integerIndex dòng/cột trong custom matrices. Bắt buộc nếu dùng matrix.
setupNointegerThời gian setup, mặc định 0.
serviceNointegerThời gian phục vụ, mặc định 0.
setup_per_typeNoobjectMap theo vehicle.type để override setup.
service_per_typeNoobjectMap theo vehicle.type để override service.
deliveryNointeger[]Nhu cầu delivery đa chiều.
pickupNointeger[]Nhu cầu pickup đa chiều.
skillsNointeger[]Tập kỹ năng bắt buộc.
priorityNointegerMức ưu tiên từ 0 đến 100, mặc định 0.
time_windowsNotime_window[]Các khoảng thời gian hợp lệ để bắt đầu service.

Ví dụ job

{
  "id": 101,
  "description": "Giao hồ sơ chi nhánh A",
  "location": [106.70098, 10.77689],
  "setup": 60,
  "service": 300,
  "delivery": [1],
  "skills": [2, 7],
  "priority": 80,
  "time_windows": [[1713402000, 1713405600]]
}

Ghi chú

  • setup chỉ áp dụng khi xe vừa đến một location mới
  • nếu nhiều task liên tiếp xảy ra cùng vị trí, task sau chỉ tính service
  • skills của job phải là tập con của skills xe

3. Shipments

shipment mô tả một cặp công việc có thứ tự bắt buộc: pickup trước, delivery sau.

FieldRequiredTypeMô tả
pickupYesshipment_stepĐiểm lấy hàng.
deliveryYesshipment_stepĐiểm giao hàng.
amountNointeger[]Tải trọng đa chiều của shipment.
skillsNointeger[]Kỹ năng bắt buộc.
priorityNointegerMức ưu tiên 0..100.

3.1 Shipment Step

FieldRequiredTypeMô tả
idYesintegerID của step.
descriptionNostringMô tả step.
locationCond.[lon, lat]Tọa độ step.
location_indexCond.integerChỉ số matrix tương ứng.
setupNointegerSetup duration, mặc định 0.
serviceNointegerService duration, mặc định 0.
setup_per_typeNoobjectOverride setup theo loại xe.
service_per_typeNoobjectOverride service theo loại xe.
time_windowsNotime_window[]Các slot thời gian hợp lệ.

Ví dụ shipment

{
  "pickup": {
    "id": 201,
    "location": [106.66017, 10.76262],
    "service": 180
  },
  "delivery": {
    "id": 202,
    "location": [106.70098, 10.77689],
    "service": 240
  },
  "amount": [5],
  "skills": [3],
  "priority": 90
}

Ghi chú

  • backend sẽ báo lỗi nếu delivery xuất hiện trước pickup
  • shipment phù hợp với bài toán lấy hàng - giao hàng có ràng buộc precedence

4. Vehicles

vehicle mô tả nguồn lực có thể dùng để phục vụ jobs/shipments.

FieldRequiredTypeMô tả
idYesintegerID xe.
profileNostringRouting profile: car | truck | motorcycle, mặc định car.
descriptionNostringMô tả xe.
startCond.[lon, lat]Điểm xuất phát.
start_indexCond.integerIndex trong matrix cho start.
endCond.[lon, lat]Điểm kết thúc.
end_indexCond.integerIndex trong matrix cho end.
capacityNointeger[]Tải trọng đa chiều.
costsNocostChi phí vận hành xe.
skillsNointeger[]Tập kỹ năng của xe.
typeNostringLoại xe.
time_windowNotime_windowGiờ làm việc hợp lệ.
breaksNobreak[]Danh sách điểm nghỉ.
speed_factorNonumberHệ số nhân cho travel time, (0, 5].
max_tasksNointegerSố task tối đa.
max_travel_timeNointegerTravel time tối đa.
max_distanceNointegerQuãng đường tối đa.
stepsNovehicle_step[]Route custom cho plan mode hoặc starting solution.

4.1 Cost Object

FieldRequiredTypeDefaultMô tả
fixedNointeger0Chi phí cố định nếu xe được dùng.
per_hourNointeger3600Chi phí cho 1 giờ di chuyển.
per_task_hourNointeger0Chi phí cho 1 giờ task time (setup + service).
per_kmNointeger0Chi phí cho 1 km di chuyển.

Nếu dùng per_hour khác mặc định, không nên đồng thời dùng custom cost matrix cho cùng vehicle vì contract gốc xem đó là không nhất quán.

4.2 Break Object

FieldRequiredTypeMô tả
idYesintegerID break trong xe.
time_windowsNotime_window[]Slot hợp lệ để bắt đầu nghỉ.
serviceNointegerThời gian nghỉ.
descriptionNostringMô tả break.
max_loadNointeger[]Load tối đa cho phép khi break xảy ra.

4.3 Vehicle Step

FieldRequiredTypeMô tả
typeYesstringstart, job, pickup, delivery, break, end.
idCond.integerID task/break nếu type không phải start hoặc end.
service_atNointegerHard constraint cho thời điểm service.
service_afterNointegerLower bound cho service time.
service_beforeNointegerUpper bound cho service time.

Ví dụ vehicle

{
  "id": 1,
  "profile": "car",
  "description": "Xe tải 1.5 tấn",
  "start": [106.66017, 10.76262],
  "end": [106.66017, 10.76262],
  "capacity": [20],
  "skills": [2, 3, 7],
  "time_window": [1713398400, 1713430800],
  "costs": {
    "fixed": 100000,
    "per_hour": 3600,
    "per_km": 1500
  },
  "breaks": [
    {
      "id": 1,
      "time_windows": [[1713412800, 1713416400]],
      "service": 1800,
      "description": "Nghỉ trưa"
    }
  ]
}

Ghi chú

  • startend là optional miễn là có ít nhất một trong hai
  • nếu bỏ end, route kết thúc ở task cuối cùng được phục vụ
  • nếu bỏ start, route bắt đầu ở task đầu tiên được gán
  • nếu startend giống nhau, đó là round trip

5. Matrices

matrices cho phép truyền custom matrices theo từng profile của xe.

KeyTypeMô tả
durationsnumber[][]Travel-time matrix dùng cho timing constraints.
distancesnumber[][]Distance matrix. Muốn dùng field này phải có durations.
costsnumber[][]Cost matrix cho objective evaluation.

Ví dụ

{
  "matrices": {
    "car": {
      "durations": [
        [0, 14],
        [21, 0]
      ]
    },
    "bike": {
      "durations": [
        [0, 57],
        [43, 0]
      ]
    }
  }
}

Ghi chú

  • nếu có đủ custom matrices cho mọi profile liên quan thì location, start, end có thể bỏ qua
  • khi đó cần dùng location_index, start_index, end_index
  • nếu có durations nhưng không có distances, backend vẫn có thể cần truy xuất distance riêng nếu bài toán yêu cầu

6. Response Overview

Response trả về JSON object mô tả kết quả tối ưu.

KeyTypeMô tả
codeintegerTrạng thái xử lý. 0 là thành công.
errorstringThông báo lỗi nếu code != 0.
summaryobjectTổng hợp chỉ số toàn cục của solution.
unassignedobject[]Danh sách task không được gán route, kèm reason.
routesroute[]Danh sách route tối ưu.

6.1 Status Code

CodeÝ nghĩa
0Thành công, không có lỗi.
1Internal error.
2Input error.
3Routing error.

7. Summary

summary là phần tổng hợp của toàn bộ nghiệm.

FieldTypeMô tả
costintegerTổng cost của tất cả routes.
routesintegerSố route được tạo.
unassignedintegerSố task không được phục vụ.
setupintegerTổng setup time.
serviceintegerTổng service time.
durationintegerTổng travel time.
waiting_timeintegerTổng waiting time.
priorityintegerTổng priority của task đã được gán.
violationsviolation[]Vi phạm ở cấp solution/route.
deliveryinteger[]Tổng delivery.
pickupinteger[]Tổng pickup.
distanceintegerTổng khoảng cách, nếu backend có trả distance.
computing_timesobjectThước đo thời gian xử lý nội bộ của engine.

computing_times

FieldTypeMô tả
loadingintegerThời gian load dữ liệu (ms).
solvingintegerThời gian giải bài toán (ms).
routingintegerThời gian gọi routing engine (ms).

8. Routes và Steps

8.1 Route Object

FieldTypeMô tả
vehicleintegerID xe được gán route.
stepsstep[]Các bước trong route.
costintegerCost của route.
setupintegerTổng setup time của route.
serviceintegerTổng service time của route.
durationintegerTổng travel time của route.
waiting_timeintegerTổng waiting time của route.
priorityintegerTổng priority của task trong route.
violationsviolation[]Vi phạm của route.
deliveryinteger[]Delivery load của route.
pickupinteger[]Pickup load của route.
descriptionstringVehicle description nếu có trong input.
geometrystringPolyline encoded, nếu backend bật geometry.
distanceintegerTổng quãng đường route.

8.2 Step Object

FieldTypeMô tả
typestringstart, job, pickup, delivery, break, end.
arrivalintegerETA tại step.
durationintegerTravel time tích lũy đến step này.
setupintegerSetup time tại step.
serviceintegerService time tại step.
waiting_timeintegerWaiting time trước khi bắt đầu service.
violationsviolation[]Vi phạm phát sinh tại step.
descriptionstringMô tả step, nếu có từ input.
location[lon, lat]Tọa độ step, nếu input có cung cấp.
location_indexintegerIndex matrix, nếu có.
idintegerID task/break tương ứng.
loadinteger[]Tải trọng xe sau khi hoàn tất step.
distanceintegerQuãng đường tích lũy đến step.

Ghi chú về steps

  • trong solving mode, route sẽ được backend tối ưu tự động
  • trong plan mode, vehicle.steps mô tả route dự kiến và backend chủ yếu tính ETA/violations
  • trong solving mode, nếu truyền vehicle.steps, đó được xem như starting solution và phải hợp lệ với mọi constraint

9. Violations

violation mô tả một ràng buộc bị vi phạm.

FieldTypeMô tả
causestringNguyên nhân vi phạm.
durationintegerMức lệch thời gian nếu là lead_time hoặc delay.

9.1 Các giá trị cause

CauseÝ nghĩa
delayService bắt đầu muộn hơn time window cho phép.
lead_timeService bắt đầu sớm hơn time window cho phép.
loadTải trọng vượt capacity.
max_tasksSố task vượt max_tasks.
skillsXe không có đủ skills.
precedenceDelivery xảy ra trước pickup hoặc thiếu cặp tương ứng.
missing_breakBỏ qua break bắt buộc trong custom route.
max_travel_timeVượt travel time tối đa.
max_distanceVượt distance tối đa.
max_loadLoad tại thời điểm break vượt max_load.

Trong regular optimization, violations thường rỗng. Chúng có ý nghĩa rõ nhất khi backend chạy theo logic plan mode để kiểm tra route có sẵn.


10. Error Responses

HTTP 400 — Input lỗi (OptimizeApi validation)

{
  "error": "INPUT_ERROR",
  "message": "Request body is empty",
  "code": 2
}
{
  "error": "INPUT_ERROR",
  "message": "Request body is not valid JSON",
  "code": 2
}

HTTP 401 — Unauthorized

Thiếu hoặc sai X-API-Key.

// (no body — ASP.NET default 401)

HTTP 400/500 — Engine error (forwarded)

Khi engine trả lỗi, OptimizeApi forward nguyên:

{
  "code": 2,
  "error": "Invalid jobs: location missing for job 3."
}
codeÝ nghĩa
0OK
1Internal error
2Input validation error

Unassigned jobs

Khi có job không giao được, response sẽ chứa mảng unassigned kèm lý do:

{
  "unassigned": [
    {
      "id": 5,
      "type": "job",
      "location": [106.72, 10.75],
      "reason": "No vehicle with matching skills"
    }
  ]
}

11. Ví dụ Request/Response

11.1 Ví dụ Request

Bài toán 1 xe, 3 điểm giao

curl -X POST https://live.fleetwork.vn/api/v1/optimize \
  -H "X-API-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "vehicles": [
      {
        "id": 1,
        "profile": "car",
        "start": [106.6297, 10.8231],
        "end": [106.6297, 10.8231]
      }
    ],
    "jobs": [
      { "id": 1, "location": [106.6602, 10.7626], "service": 300 },
      { "id": 2, "location": [106.7010, 10.7769], "service": 300 },
      { "id": 3, "location": [106.6893, 10.8018], "service": 180 }
    ]
  }'

Ví dụ loại service (theo thời gian phục vụ)

Quy ước ví dụ:

  • service: 120 -> giao nhanh (2 phút)
  • service: 300 -> giao tiêu chuẩn (5 phút)
  • service: 900 -> giao cồng kềnh (15 phút)
curl -X POST https://live.fleetwork.vn/api/v1/optimize \
  -H "X-API-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "vehicles": [
      {
        "id": 1,
        "profile": "car",
        "start": [106.6297, 10.8231],
        "end": [106.6297, 10.8231]
      }
    ],
    "jobs": [
      { "id": 101, "location": [106.6602, 10.7626], "service": 120 },
      { "id": 102, "location": [106.7010, 10.7769], "service": 300 },
      { "id": 103, "location": [106.6893, 10.8018], "service": 900 }
    ]
  }'

11.2 Ví dụ Response 200 OK

{
  "code": 0,
  "summary": {
    "cost": 3600,
    "unassigned": 0,
    "delivery": [0],
    "pickup": [0],
    "service": 300,
    "duration": 3300,
    "waiting_time": 0,
    "distance": 12500,
    "priority": 0,
    "violations": [],
    "computing_times": {
      "loading": 2,
      "solving": 45,
      "routing": 10
    }
  },
  "unassigned": [],
  "routes": [
    {
      "vehicle": 1,
      "cost": 3600,
      "service": 300,
      "duration": 3300,
      "waiting_time": 0,
      "distance": 12500,
      "priority": 0,
      "violations": [],
      "delivery": [0],
      "pickup": [0],
      "steps": [
        {
          "type": "start",
          "location": [106.6297, 10.8231],
          "arrival": 0,
          "duration": 0,
          "distance": 0
        },
        {
          "type": "job",
          "id": 1,
          "location": [106.701, 10.7769],
          "arrival": 2800,
          "duration": 3300,
          "distance": 12500,
          "load": [0]
        },
        {
          "type": "end",
          "location": [106.6297, 10.8231],
          "arrival": 3600,
          "duration": 3600,
          "distance": 15200
        }
      ]
    }
  ]
}

Lưu ý triển khai

  • nếu bài toán có ràng buộc tải trọng, hãy khai báo đồng nhất giữa vehicle.capacity, job.delivery / job.pickup, hoặc shipment.amount
  • nếu backend trả về distance hoặc geometry, cần có cấu hình tương ứng ở lớp routing engine
  • nếu dùng timestamp tuyệt đối trong time_window, các giá trị arrival trong output cũng được hiểu là timestamp tuyệt đối
  • nếu dùng giá trị tương đối, toàn bộ arrival sẽ là thời gian tương đối theo planning horizon
  • engine forward nguyên response — không bọc thêm wrapper
  • timeout khuyến nghị cho bài toán lớn là 5 phút

On this page