นักพัฒนา

พัฒนาบน API ของ MG Ship

ดึงข้อมูลการมองเห็นการขนส่งแบบเรียลไทม์เข้าสู่ระบบของคุณเองด้วย REST API ที่ใช้งานง่ายและมีการจัดเวอร์ชัน

ภาพรวม

MG Ship API เป็น REST API ที่คืนค่าเป็น JSON ผ่าน HTTPS โดยให้ระบบของคุณเข้าถึงข้อมูลการมองเห็นการขนส่งแบบเป็นโปรแกรมได้ ทั้งรายการการขนส่ง บันทึกการขนส่งฉบับเต็ม และไทม์ไลน์การติดตาม เพื่อให้คุณสามารถดึงเหตุการณ์สำคัญ (milestone) เข้าสู่ TMS, ERP หรือพอร์ทัลลูกค้าของคุณเองได้

ทุกเอนด์พอยต์อยู่ภายใต้เส้นทางฐานที่มีการจัดเวอร์ชันด้านล่าง API มีการจัดเวอร์ชันในเส้นทาง URL (v1) การเปลี่ยนแปลงที่ทำให้เกิดความไม่เข้ากัน (breaking changes) จะเผยแพร่ภายใต้เส้นทางใหม่ (v2) พร้อมระยะเวลาเลิกใช้งาน 12 เดือนสำหรับเวอร์ชันก่อนหน้า ดังนั้นการเชื่อมต่อที่สร้างขึ้นบน v1 จะยังคงทำงานได้ต่อไป

Base URL

เลือก Base URL สำหรับสภาพแวดล้อมที่คุณกำลังเชื่อมต่อด้วย เส้นทางของทุกเอนด์พอยต์ด้านล่างเป็นเส้นทางสัมพัทธ์กับ Base URL นี้ Staging และ Test (VPS) มีไว้สำหรับการพัฒนาและทดสอบ ใช้ Production เฉพาะกับคีย์จริงเท่านั้น

สภาพแวดล้อมBase URL
Productionhttps://api.mglobalship.com/api/v1/external
Staginghttps://api.staging.mglobalship.com/api/v1/external
Test (VPS)https://mgs.aipipis.com/api/v1/external

การยืนยันตัวตน

ยืนยันตัวตนทุกคำขอด้วยคีย์ API ที่ส่งเป็น Bearer token ในส่วนหัว Authorization คีย์จะออกให้แยกตามผู้เช่า (tenant) จาก API Portal จะแสดงเพียงครั้งเดียวเมื่อสร้าง มีขอบเขตที่ระบุไว้อย่างชัดเจน (เช่น shipments.read) และสามารถหมุนเวียนหรือเพิกถอนได้ทุกเมื่อ

เก็บคีย์ไว้ฝั่งเซิร์ฟเวอร์เสมอ อย่านำไปใส่ในโค้ดของเบราว์เซอร์หรือมือถือ หากคีย์ถูกเปิดเผย ให้หมุนเวียนคีย์จาก API Portal แล้วคีย์เดิมจะหยุดทำงานทันที

bash
curl https://api.staging.mglobalship.com/api/v1/external/health \
  -H "Authorization: Bearer mgs_live_xxxxxxxxxxxxxxxxxxxxxxxx"

ข้อกำหนด

การแบ่งหน้า

เอนด์พอยต์แบบรายการใช้การแบ่งหน้าด้วยเคอร์เซอร์ (cursor) ส่งค่า limit (1–100, ค่าเริ่มต้น 20) เพื่อกำหนดขนาดหน้า เมื่อมีผลลัพธ์เพิ่มเติม การตอบกลับจะตั้งค่า has_more เป็น true และคืนค่า next_cursor ให้ส่งค่านี้กลับมาเป็นพารามิเตอร์การค้นหา cursor เพื่อดึงหน้าถัดไป เคอร์เซอร์เป็นค่าทึบ (opaque) ให้ปฏิบัติต่อมันเสมือนโทเค็น อย่าสร้างขึ้นเอง

ขีดจำกัดอัตรา

คำขอถูกจำกัดอัตราต่อนาทีตามระดับ (tier) ของบัญชีคุณ ทุกการตอบกลับจะมีส่วนหัว X-RateLimit-Limit, X-RateLimit-Remaining และ X-RateLimit-Reset (วินาทีจนกว่าหน้าต่างจะรีเซ็ต) การใช้งานเกินขีดจำกัดจะคืนค่า 429 พร้อมค่า retry_after_seconds ในเนื้อหา คีย์แต่ละตัวสามารถได้รับขีดจำกัดสูงสุดที่สูงขึ้นได้ตามคำขอ

ระดับคำขอ / นาที
Bronze60
Silver300
Gold1,000
Platinum5,000
Enterpriseไม่จำกัด

Idempotency

เอนด์พอยต์การเขียน (เช่น POST /shipments) ต้องใช้ส่วนหัว Idempotency-Key การลองส่งคำขอใหม่ด้วยคีย์เดิมจะคืนผลลัพธ์เดิมแทนที่จะสร้างรายการซ้ำ ดังนั้นการลองใหม่ผ่านเครือข่ายจึงปลอดภัยเสมอ เอนด์พอยต์แบบอ่านอย่างเดียว (GET) ไม่จำเป็นต้องใช้

เอนด์พอยต์

GET/health

ตรวจสอบว่าคีย์ของคุณใช้งานได้ และดูระดับ (tier) ปัจจุบันพร้อมสถานะขีดจำกัดอัตรา เป็นการเรียกขนาดเล็กเพื่อยืนยันการเชื่อมต่อ

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

ลงทะเบียนการขนส่งเพื่อให้แพลตฟอร์มเริ่มติดตาม ต้องมีขอบเขต shipments.write และส่วนหัว Idempotency-Key ที่ไม่ซ้ำกัน การขนส่งนี้จะถูกนับรวมในโควตารายเดือนของแพ็กเกจของคุณ

พารามิเตอร์ประเภทคำอธิบาย
Idempotency-Key*string (header)ไม่ซ้ำกันต่อคำขอ การลองใหม่ด้วยค่าเดิมจะคืนการขนส่งเดิมแทนที่จะสร้างรายการซ้ำ
tracking_number*stringหมายเลข AWB / B-L / หมายเลขติดตาม
carrier_code*stringรหัสผู้ขนส่งหรือสายการบิน (รหัส PCS, รหัสสายการบิน IATA หรือ courier slug ของ AfterShip)
mode*stringโหมดการขนส่ง: sea, air หรือ 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

แสดงรายการการขนส่งของคุณ โดยเรียงจากใหม่สุดก่อน พร้อมการแบ่งหน้าด้วยเคอร์เซอร์และตัวกรองเสริม

พารามิเตอร์ประเภทคำอธิบาย
limitinteger1–100, ค่าเริ่มต้น 20
cursorstringเคอร์เซอร์แบบทึบจากหน้าก่อนหน้า
statusstringกรองตามสถานะการขนส่ง เช่น in_transit
qstringค้นหาแบบเต็มข้อความในฟิลด์การขนส่ง
modestringair, sea, rail หรือ road
carrier_codestringกรองตามผู้ขนส่ง เช่น maersk
postringกรองตามเลขที่ใบสั่งซื้อ (purchase order)
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}

ดึงข้อมูลการขนส่งรายการเดียวพร้อมรายละเอียดสินค้าฉบับเต็มและประวัติเหตุการณ์สำคัญ (milestone)

พารามิเตอร์ประเภทคำอธิบาย
id*integerรหัสการขนส่ง (พารามิเตอร์ในเส้นทาง)
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

รับสภาพอากาศปัจจุบัน/พยากรณ์ (Open-Meteo) ที่ต้นทางและปลายทางของการขนส่ง การเสริมข้อมูลแบบออนดีมานด์ แคชไว้ประมาณ 30 นาที ช่วงการเดินทาง (leg) จะเป็น null เมื่อไม่สามารถระบุตำแหน่งได้

พารามิเตอร์ประเภทคำอธิบาย
id*integerรหัสการขนส่ง (พารามิเตอร์ในเส้นทาง)
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

รับเหตุการณ์ความขัดแย้ง/ความไม่สงบของพลเรือนใกล้ต้นทางและปลายทางของการขนส่ง (ภายในระยะ 100 km ในช่วง 7 days ที่ผ่านมา) การเสริมข้อมูลแบบออนดีมานด์พร้อมแคชผลลัพธ์จากผู้ให้บริการ

พารามิเตอร์ประเภทคำอธิบาย
id*integerรหัสการขนส่ง (พารามิเตอร์ในเส้นทาง)
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

รับไทม์ไลน์การติดตามแบบกระชับ (เหตุการณ์สำคัญที่เรียงลำดับ) ของการขนส่ง

พารามิเตอร์ประเภทคำอธิบาย
id*integerรหัสการขนส่ง (พารามิเตอร์ในเส้นทาง)
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

แทนที่จะสำรวจ (polling) ให้สมัครรับ webhook เพื่อรับการแจ้งเตือนเมื่อมีบางสิ่งเกิดขึ้น เช่น เมื่อการขนส่งพบข้อยกเว้น (exception) คุณกำหนดค่า URL ของเอนด์พอยต์และเลือกประเภทเหตุการณ์ได้ใน API Portal จากนั้นเราจะส่ง POST เพย์โหลด JSON ไปยัง URL ของคุณสำหรับแต่ละเหตุการณ์

การส่งทุกครั้งจะมีการลงนามเพื่อให้คุณตรวจสอบได้ว่ามาจากเราจริง เราส่งลายเซ็นในส่วนหัว X-MGS-Signature ประเภทเหตุการณ์ใน X-MGS-Event และรหัสการส่งที่ไม่ซ้ำกันใน X-MGS-Delivery-Id (นำกลับมาใช้เพื่อให้ตัวจัดการของคุณเป็นแบบ idempotent) การส่งจะถูกลองใหม่ด้วยการถอยกลับแบบเอ็กซ์โพเนนเชียล (exponential backoff) ตลอด 24 ชั่วโมง

X-MGS-Signature มีรูปแบบ t=<timestamp>,v1=<signature> โดยที่ signature คือ HMAC-SHA256 แบบเลขฐานสิบหกของสตริง "<timestamp>.<raw-request-body>" ที่ใช้คีย์เป็นความลับของเอนด์พอยต์ของคุณ วิธีตรวจสอบ: แยก t และ v1 ออกมา คำนวณ HMAC ใหม่ครอบคลุม timestamp จุด (dot) ตามตัวอักษร และเนื้อหาดิบที่ถูกต้องแม่นยำ แล้วเปรียบเทียบ ปฏิเสธหากไม่ตรงกันหรือหาก timestamp เก่าเกินไป

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

ข้อผิดพลาด

ข้อผิดพลาดใช้รหัสสถานะ HTTP มาตรฐานและซองหุ้ม JSON ที่สม่ำเสมอ ออบเจกต์ข้อผิดพลาดจะมีรหัส (code) ที่คงที่และข้อความที่อ่านเข้าใจได้เสมอ ข้อผิดพลาดบางอย่างจะเพิ่มฟิลด์บริบทเข้ามา ทุกการตอบกลับจะมี request_id ให้อ้างอิงรหัสนี้เมื่อติดต่อฝ่ายสนับสนุน

สถานะรหัสเมื่อใด
400validation_errorเนื้อหาคำขอขาดหายหรือไม่ถูกต้อง (หรือไม่มีส่วนหัว Idempotency-Key)
401auth.token_invalidไม่มีคีย์ API หรือคีย์ API ไม่ถูกต้อง
402shipment.overage_payment_requiredโควตาการขนส่งหมดแล้ว กรุณาชำระค่าส่วนเกินที่ค้างอยู่ก่อน
403auth.insufficient_scopeคีย์ขาดขอบเขตที่จำเป็น เช่น shipments.read
403auth.tenant_suspendedบัญชีผู้เช่า (tenant) ไม่อยู่ในสถานะใช้งาน
404shipment.not_foundไม่มีทรัพยากรที่ร้องขออยู่
409shipment.duplicateมีการขนส่งที่ใช้หมายเลขติดตามและผู้ขนส่งนี้อยู่แล้ว
429rate_limit_exceededถึงขีดจำกัดอัตราแล้ว ดูที่ 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"
}

เริ่มต้นใช้งาน