{
  "info": {
    "name": "MG Ship — Public API (v1)",
    "_postman_id": "b3f1a2c4-5d6e-47f8-9a0b-1c2d3e4f5a6b",
    "description": "Postman collection for the MG Ship public API (`/api/v1/external`).\n\n## Setup\n1. Open the collection **Variables** tab.\n2. Set `baseUrl` to the environment you are testing against:\n   - Production: `https://api.mglobalship.com/api/v1/external`\n   - Staging: `https://api.staging.mglobalship.com/api/v1/external`\n   - Test (VPS): `https://mgs.aipipis.com/api/v1/external`\n3. Set `apiKey` to an API key issued from the API Portal (`mgs_live_...`). Read endpoints need the `shipments.read` scope; `POST /shipments` needs `shipments.write`.\n\nAuth is applied at the collection level as `Authorization: Bearer {{apiKey}}`.\n\nThe **Create shipment** request sends an `Idempotency-Key` header set to `{{$guid}}`, so Postman generates a fresh unique key on every send. Reuse the same value to safely retry without creating a duplicate.\n\nAfter **Create shipment** or **List shipments**, the collection's test scripts capture a shipment id into the `shipmentId` variable, which **Get shipment** and **Get tracking** then reuse.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "bearer",
    "bearer": [{ "key": "token", "value": "{{apiKey}}", "type": "string" }]
  },
  "variable": [
    { "key": "baseUrl", "value": "https://api.staging.mglobalship.com/api/v1/external", "type": "string" },
    { "key": "apiKey", "value": "mgs_live_xxxxxxxxxxxxxxxxxxxxxxxx", "type": "string" },
    { "key": "shipmentId", "value": "", "type": "string" }
  ],
  "item": [
    {
      "name": "Health check",
      "request": {
        "method": "GET",
        "header": [{ "key": "Accept", "value": "application/json" }],
        "url": {
          "raw": "{{baseUrl}}/health",
          "host": ["{{baseUrl}}"],
          "path": ["health"]
        },
        "description": "Verify your key works and read your current tier and rate-limit status."
      }
    },
    {
      "name": "Create shipment",
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "const res = pm.response.json();",
              "if (res && res.id) {",
              "  pm.collectionVariables.set('shipmentId', String(res.id));",
              "  console.log('Saved shipmentId =', res.id);",
              "}",
              "pm.test('created or returned existing shipment', function () {",
              "  pm.expect([200, 201]).to.include(pm.response.code);",
              "});"
            ]
          }
        }
      ],
      "request": {
        "method": "POST",
        "header": [
          { "key": "Content-Type", "value": "application/json" },
          { "key": "Accept", "value": "application/json" },
          { "key": "Idempotency-Key", "value": "{{$guid}}", "description": "Unique per request; retrying with the same value returns the original shipment instead of creating a duplicate." }
        ],
        "body": {
          "mode": "raw",
          "raw": "{\n  \"tracking_number\": \"160-12345675\",\n  \"carrier_code\": \"pcs\",\n  \"mode\": \"air\"\n}"
        },
        "url": {
          "raw": "{{baseUrl}}/shipments",
          "host": ["{{baseUrl}}"],
          "path": ["shipments"]
        },
        "description": "Register a shipment so the platform starts tracking it. Requires the `shipments.write` scope and a unique `Idempotency-Key` header. Counts against your plan's monthly quota."
      }
    },
    {
      "name": "List shipments",
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "const res = pm.response.json();",
              "if (res && Array.isArray(res.data) && res.data.length && !pm.collectionVariables.get('shipmentId')) {",
              "  pm.collectionVariables.set('shipmentId', String(res.data[0].id));",
              "  console.log('Saved shipmentId =', res.data[0].id);",
              "}"
            ]
          }
        }
      ],
      "request": {
        "method": "GET",
        "header": [{ "key": "Accept", "value": "application/json" }],
        "url": {
          "raw": "{{baseUrl}}/shipments?limit=20&status=in_transit",
          "host": ["{{baseUrl}}"],
          "path": ["shipments"],
          "query": [
            { "key": "limit", "value": "20", "description": "1–100, default 20." },
            { "key": "status", "value": "in_transit", "description": "Filter by shipment status." },
            { "key": "cursor", "value": "", "description": "Opaque cursor from a previous page.", "disabled": true },
            { "key": "q", "value": "", "description": "Full-text search.", "disabled": true },
            { "key": "mode", "value": "", "description": "air, sea, or courier.", "disabled": true },
            { "key": "carrier_code", "value": "", "description": "Filter by carrier.", "disabled": true },
            { "key": "po", "value": "", "description": "Filter by purchase-order number.", "disabled": true }
          ]
        },
        "description": "List your shipments, newest first, with cursor pagination and optional filters."
      }
    },
    {
      "name": "Get shipment",
      "request": {
        "method": "GET",
        "header": [{ "key": "Accept", "value": "application/json" }],
        "url": {
          "raw": "{{baseUrl}}/shipments/{{shipmentId}}",
          "host": ["{{baseUrl}}"],
          "path": ["shipments", "{{shipmentId}}"]
        },
        "description": "Retrieve a single shipment with full cargo details and milestone history. Uses the `shipmentId` captured by Create / List."
      }
    },
    {
      "name": "Get tracking",
      "request": {
        "method": "GET",
        "header": [{ "key": "Accept", "value": "application/json" }],
        "url": {
          "raw": "{{baseUrl}}/shipments/{{shipmentId}}/tracking",
          "host": ["{{baseUrl}}"],
          "path": ["shipments", "{{shipmentId}}", "tracking"]
        },
        "description": "Get the compact tracking timeline (ordered milestone events) for a shipment."
      }
    },
    {
      "name": "Get weather along route",
      "request": {
        "method": "GET",
        "header": [{ "key": "Accept", "value": "application/json" }],
        "url": {
          "raw": "{{baseUrl}}/shipments/{{shipmentId}}/weather",
          "host": ["{{baseUrl}}"],
          "path": ["shipments", "{{shipmentId}}", "weather"]
        },
        "description": "On-demand weather (Open-Meteo) at the shipment's origin and destination. A leg is null when its position cannot be resolved. Provider results are cached ~30 min."
      }
    },
    {
      "name": "Get geopolitical risk along route",
      "request": {
        "method": "GET",
        "header": [{ "key": "Accept", "value": "application/json" }],
        "url": {
          "raw": "{{baseUrl}}/shipments/{{shipmentId}}/risk",
          "host": ["{{baseUrl}}"],
          "path": ["shipments", "{{shipmentId}}", "risk"]
        },
        "description": "On-demand conflict / civil-unrest events near the shipment's origin and destination (within 100 km over the last 7 days)."
      }
    }
  ]
}
