{
  "name": "CONNEX API",
  "version": "1",
  "items": [
    {
      "type": "folder",
      "name": "Authentication",
      "seq": 1,
      "items": [
        {
          "type": "http-request",
          "name": "Get access token",
          "seq": 1,
          "request": {
            "url": "{{baseUrl}}/oauth/token",
            "method": "POST",
            "headers": [],
            "params": [],
            "body": {
              "mode": "formUrlEncoded",
              "json": null,
              "text": null,
              "xml": null,
              "sparql": null,
              "formUrlEncoded": [
                {
                  "name": "grant_type",
                  "value": "client_credentials",
                  "enabled": true
                }
              ],
              "multipartForm": []
            },
            "auth": {
              "mode": "basic",
              "basic": {
                "username": "{{clientId}}",
                "password": "{{clientSecret}}"
              }
            },
            "script": {
              "req": null,
              "res": "if (res.body?.access_token) bru.setEnvVar('accessToken', res.body.access_token);"
            },
            "vars": {
              "req": [],
              "res": []
            },
            "assertions": [],
            "tests": null,
            "docs": "Client credentials: clientId and clientSecret come from your API key — CONNEX portal → Tools → API keys (https://connex.fastship.co/api-keys). Saves access_token into accessToken. Tokens last one hour — run this again when one expires."
          }
        }
      ]
    },
    {
      "type": "folder",
      "name": "Rates",
      "seq": 2,
      "items": [
        {
          "type": "http-request",
          "name": "Get rates",
          "seq": 1,
          "request": {
            "url": "{{baseUrl}}/v1/rates",
            "method": "POST",
            "headers": [],
            "params": [],
            "body": {
              "mode": "json",
              "json": "{\n  \"Country\": \"USA\",\n  \"ActualWeight\": 850,\n  \"Weight\": 1200,\n  \"Length\": 30,\n  \"Width\": 20,\n  \"Height\": 10\n}",
              "text": null,
              "xml": null,
              "sparql": null,
              "formUrlEncoded": [],
              "multipartForm": []
            },
            "auth": {
              "mode": "bearer",
              "bearer": {
                "token": "{{accessToken}}"
              }
            },
            "script": {
              "req": null,
              "res": null
            },
            "vars": {
              "req": [],
              "res": []
            },
            "assertions": [],
            "tests": null,
            "docs": "Requires rates:read. Country is ISO-3; weights in grams, dimensions in cm. Prices come back in THB."
          }
        }
      ]
    },
    {
      "type": "folder",
      "name": "Tracking",
      "seq": 3,
      "items": [
        {
          "type": "http-request",
          "name": "Get tracking",
          "seq": 1,
          "request": {
            "url": "{{baseUrl}}/v1/tracking?refs=ORD-10432,ORD-10433",
            "method": "GET",
            "headers": [],
            "params": [
              {
                "name": "refs",
                "value": "ORD-10432,ORD-10433",
                "type": "query",
                "enabled": true
              }
            ],
            "body": {
              "mode": "none",
              "json": null,
              "text": null,
              "xml": null,
              "sparql": null,
              "formUrlEncoded": [],
              "multipartForm": []
            },
            "auth": {
              "mode": "bearer",
              "bearer": {
                "token": "{{accessToken}}"
              }
            },
            "script": {
              "req": null,
              "res": null
            },
            "vars": {
              "req": [],
              "res": []
            },
            "assertions": [],
            "tests": null,
            "docs": "Requires tracking:read. Up to 50 comma-separated order refs."
          }
        }
      ]
    },
    {
      "type": "folder",
      "name": "Orders",
      "seq": 4,
      "items": [
        {
          "type": "http-request",
          "name": "Create order",
          "seq": 1,
          "request": {
            "url": "{{baseUrl}}/v1/orders",
            "method": "POST",
            "headers": [],
            "params": [],
            "body": {
              "mode": "json",
              "json": "{\n  \"orderId\": \"ORD-10432\",\n  \"currency\": \"THB\",\n  \"customer\": {\n    \"name\": \"Jane Doe\",\n    \"email\": \"jane@example.com\",\n    \"phone\": \"+1 512 555 0100\"\n  },\n  \"shippingAddress\": {\n    \"name\": \"Jane Doe\",\n    \"phone\": \"+1 512 555 0100\",\n    \"line1\": \"1 Main St\",\n    \"city\": \"Austin\",\n    \"state\": \"TX\",\n    \"postalCode\": \"78701\",\n    \"country\": \"US\"\n  },\n  \"items\": [\n    {\n      \"sku\": \"SKU-001\",\n      \"name\": \"Gold Rook Ear Cuff\",\n      \"quantity\": 2,\n      \"unitPrice\": 500,\n      \"weight\": 50\n    }\n  ],\n  \"shipping\": {\n    \"serviceId\": \"EX001.\",\n    \"serviceName\": \"Fastship Express via UPS\",\n    \"price\": 1884\n  },\n  \"totals\": {\n    \"total\": 2884\n  }\n}",
              "text": null,
              "xml": null,
              "sparql": null,
              "formUrlEncoded": [],
              "multipartForm": []
            },
            "auth": {
              "mode": "bearer",
              "bearer": {
                "token": "{{accessToken}}"
              }
            },
            "script": {
              "req": null,
              "res": null
            },
            "vars": {
              "req": [],
              "res": []
            },
            "assertions": [],
            "tests": null,
            "docs": "Requires orders:write. Creates the order in the CONNEX account that generated this API key — a REAL order on that account's order desk, under its \"CONNEX API\" channel (created with the first order). Same orderId again = safe retry. Track it with Get tracking ?refs=<orderId>."
          }
        }
      ]
    },
    {
      "type": "folder",
      "name": "Webhooks",
      "seq": 5,
      "items": [
        {
          "type": "http-request",
          "name": "Register webhook endpoint",
          "seq": 1,
          "request": {
            "url": "{{baseUrl}}/v1/webhook_endpoints",
            "method": "POST",
            "headers": [],
            "params": [],
            "body": {
              "mode": "json",
              "json": "{\n  \"url\": \"{{webhookUrl}}\",\n  \"events\": [\n    \"tracking.updated\"\n  ]\n}",
              "text": null,
              "xml": null,
              "sparql": null,
              "formUrlEncoded": [],
              "multipartForm": []
            },
            "auth": {
              "mode": "bearer",
              "bearer": {
                "token": "{{accessToken}}"
              }
            },
            "script": {
              "req": null,
              "res": "if (res.body?.id) bru.setEnvVar('webhookEndpointId', res.body.id);\nif (res.body?.secret) bru.setEnvVar('webhookSecret', res.body.secret);"
            },
            "vars": {
              "req": [],
              "res": []
            },
            "assertions": [],
            "tests": null,
            "docs": "Requires webhooks:write. The secret is returned only here — it is saved into webhookSecret."
          }
        },
        {
          "type": "http-request",
          "name": "Test webhook endpoint",
          "seq": 2,
          "request": {
            "url": "{{baseUrl}}/v1/webhook_endpoints/{{webhookEndpointId}}/test",
            "method": "POST",
            "headers": [],
            "params": [],
            "body": {
              "mode": "none",
              "json": null,
              "text": null,
              "xml": null,
              "sparql": null,
              "formUrlEncoded": [],
              "multipartForm": []
            },
            "auth": {
              "mode": "bearer",
              "bearer": {
                "token": "{{accessToken}}"
              }
            },
            "script": {
              "req": null,
              "res": null
            },
            "vars": {
              "req": [],
              "res": []
            },
            "assertions": [],
            "tests": null,
            "docs": "Sends a sample tracking.updated (X-Connex-Test: true, orderRef TEST-ORDER-001) to the endpoint now and reports whether it accepted it."
          }
        },
        {
          "type": "http-request",
          "name": "List webhook endpoints",
          "seq": 3,
          "request": {
            "url": "{{baseUrl}}/v1/webhook_endpoints",
            "method": "GET",
            "headers": [],
            "params": [],
            "body": {
              "mode": "none",
              "json": null,
              "text": null,
              "xml": null,
              "sparql": null,
              "formUrlEncoded": [],
              "multipartForm": []
            },
            "auth": {
              "mode": "bearer",
              "bearer": {
                "token": "{{accessToken}}"
              }
            },
            "script": {
              "req": null,
              "res": null
            },
            "vars": {
              "req": [],
              "res": []
            },
            "assertions": [],
            "tests": null,
            "docs": "Requires webhooks:write."
          }
        },
        {
          "type": "http-request",
          "name": "Delete webhook endpoint",
          "seq": 4,
          "request": {
            "url": "{{baseUrl}}/v1/webhook_endpoints/{{webhookEndpointId}}",
            "method": "DELETE",
            "headers": [],
            "params": [],
            "body": {
              "mode": "none",
              "json": null,
              "text": null,
              "xml": null,
              "sparql": null,
              "formUrlEncoded": [],
              "multipartForm": []
            },
            "auth": {
              "mode": "bearer",
              "bearer": {
                "token": "{{accessToken}}"
              }
            },
            "script": {
              "req": null,
              "res": null
            },
            "vars": {
              "req": [],
              "res": []
            },
            "assertions": [],
            "tests": null,
            "docs": "Requires webhooks:write."
          }
        },
        {
          "type": "http-request",
          "name": "Simulate tracking.updated (to your endpoint)",
          "seq": 5,
          "request": {
            "url": "{{webhookUrl}}",
            "method": "POST",
            "headers": [],
            "params": [],
            "body": {
              "mode": "json",
              "json": "{\n  \"updates\": [\n    {\n      \"scope\": \"shipment\",\n      \"fastShipId\": 137971,\n      \"orderRef\": \"ORD-10432\",\n      \"fastshipShipmentId\": 884120,\n      \"trackingNo\": \"FS2604188412\",\n      \"agentTrackingNo\": \"1Z999AA10123456784\",\n      \"status\": \"OUT_FOR_DELIVERY\",\n      \"orderStatus\": \"SHIPPED\",\n      \"provider\": \"UPS\",\n      \"serviceAgent\": \"FSEXP-UPS\",\n      \"agentName\": \"UPS Worldwide Express\",\n      \"updatedAt\": \"2026-10-24T08:15:00.000Z\"\n    },\n    {\n      \"scope\": \"order\",\n      \"fastShipId\": 137971,\n      \"orderRef\": \"ORD-10433\",\n      \"orderStatus\": \"CANCELLED\",\n      \"updatedAt\": \"2026-10-24T08:16:30.000Z\"\n    }\n  ]\n}",
              "text": null,
              "xml": null,
              "sparql": null,
              "formUrlEncoded": [],
              "multipartForm": []
            },
            "auth": {
              "mode": "bearer",
              "bearer": {
                "token": "{{webhookSecret}}"
              }
            },
            "script": {
              "req": null,
              "res": null
            },
            "vars": {
              "req": [],
              "res": []
            },
            "assertions": [],
            "tests": null,
            "docs": "Sends YOUR receiver exactly what CONNEX will send, signed with webhookSecret — use it to test your handler before going live. Expect 2xx; a wrong secret should get 401."
          }
        }
      ]
    }
  ],
  "environments": [
    {
      "name": "Production",
      "variables": [
        {
          "name": "baseUrl",
          "value": "https://api.connexglobal.co",
          "type": "text",
          "enabled": true,
          "secret": false
        },
        {
          "name": "clientId",
          "value": "cnx_client_…",
          "type": "text",
          "enabled": true,
          "secret": false
        },
        {
          "name": "clientSecret",
          "value": "",
          "type": "text",
          "enabled": true,
          "secret": true
        },
        {
          "name": "accessToken",
          "value": "",
          "type": "text",
          "enabled": true,
          "secret": true
        },
        {
          "name": "webhookEndpointId",
          "value": "",
          "type": "text",
          "enabled": true,
          "secret": false
        },
        {
          "name": "webhookUrl",
          "value": "https://your-app.com/webhooks/connex",
          "type": "text",
          "enabled": true,
          "secret": false
        },
        {
          "name": "webhookSecret",
          "value": "",
          "type": "text",
          "enabled": true,
          "secret": true
        }
      ]
    }
  ],
  "brunoConfig": {
    "version": "1",
    "name": "CONNEX API",
    "type": "collection",
    "ignore": [
      "node_modules",
      ".git"
    ]
  }
}