Nhà phát triển

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ườngURL cơ sở
Productionhttps://api.mglobalship.com/api/v1/external
Staginghttps://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.

bash
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ậcYêu cầu / phút
Bronze60
Silver300
Gold1.000
Platinum5.000
EnterpriseKhô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

GET/health

Kiể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.

bash
curl https://api.staging.mglobalship.com/api/v1/external/health \
  -H "Authorization: Bearer mgs_live_..."
json
{
  "status": "ok",
  "tenant_id": 123,
  "tier": "silver",
  "rate_limit": {
    "limit": 300,
    "remaining": 299,
    "reset_seconds": 59
  }
}
POST/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ểuMô 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*stringSố AWB / B-L / số theo dõi.
carrier_code*stringMã 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*stringPhương thức vận chuyển: sea, air hoặc courier.
bash
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"
  }'
json
{
  "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"
  }
}
GET/shipments

Liệ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ểuMô tả
limitinteger1–100, mặc định 20.
cursorstringCon trỏ mờ từ một trang trước đó.
statusstringLọc theo trạng thái lô hàng, ví dụ in_transit.
qstringTìm kiếm toàn văn trên các trường của lô hàng.
modestringair, sea, rail hoặc road.
carrier_codestringLọc theo hãng vận chuyển, ví dụ maersk.
postringLọc theo số đơn đặt hàng.
bash
curl "https://api.staging.mglobalship.com/api/v1/external/shipments?status=in_transit&limit=20" \
  -H "Authorization: Bearer mgs_live_..."
json
{
  "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" }
}
GET/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ểuMô tả
id*integerMã lô hàng (tham số trong đường dẫn).
bash
curl https://api.staging.mglobalship.com/api/v1/external/shipments/12345 \
  -H "Authorization: Bearer mgs_live_..."
json
{
  "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"
  }
}
GET/shipments/{id}/weather

Lấ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ểuMô tả
id*integerMã lô hàng (tham số trong đường dẫn).
bash
curl https://api.staging.mglobalship.com/api/v1/external/shipments/12345/weather \
  -H "Authorization: Bearer mgs_live_..."
json
{
  "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"
  }
}
GET/shipments/{id}/risk

Lấ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ểuMô tả
id*integerMã lô hàng (tham số trong đường dẫn).
bash
curl https://api.staging.mglobalship.com/api/v1/external/shipments/12345/risk \
  -H "Authorization: Bearer mgs_live_..."
json
{
  "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"
  }
}
GET/shipments/{id}/tracking

Lấ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ểuMô tả
id*integerMã lô hàng (tham số trong đường dẫn).
bash
curl https://api.staging.mglobalship.com/api/v1/external/shipments/12345/tracking \
  -H "Authorization: Bearer mgs_live_..."
json
{
  "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ũ.

http
X-MGS-Event: shipment.exception
X-MGS-Delivery-Id: whd_8f3c2a1b
X-MGS-Signature: t=1715241600,v1=4e2c...hex...sha256

Lỗ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áiKhi nào
400validation_errorPhần thân yêu cầu bị thiếu hoặc không hợp lệ (hoặc thiếu header Idempotency-Key).
401auth.token_invalidThiếu hoặc khóa API không hợp lệ.
402shipment.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.
403auth.insufficient_scopeKhóa thiếu phạm vi bắt buộc, ví dụ shipments.read.
403auth.tenant_suspendedTài khoản tenant không hoạt động.
404shipment.not_foundTài nguyên được yêu cầu không tồn tại.
409shipment.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.
429rate_limit_exceededĐã chạm giới hạn tốc độ; xem retry_after_seconds.
json
{
  "error": {
    "code": "auth.token_invalid",
    "message": "Token invalid."
  },
  "request_id": "req_9a8b7c6d"
}
json
{
  "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"
}

Bắt đầu