Xây dựng trên API MG Ship
Đưa dữ liệu theo dõi lô hàng theo thời gian thực vào hệ thống của bạn thông qua một REST API đơn giản, có phiên bản.
Tổng quan
API của MG Ship là một REST API trả về JSON qua HTTPS. Nó cung cấp cho hệ thống của bạn quyền truy cập lập trình vào dữ liệu theo dõi lô hàng — danh sách lô hàng, bản ghi lô hàng đầy đủ và dòng thời gian theo dõi — để bạn có thể đưa các mốc hành trình vào TMS, ERP hoặc cổng thông tin khách hàng của riêng mình.
Mọi điểm cuối đều nằm dưới đường dẫn gốc có phiên bản bên dưới. API được phân phiên bản trong đường dẫn URL (v1). Các thay đổi gây phá vỡ tương thích sẽ được phát hành dưới một đường dẫn mới (v2) kèm theo khoảng thời gian ngừng hỗ trợ 12 tháng cho phiên bản trước, nhờ vậy một tích hợp xây dựng trên v1 vẫn tiếp tục hoạt động.
URL cơ sở
Chọn URL cơ sở cho môi trường mà bạn đang tích hợp. Mọi đường dẫn endpoint bên dưới đều là tương đối so với URL này. Staging và Test (VPS) dùng cho phát triển và kiểm thử; chỉ sử dụng Production với khóa thật.
| Môi trường | URL cơ sở |
|---|---|
| Production | https://api.mglobalship.com/api/v1/external |
| Staging | https://api.staging.mglobalship.com/api/v1/external |
| Test (VPS) | https://mgs.aipipis.com/api/v1/external |
Xác thực
Hãy xác thực mọi yêu cầu bằng một khóa API được gửi dưới dạng token Bearer trong header Authorization. Khóa được cấp theo từng tenant từ API Portal, chỉ hiển thị một lần duy nhất khi tạo, mang theo các phạm vi rõ ràng (ví dụ shipments.read), và có thể được xoay vòng hoặc thu hồi bất cứ lúc nào.
Hãy giữ khóa ở phía máy chủ — đừng bao giờ đưa chúng vào mã chạy trên trình duyệt hoặc thiết bị di động. Nếu một khóa bị lộ, hãy xoay vòng nó từ API Portal và khóa cũ sẽ ngừng hoạt động ngay lập tức.
curl https://api.staging.mglobalship.com/api/v1/external/health \
-H "Authorization: Bearer mgs_live_xxxxxxxxxxxxxxxxxxxxxxxx"Quy ước
Phân trang
Các điểm cuối dạng danh sách được phân trang theo con trỏ. Truyền limit (1–100, mặc định 20) để xác định kích thước trang. Khi còn nhiều kết quả hơn, phản hồi sẽ đặt has_more thành true và trả về next_cursor; hãy truyền giá trị này trở lại dưới dạng tham số truy vấn cursor để lấy trang tiếp theo. Con trỏ là mờ — hãy xem chúng như một token, đừng tự dựng chúng.
Giới hạn tốc độ
Yêu cầu bị giới hạn tốc độ theo từng phút dựa trên bậc tài khoản của bạn. Mọi phản hồi đều bao gồm các header X-RateLimit-Limit, X-RateLimit-Remaining và X-RateLimit-Reset (số giây cho đến khi cửa sổ giới hạn được đặt lại). Vượt quá giới hạn sẽ trả về 429 cùng với giá trị retry_after_seconds trong nội dung phản hồi. Các khóa riêng lẻ có thể được cấp ngưỡng cao hơn theo yêu cầu.
| Bậc | Yêu cầu / phút |
|---|---|
| Bronze | 60 |
| Silver | 300 |
| Gold | 1.000 |
| Platinum | 5.000 |
| Enterprise | Không giới hạn |
Tính bất biến (Idempotency)
Các điểm cuối ghi (chẳng hạn POST /shipments) yêu cầu một header Idempotency-Key. Thử lại một yêu cầu với cùng một khóa sẽ trả về kết quả ban đầu thay vì tạo bản trùng lặp, nên việc thử lại qua mạng luôn an toàn. Các điểm cuối chỉ đọc (GET) không cần đến nó.
Điểm cuối
/healthKiểm tra xem khóa của bạn có hoạt động không và xem bậc hiện tại cùng trạng thái giới hạn tốc độ. Một lệnh gọi nhẹ để xác minh khả năng kết nối.
curl https://api.staging.mglobalship.com/api/v1/external/health \
-H "Authorization: Bearer mgs_live_..."{
"status": "ok",
"tenant_id": 123,
"tier": "silver",
"rate_limit": {
"limit": 300,
"remaining": 299,
"reset_seconds": 59
}
}/shipmentsĐăng ký một lô hàng để nền tảng bắt đầu theo dõi nó. Yêu cầu phạm vi shipments.write và một header Idempotency-Key duy nhất. Lô hàng này được tính vào hạn mức hằng tháng của gói cước của bạn.
| Tham số | Kiểu | Mô tả |
|---|---|---|
Idempotency-Key* | string (header) | Duy nhất cho mỗi yêu cầu; thử lại với cùng một giá trị sẽ trả về lô hàng ban đầu thay vì tạo bản trùng lặp. |
tracking_number* | string | Số AWB / B-L / số theo dõi. |
carrier_code* | string | Mã hãng vận chuyển hoặc hãng hàng không (mã PCS, mã hãng hàng không IATA, hoặc courier slug của AfterShip). |
mode* | string | Phương thức vận chuyển: sea, air hoặc courier. |
curl -X POST https://api.staging.mglobalship.com/api/v1/external/shipments \
-H "Authorization: Bearer mgs_live_..." \
-H "Idempotency-Key: a1b2c3d4-e5f6-7890" \
-H "Content-Type: application/json" \
-d '{
"tracking_number": "160-12345675",
"carrier_code": "pcs",
"mode": "air"
}'{
"object": "shipment",
"id": 12346,
"tracking_number": "160-12345675",
"carrier_code": "pcs",
"mode": "air",
"status": "pending",
"awb_number": "160-12345675",
"_links": {
"self": "/api/v1/external/shipments/12346",
"tracking": "/api/v1/external/shipments/12346/tracking"
}
}/shipmentsLiệt kê các lô hàng của bạn, mới nhất trước, với phân trang theo con trỏ và các bộ lọc tùy chọn.
| Tham số | Kiểu | Mô tả |
|---|---|---|
limit | integer | 1–100, mặc định 20. |
cursor | string | Con trỏ mờ từ một trang trước đó. |
status | string | Lọc theo trạng thái lô hàng, ví dụ in_transit. |
q | string | Tìm kiếm toàn văn trên các trường của lô hàng. |
mode | string | air, sea, rail hoặc road. |
carrier_code | string | Lọc theo hãng vận chuyển, ví dụ maersk. |
po | string | Lọc theo số đơn đặt hàng. |
curl "https://api.staging.mglobalship.com/api/v1/external/shipments?status=in_transit&limit=20" \
-H "Authorization: Bearer mgs_live_..."{
"object": "list",
"data": [
{
"object": "shipment",
"id": 12345,
"tracking_number": "MAEU1234567",
"carrier_code": "maersk",
"mode": "sea",
"status": "in_transit",
"origin": { "country": "CN", "city": "Shanghai", "port_code": "CNSHA" },
"destination": { "country": "MY", "city": "Port Klang", "port_code": "MYPKG" },
"po_number": "PO-2026-001",
"estimated_arrival": "2026-04-30T14:00:00+08:00",
"_links": {
"self": "/api/v1/external/shipments/12345",
"tracking": "/api/v1/external/shipments/12345/tracking"
}
}
],
"has_more": false,
"next_cursor": null,
"_links": { "self": "/api/v1/external/shipments" }
}/shipments/{id}Truy xuất một lô hàng đơn lẻ kèm theo thông tin hàng hóa đầy đủ và lịch sử các mốc hành trình của nó.
| Tham số | Kiểu | Mô tả |
|---|---|---|
id* | integer | Mã lô hàng (tham số trong đường dẫn). |
curl https://api.staging.mglobalship.com/api/v1/external/shipments/12345 \
-H "Authorization: Bearer mgs_live_..."{
"object": "shipment",
"id": 12345,
"tracking_number": "MAEU1234567",
"carrier_code": "maersk",
"mode": "sea",
"status": "in_transit",
"origin": { "country": "CN", "city": "Shanghai", "port_code": "CNSHA" },
"destination": { "country": "MY", "city": "Port Klang", "port_code": "MYPKG" },
"po_number": "PO-2026-001",
"container_no": "MAEU123456789",
"estimated_arrival": "2026-04-30T14:00:00+08:00",
"vessel_name": "MSC GULSUN",
"voyage_number": "2026W0105",
"cargo": {
"weight_kg": 18000.5,
"volume_cbm": 45.25,
"pieces": 120,
"description": "Electronics",
"hs_code": "8471.30",
"container_size": "40HQ",
"declared_value": { "amount": 499900, "currency": "USD" }
},
"milestones": [
{
"object": "milestone",
"status_code": "PICKED_UP",
"status_text": "Picked up",
"location": "Shanghai",
"occurred_at": "2026-04-22T08:15:00+08:00",
"source": "maersk_direct_api"
}
],
"_links": {
"self": "/api/v1/external/shipments/12345",
"tracking": "/api/v1/external/shipments/12345/tracking"
}
}/shipments/{id}/weatherLấy thời tiết hiện tại/dự báo (Open-Meteo) tại điểm xuất phát và điểm đến của lô hàng. Làm giàu dữ liệu theo yêu cầu, lưu cache khoảng 30 phút; một chặng sẽ là null khi không thể xác định được vị trí của nó.
| Tham số | Kiểu | Mô tả |
|---|---|---|
id* | integer | Mã lô hàng (tham số trong đường dẫn). |
curl https://api.staging.mglobalship.com/api/v1/external/shipments/12345/weather \
-H "Authorization: Bearer mgs_live_..."{
"object": "weather",
"shipment_id": 12345,
"origin": {
"label": "Singapore, SG",
"lat": 1.29,
"lng": 103.85,
"observed_at": "2026-06-25T12:00:00+00:00",
"temperature_c": 29.4,
"wind_mps": 2.7,
"condition_id": 803,
"condition_main": "Clouds",
"severity": "low",
"summary": "Clouds",
"alerts_count": 0
},
"destination": {
"label": "New York, US",
"lat": 40.71,
"lng": -74.0,
"observed_at": "2026-06-25T12:00:00+00:00",
"temperature_c": 17.1,
"wind_mps": 0.5,
"condition_id": 803,
"condition_main": "Clouds",
"severity": "low",
"summary": "Clouds",
"alerts_count": 0
},
"_links": {
"self": "/api/v1/external/shipments/12345/weather",
"shipment": "/api/v1/external/shipments/12345"
}
}/shipments/{id}/riskLấy các sự kiện xung đột / bất ổn dân sự gần điểm xuất phát và điểm đến của lô hàng (trong phạm vi 100 km trong 7 days qua). Làm giàu dữ liệu theo yêu cầu với kết quả của nhà cung cấp được lưu cache.
| Tham số | Kiểu | Mô tả |
|---|---|---|
id* | integer | Mã lô hàng (tham số trong đường dẫn). |
curl https://api.staging.mglobalship.com/api/v1/external/shipments/12345/risk \
-H "Authorization: Bearer mgs_live_..."{
"object": "geopolitical_risk",
"shipment_id": 12345,
"origin": {
"label": "Singapore, SG",
"lat": 1.29,
"lng": 103.85,
"observed_at": "2026-06-25T12:00:00+00:00",
"severity": "high",
"radius_km": 100,
"since_days": 7,
"summary": "High: 1 violence_civilians event",
"events_count": 1,
"top_events": [
{
"occurred_on": "2026-06-21",
"type": "violence_civilians",
"sub_type": "Attack",
"location": "Singapore",
"fatalities": 0,
"distance_km": 12.0,
"description": "High: 1 violence_civilians event"
}
]
},
"destination": null,
"_links": {
"self": "/api/v1/external/shipments/12345/risk",
"shipment": "/api/v1/external/shipments/12345"
}
}/shipments/{id}/trackingLấy dòng thời gian theo dõi rút gọn (các sự kiện mốc hành trình theo thứ tự) của một lô hàng.
| Tham số | Kiểu | Mô tả |
|---|---|---|
id* | integer | Mã lô hàng (tham số trong đường dẫn). |
curl https://api.staging.mglobalship.com/api/v1/external/shipments/12345/tracking \
-H "Authorization: Bearer mgs_live_..."{
"object": "tracking",
"shipment_id": 12345,
"status": "in_transit",
"estimated_arrival": "2026-04-30T14:00:00+08:00",
"last_event_at": "2026-04-23T06:00:00+08:00",
"events": [
{
"object": "milestone",
"status_code": "PICKED_UP",
"status_text": "Picked up at origin",
"location": "Shanghai",
"occurred_at": "2026-04-22T08:15:00+08:00",
"source": "maersk_direct_api"
},
{
"object": "milestone",
"status_code": "DEPARTED_ORIGIN",
"status_text": "Departed origin port",
"location": "Shanghai",
"occurred_at": "2026-04-23T06:00:00+08:00",
"source": "maersk_direct_api"
}
],
"_links": {
"self": "/api/v1/external/shipments/12345/tracking",
"shipment": "/api/v1/external/shipments/12345"
}
}Webhook
Thay vì liên tục thăm dò, hãy đăng ký webhook để được thông báo khi có điều gì đó xảy ra — ví dụ khi một lô hàng gặp ngoại lệ. Bạn cấu hình các URL điểm cuối và chọn các loại sự kiện trong API Portal, và chúng tôi sẽ POST một payload JSON đến URL của bạn cho mỗi sự kiện.
Mọi lượt gửi đều được ký để bạn có thể xác minh rằng nó đến từ chúng tôi. Chúng tôi gửi chữ ký trong header X-MGS-Signature, loại sự kiện trong X-MGS-Event, và một mã gửi duy nhất trong X-MGS-Delivery-Id (hãy tái sử dụng nó để làm cho trình xử lý của bạn có tính bất biến). Các lượt gửi được thử lại với khoảng lùi theo cấp số nhân trong vòng 24 giờ.
X-MGS-Signature có dạng t=<timestamp>,v1=<signature>, trong đó signature là HMAC-SHA256 dạng hex của chuỗi "<timestamp>.<raw-request-body>" được khóa bằng secret của điểm cuối của bạn. Để xác minh: tách riêng t và v1, tính lại HMAC trên timestamp, một dấu chấm thực tế, và phần thân thô chính xác, rồi so sánh. Hãy từ chối nếu không khớp hoặc nếu timestamp quá cũ.
X-MGS-Event: shipment.exception
X-MGS-Delivery-Id: whd_8f3c2a1b
X-MGS-Signature: t=1715241600,v1=4e2c...hex...sha256Lỗi
Lỗi sử dụng các mã trạng thái HTTP tiêu chuẩn và một cấu trúc JSON nhất quán. Đối tượng lỗi luôn mang một mã ổn định và một thông điệp mà con người đọc được; một số lỗi bổ sung thêm các trường ngữ cảnh. Mọi phản hồi đều bao gồm một request_id — hãy trích dẫn nó khi liên hệ với bộ phận hỗ trợ.
| Trạng thái | Mã | Khi nào |
|---|---|---|
| 400 | validation_error | Phần thân yêu cầu bị thiếu hoặc không hợp lệ (hoặc thiếu header Idempotency-Key). |
| 401 | auth.token_invalid | Thiếu hoặc khóa API không hợp lệ. |
| 402 | shipment.overage_payment_required | Đã hết hạn mức lô hàng; vui lòng thanh toán phần vượt mức còn nợ trước. |
| 403 | auth.insufficient_scope | Khóa thiếu phạm vi bắt buộc, ví dụ shipments.read. |
| 403 | auth.tenant_suspended | Tài khoản tenant không hoạt động. |
| 404 | shipment.not_found | Tài nguyên được yêu cầu không tồn tại. |
| 409 | shipment.duplicate | Đã tồn tại một lô hàng với số theo dõi và hãng vận chuyển này. |
| 429 | rate_limit_exceeded | Đã chạm giới hạn tốc độ; xem retry_after_seconds. |
{
"error": {
"code": "auth.token_invalid",
"message": "Token invalid."
},
"request_id": "req_9a8b7c6d"
}{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded for Silver tier (300 req/min). Wait 23s.",
"retry_after_seconds": 23
},
"request_id": "req_1f2e3d4c"
}