Bỏ qua, tới nội dung chính
Fleetwork
Fleetwork

Liên hệ

Chúng tôi rất mong nhận được liên hệ từ bạn. Vui lòng điền vào biểu mẫu bên dưới.

SDKOptimize

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

HTTP
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

JSON
{
  "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.id và delivery.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.

  • idintegerYes
    ID duy nhất của job.
  • descriptionstringNo
    Mô tả job.
  • location[lon, lat]Cond.
    Tọa độ job. Bắt buộc nếu không dùng custom matrix.
  • location_indexintegerCond.
    Index dòng/cột trong custom matrices. Bắt buộc nếu dùng matrix.
  • setupintegerNo
    Thời gian setup, mặc định 0.
  • serviceintegerNo
    Thời gian phục vụ, mặc định 0.
  • setup_per_typeobjectNo
    Map theo vehicle.type để override setup.
  • service_per_typeobjectNo
    Map theo vehicle.type để override service.
  • deliveryinteger[]No
    Nhu cầu delivery đa chiều.
  • pickupinteger[]No
    Nhu cầu pickup đa chiều.
  • skillsinteger[]No
    Tập kỹ năng bắt buộc.
  • priorityintegerNo
    Mức ưu tiên từ 0 đến 100, mặc định 0.
  • time_windowstime_window[]No
    Các khoảng thời gian hợp lệ để bắt đầu service.

Ví dụ job

JSON
{
  "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.

  • pickupshipment_stepYes
    Điểm lấy hàng.
  • deliveryshipment_stepYes
    Điểm giao hàng.
  • amountinteger[]No
    Tải trọng đa chiều của shipment.
  • skillsinteger[]No
    Kỹ năng bắt buộc.
  • priorityintegerNo
    Mức ưu tiên 0..100.

3.1 Shipment Step

  • idintegerYes
    ID của step.
  • descriptionstringNo
    Mô tả step.
  • location[lon, lat]Cond.
    Tọa độ step.
  • location_indexintegerCond.
    Chỉ số matrix tương ứng.
  • setupintegerNo
    Setup duration, mặc định 0.
  • serviceintegerNo
    Service duration, mặc định 0.
  • setup_per_typeobjectNo
    Override setup theo loại xe.
  • service_per_typeobjectNo
    Override service theo loại xe.
  • time_windowstime_window[]No
    Các slot thời gian hợp lệ.

Ví dụ shipment

JSON
{
  "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.

  • idintegerYes
    ID xe.
  • profilestringNo
    Routing profile: car | truck | motorcycle, mặc định car.
  • descriptionstringNo
    Mô tả xe.
  • start[lon, lat]Cond.
    Điểm xuất phát.
  • start_indexintegerCond.
    Index trong matrix cho start.
  • end[lon, lat]Cond.
    Điểm kết thúc.
  • end_indexintegerCond.
    Index trong matrix cho end.
  • capacityinteger[]No
    Tải trọng đa chiều.
  • costscostNo
    Chi phí vận hành xe.
  • skillsinteger[]No
    Tập kỹ năng của xe.
  • typestringNo
    Loại xe.
  • time_windowtime_windowNo
    Giờ làm việc hợp lệ.
  • breaksbreak[]No
    Danh sách điểm nghỉ.
  • speed_factornumberNo
    Hệ số nhân cho travel time, (0, 5].
  • max_tasksintegerNo
    Số task tối đa.
  • max_travel_timeintegerNo
    Travel time tối đa.
  • max_distanceintegerNo
    Quãng đường tối đa.
  • stepsvehicle_step[]No
    Route custom cho plan mode hoặc starting solution.

4.1 Cost Object

  • fixedintegerNo
    Chi phí cố định nếu xe được dùng.
  • per_hourintegerNo
    Chi phí cho 1 giờ di chuyển.
  • per_task_hourintegerNo
    Chi phí cho 1 giờ task time (setup + service).
  • per_kmintegerNo
    Chi 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

  • idintegerYes
    ID break trong xe.
  • time_windowstime_window[]No
    Slot hợp lệ để bắt đầu nghỉ.
  • serviceintegerNo
    Thời gian nghỉ.
  • descriptionstringNo
    Mô tả break.
  • max_loadinteger[]No
    Load tối đa cho phép khi break xảy ra.

4.3 Vehicle Step

  • typestringYes
    start, job, pickup, delivery, break, end.
  • idintegerCond.
    ID task/break nếu type không phải start hoặc end.
  • service_atintegerNo
    Hard constraint cho thời điểm service.
  • service_afterintegerNo
    Lower bound cho service time.
  • service_beforeintegerNo
    Upper bound cho service time.

Ví dụ vehicle

JSON
{
  "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ú

  • start và end 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 start và end 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ụ

JSON
{
  "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.

  • costinteger
    Tổng cost của tất cả routes.
  • routesinteger
    Số route được tạo.
  • unassignedinteger
    Số task không được phục vụ.
  • setupinteger
    Tổng setup time.
  • serviceinteger
    Tổng service time.
  • durationinteger
    Tổng travel time.
  • waiting_timeinteger
    Tổng waiting time.
  • priorityinteger
    Tổng priority của task đã được gán.
  • violationsviolation[]
    Vi phạm ở cấp solution/route.
  • deliveryinteger[]
    Tổng delivery.
  • pickupinteger[]
    Tổng pickup.
  • distanceinteger
    Tổng khoảng cách, nếu backend có trả distance.
  • computing_timesobject
    Thước đo thời gian xử lý nội bộ của engine.

computing_times

  • loadinginteger
    Thời gian load dữ liệu (ms).
  • solvinginteger
    Thời gian giải bài toán (ms).
  • routinginteger
    Thời gian gọi routing engine (ms).

8. Routes và Steps

8.1 Route Object

  • vehicleinteger
    ID xe được gán route.
  • stepsstep[]
    Các bước trong route.
  • costinteger
    Cost của route.
  • setupinteger
    Tổng setup time của route.
  • serviceinteger
    Tổng service time của route.
  • durationinteger
    Tổng travel time của route.
  • waiting_timeinteger
    Tổng waiting time của route.
  • priorityinteger
    Tổ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.
  • descriptionstring
    Vehicle description nếu có trong input.
  • geometrystring
    Polyline encoded, nếu backend bật geometry.
  • distanceinteger
    Tổng quãng đường route.

8.2 Step Object

  • typestring
    start, job, pickup, delivery, break, end.
  • arrivalinteger
    ETA tại step.
  • durationinteger
    Travel time tích lũy đến step này.
  • setupinteger
    Setup time tại step.
  • serviceinteger
    Service time tại step.
  • waiting_timeinteger
    Waiting time trước khi bắt đầu service.
  • violationsviolation[]
    Vi phạm phát sinh tại step.
  • descriptionstring
    Mô tả step, nếu có từ input.
  • location[lon, lat]
    Tọa độ step, nếu input có cung cấp.
  • location_indexinteger
    Index matrix, nếu có.
  • idinteger
    ID task/break tương ứng.
  • loadinteger[]
    Tải trọng xe sau khi hoàn tất step.
  • distanceinteger
    Quã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.

  • causestring
    Nguyên nhân vi phạm.
  • durationinteger
    Mứ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)

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

HTTP 401 — Unauthorized

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

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

HTTP 400/500 — Engine error (forwarded)

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

JSON
{
  "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:

JSON
{
  "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

Shell
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)
Shell
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

JSON
{
  "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