# VRP API — Vietmap API Playground

> Phân bổ nhiều điểm giao cho đội xe, tôn trọng tải trọng và khung giờ.

- Trang tương tác: https://tools.vietmap.vn/playground/vrp
- Endpoint: `POST /api/vrp?api-version=1.1` trên `https://maps.vietmap.vn`
- Tài liệu chính thức: https://maps.vietmap.vn/docs/map-api/vrp/
- API key: mọi request cần tham số `apikey`. Code mẫu dùng `YOUR_API_KEY` làm chỗ giữ key — khi tích hợp, đọc key từ biến môi trường (ví dụ `VIETMAP_API_KEY`). Lấy key tại https://maps.vietmap.vn/console-v2/consumers
- Mã lỗi: `401` sai API key · `403` key bị giới hạn domain/IP · `423` API chưa bật cho consumer của key, hoặc hết credit (phản hồi có "exceeded credit") · `429` vượt giới hạn tần suất.

## Code mẫu

### cURL

```bash
curl -X POST 'https://maps.vietmap.vn/api/vrp?api-version=1.1&apikey=YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "jobs": [
    {
      "id": 1,
      "location": [
        106.70592,
        10.79628
      ],
      "service": 600,
      "description": "Cửa hàng Bình Thạnh",
      "delivery": [
        3
      ],
      "time_windows": [
        [
          28800,
          39600
        ]
      ]
    },
    {
      "id": 2,
      "location": [
        106.7066,
        10.80189
      ],
      "service": 900,
      "description": "Siêu thị mini Điện Biên Phủ",
      "delivery": [
        4
      ]
    },
    {
      "id": 3,
      "location": [
        106.68982,
        10.80159
      ],
      "service": 600,
      "description": "Quán ăn Phú Nhuận",
      "delivery": [
        2
      ],
      "time_windows": [
        [
          32400,
          43200
        ]
      ]
    },
    {
      "id": 4,
      "location": [
        106.695,
        10.785
      ],
      "service": 300,
      "description": "Nhà khách Quận 3",
      "delivery": [
        1
      ]
    },
    {
      "id": 5,
      "location": [
        106.712,
        10.7905
      ],
      "service": 600,
      "description": "Kho lẻ Thủ Đức",
      "delivery": [
        3
      ],
      "time_windows": [
        [
          46800,
          57600
        ]
      ]
    },
    {
      "id": 6,
      "location": [
        106.6835,
        10.7925
      ],
      "service": 300,
      "description": "Tiệm tạp hoá Gò Vấp",
      "delivery": [
        2
      ]
    },
    {
      "id": 7,
      "location": [
        106.6961,
        10.7826
      ],
      "service": 600,
      "description": "Nhà hàng Nguyễn Đình Chiểu",
      "delivery": [
        2
      ],
      "time_windows": [
        [
          50400,
          61200
        ]
      ]
    },
    {
      "id": 8,
      "location": [
        106.7047,
        10.7877
      ],
      "service": 300,
      "description": "Chung cư Bình Thạnh",
      "delivery": [
        1
      ]
    }
  ],
  "vehicles": [
    {
      "id": 1,
      "description": "Xe tải nhỏ 1",
      "profile": "car",
      "start": [
        106.7,
        10.79
      ],
      "end": [
        106.7,
        10.79
      ],
      "capacity": [
        12
      ]
    },
    {
      "id": 2,
      "description": "Xe tải nhỏ 2",
      "profile": "car",
      "start": [
        106.7,
        10.79
      ],
      "end": [
        106.7,
        10.79
      ],
      "capacity": [
        12
      ]
    },
    {
      "id": 3,
      "description": "Xe giao hàng nhỏ",
      "profile": "car",
      "start": [
        106.7,
        10.79
      ],
      "end": [
        106.7,
        10.79
      ],
      "capacity": [
        4
      ]
    }
  ]
}'
```

### JavaScript

```javascript
// Khi đưa vào sản phẩm, đọc key từ biến môi trường thay vì ghi cứng.
const API_KEY = "YOUR_API_KEY";

const params = new URLSearchParams([
  ["api-version", "1.1"],
  ["apikey", API_KEY],
]);

const body = {
  "jobs": [
    {
      "id": 1,
      "location": [
        106.70592,
        10.79628
      ],
      "service": 600,
      "description": "Cửa hàng Bình Thạnh",
      "delivery": [
        3
      ],
      "time_windows": [
        [
          28800,
          39600
        ]
      ]
    },
    {
      "id": 2,
      "location": [
        106.7066,
        10.80189
      ],
      "service": 900,
      "description": "Siêu thị mini Điện Biên Phủ",
      "delivery": [
        4
      ]
    },
    {
      "id": 3,
      "location": [
        106.68982,
        10.80159
      ],
      "service": 600,
      "description": "Quán ăn Phú Nhuận",
      "delivery": [
        2
      ],
      "time_windows": [
        [
          32400,
          43200
        ]
      ]
    },
    {
      "id": 4,
      "location": [
        106.695,
        10.785
      ],
      "service": 300,
      "description": "Nhà khách Quận 3",
      "delivery": [
        1
      ]
    },
    {
      "id": 5,
      "location": [
        106.712,
        10.7905
      ],
      "service": 600,
      "description": "Kho lẻ Thủ Đức",
      "delivery": [
        3
      ],
      "time_windows": [
        [
          46800,
          57600
        ]
      ]
    },
    {
      "id": 6,
      "location": [
        106.6835,
        10.7925
      ],
      "service": 300,
      "description": "Tiệm tạp hoá Gò Vấp",
      "delivery": [
        2
      ]
    },
    {
      "id": 7,
      "location": [
        106.6961,
        10.7826
      ],
      "service": 600,
      "description": "Nhà hàng Nguyễn Đình Chiểu",
      "delivery": [
        2
      ],
      "time_windows": [
        [
          50400,
          61200
        ]
      ]
    },
    {
      "id": 8,
      "location": [
        106.7047,
        10.7877
      ],
      "service": 300,
      "description": "Chung cư Bình Thạnh",
      "delivery": [
        1
      ]
    }
  ],
  "vehicles": [
    {
      "id": 1,
      "description": "Xe tải nhỏ 1",
      "profile": "car",
      "start": [
        106.7,
        10.79
      ],
      "end": [
        106.7,
        10.79
      ],
      "capacity": [
        12
      ]
    },
    {
      "id": 2,
      "description": "Xe tải nhỏ 2",
      "profile": "car",
      "start": [
        106.7,
        10.79
      ],
      "end": [
        106.7,
        10.79
      ],
      "capacity": [
        12
      ]
    },
    {
      "id": 3,
      "description": "Xe giao hàng nhỏ",
      "profile": "car",
      "start": [
        106.7,
        10.79
      ],
      "end": [
        106.7,
        10.79
      ],
      "capacity": [
        4
      ]
    }
  ]
};

const response = await fetch(`https://maps.vietmap.vn/api/vrp?${params}`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify(body),
});
if (!response.ok) {
  throw new Error(`Vietmap ${response.status}: ${await response.text()}`);
}
const data = await response.json();
console.log(data);
```

### Python

```python
import requests

# Khi đưa vào sản phẩm, đọc key từ biến môi trường thay vì ghi cứng.
API_KEY = "YOUR_API_KEY"

params = [
    ("api-version", "1.1"),
    ("apikey", API_KEY),
]

body = {
    "jobs": [
        {
            "id": 1,
            "location": [
                106.70592,
                10.79628,
            ],
            "service": 600,
            "description": "Cửa hàng Bình Thạnh",
            "delivery": [
                3,
            ],
            "time_windows": [
                [
                    28800,
                    39600,
                ],
            ],
        },
        {
            "id": 2,
            "location": [
                106.7066,
                10.80189,
            ],
            "service": 900,
            "description": "Siêu thị mini Điện Biên Phủ",
            "delivery": [
                4,
            ],
        },
        {
            "id": 3,
            "location": [
                106.68982,
                10.80159,
            ],
            "service": 600,
            "description": "Quán ăn Phú Nhuận",
            "delivery": [
                2,
            ],
            "time_windows": [
                [
                    32400,
                    43200,
                ],
            ],
        },
        {
            "id": 4,
            "location": [
                106.695,
                10.785,
            ],
            "service": 300,
            "description": "Nhà khách Quận 3",
            "delivery": [
                1,
            ],
        },
        {
            "id": 5,
            "location": [
                106.712,
                10.7905,
            ],
            "service": 600,
            "description": "Kho lẻ Thủ Đức",
            "delivery": [
                3,
            ],
            "time_windows": [
                [
                    46800,
                    57600,
                ],
            ],
        },
        {
            "id": 6,
            "location": [
                106.6835,
                10.7925,
            ],
            "service": 300,
            "description": "Tiệm tạp hoá Gò Vấp",
            "delivery": [
                2,
            ],
        },
        {
            "id": 7,
            "location": [
                106.6961,
                10.7826,
            ],
            "service": 600,
            "description": "Nhà hàng Nguyễn Đình Chiểu",
            "delivery": [
                2,
            ],
            "time_windows": [
                [
                    50400,
                    61200,
                ],
            ],
        },
        {
            "id": 8,
            "location": [
                106.7047,
                10.7877,
            ],
            "service": 300,
            "description": "Chung cư Bình Thạnh",
            "delivery": [
                1,
            ],
        },
    ],
    "vehicles": [
        {
            "id": 1,
            "description": "Xe tải nhỏ 1",
            "profile": "car",
            "start": [
                106.7,
                10.79,
            ],
            "end": [
                106.7,
                10.79,
            ],
            "capacity": [
                12,
            ],
        },
        {
            "id": 2,
            "description": "Xe tải nhỏ 2",
            "profile": "car",
            "start": [
                106.7,
                10.79,
            ],
            "end": [
                106.7,
                10.79,
            ],
            "capacity": [
                12,
            ],
        },
        {
            "id": 3,
            "description": "Xe giao hàng nhỏ",
            "profile": "car",
            "start": [
                106.7,
                10.79,
            ],
            "end": [
                106.7,
                10.79,
            ],
            "capacity": [
                4,
            ],
        },
    ],
}

response = requests.post("https://maps.vietmap.vn/api/vrp", params=params, json=body, timeout=60)
response.raise_for_status()
print(response.json())
```

## AI prompt

Prompt soạn sẵn để giao cho trợ lý lập trình (ChatGPT, Claude, Copilot…) viết code tích hợp API này:

````text
Tôi cần tích hợp VRP API (api-version 1.1) của Vietmap vào ứng dụng của mình.

Tài liệu chính thức: https://maps.vietmap.vn/docs/map-api/vrp/

Đây là một request mẫu đã chạy được trên Vietmap API Playground:

POST https://maps.vietmap.vn/api/vrp?api-version=1.1&apikey=YOUR_API_KEY

Body (JSON):
```json
{
  "jobs": [
    {
      "id": 1,
      "location": [
        106.70592,
        10.79628
      ],
      "service": 600,
      "description": "Cửa hàng Bình Thạnh",
      "delivery": [
        3
      ],
      "time_windows": [
        [
          28800,
          39600
        ]
      ]
    },
    {
      "id": 2,
      "location": [
        106.7066,
        10.80189
      ],
      "service": 900,
      "description": "Siêu thị mini Điện Biên Phủ",
      "delivery": [
        4
      ]
    },
    {
      "id": 3,
      "location": [
        106.68982,
        10.80159
      ],
      "service": 600,
      "description": "Quán ăn Phú Nhuận",
      "delivery": [
        2
      ],
      "time_windows": [
        [
          32400,
          43200
        ]
      ]
    },
    {
      "id": 4,
      "location": [
        106.695,
        10.785
      ],
      "service": 300,
      "description": "Nhà khách Quận 3",
      "delivery": [
        1
      ]
    },
    {
      "id": 5,
      "location": [
        106.712,
        10.7905
      ],
      "service": 600,
      "description": "Kho lẻ Thủ Đức",
      "delivery": [
        3
      ],
      "time_windows": [
        [
          46800,
          57600
        ]
      ]
    },
    {
      "id": 6,
      "location": [
        106.6835,
        10.7925
      ],
      "service": 300,
      "description": "Tiệm tạp hoá Gò Vấp",
      "delivery": [
        2
      ]
    },
    {
      "id": 7,
      "location": [
        106.6961,
        10.7826
      ],
      "service": 600,
      "description": "Nhà hàng Nguyễn Đình Chiểu",
      "delivery": [
        2
      ],
      "time_windows": [
        [
          50400,
          61200
        ]
      ]
    },
    {
      "id": 8,
      "location": [
        106.7047,
        10.7877
      ],
      "service": 300,
      "description": "Chung cư Bình Thạnh",
      "delivery": [
        1
      ]
    }
  ],
  "vehicles": [
    {
      "id": 1,
      "description": "Xe tải nhỏ 1",
      "profile": "car",
      "start": [
        106.7,
        10.79
      ],
      "end": [
        106.7,
        10.79
      ],
      "capacity": [
        12
      ]
    },
    {
      "id": 2,
      "description": "Xe tải nhỏ 2",
      "profile": "car",
      "start": [
        106.7,
        10.79
      ],
      "end": [
        106.7,
        10.79
      ],
      "capacity": [
        12
      ]
    },
    {
      "id": 3,
      "description": "Xe giao hàng nhỏ",
      "profile": "car",
      "start": [
        106.7,
        10.79
      ],
      "end": [
        106.7,
        10.79
      ],
      "capacity": [
        4
      ]
    }
  ]
}
```

Tham số đang dùng:
- api-version = 1.1

Hãy viết code bằng [ngôn ngữ / framework của tôi] để gọi API này, với các yêu cầu:
1. Đọc API key từ biến môi trường VIETMAP_API_KEY, không ghi cứng trong code.
2. Truyền tham số qua query string đúng như request mẫu; tham số lặp lại (như `point`) phải giữ nguyên thứ tự.
3. Xử lý lỗi theo mã HTTP của Vietmap:
   - 401: API key sai hoặc đã bị thu hồi.
   - 403: key bị giới hạn theo domain / IP không khớp.
   - 423: API chưa được bật cho consumer của key, HOẶC tài khoản hết credit — phân biệt bằng nội dung phản hồi (có cụm "exceeded credit" là hết credit).
   - 429: vượt giới hạn tần suất — thử lại với backoff tăng dần.
4. Đặt timeout cho request, và định nghĩa kiểu dữ liệu (type / interface / dataclass) cho phản hồi.

Nếu không chắc tên một trường, tra trong tài liệu ở link trên thay vì đoán.
````

## Mở lại đúng request này trong Playground

https://tools.vietmap.vn/playground/vrp?sample=last-mile
