{
  "info": {
    "name": "CTO Logistics Public API (v1)",
    "description": "B2B public API for CTO Logistics.\n\n**Auth:** set collection variables `api_key` and `client_secret`. Every request is sent with `X-API-KEY` + `X-CLIENT-SECRET`, and JSON bodies are AES-256-CBC encrypted automatically (collection pre-request script). Responses are decrypted automatically — open the **Visualize** tab to read the plaintext.\n\n**Base URL:** `base_url` is set to staging `https://public-api-service-316996095971.us-central1.run.app/api/v1`; production is `https://api.ctologistic.com/v1`.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "event": [
    {
      "listen": "prerequest",
      "script": {
        "type": "text/javascript",
        "exec": [
          "// CTO Logistics — plain JSON over HTTPS (payload encryption removed).",
          "// Auth: get a token from 'Authentication > Get access token', then every",
          "// request auto-sends 'Authorization: Bearer {{access_token}}'.",
          "pm.request.headers.upsert({ key: 'Accept', value: 'application/json' });"
        ]
      }
    }
  ],
  "variable": [
    {
      "key": "base_url",
      "value": "https://public-api-service-316996095971.us-central1.run.app/api/v1",
      "type": "string"
    },
    {
      "key": "api_key",
      "value": "",
      "type": "string"
    },
    {
      "key": "client_secret",
      "value": "",
      "type": "string"
    },
    {
      "key": "shipment_id",
      "value": "669823271",
      "type": "string"
    },
    {
      "key": "access_token",
      "value": "",
      "type": "string"
    }
  ],
  "item": [
    {
      "name": "Authentication",
      "item": [
        {
          "name": "Get access token",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "let json = null;",
                  "try { json = pm.response.json(); } catch (e) {}",
                  "pm.test('token issued (200)', function () { pm.expect(pm.response.code).to.eql(200); });",
                  "if (json && json.access_token) {",
                  "    pm.collectionVariables.set('access_token', json.access_token);",
                  "    console.log('Saved access_token (expires_in ' + json.expires_in + 's)');",
                  "} else {",
                  "    console.warn('No access_token in response:', pm.response.text());",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"api_key\": \"{{api_key}}\",\n  \"client_secret\": \"{{client_secret}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/auth/token",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "auth",
                "token"
              ]
            },
            "description": "Exchange api_key + client_secret for a JWT Bearer token (valid 12h). The test script saves it to the collection variable {{access_token}}, which every other request sends as Authorization: Bearer."
          }
        }
      ]
    },
    {
      "name": "Health",
      "item": [
        {
          "name": "Ping",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/ping",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "ping"
              ]
            },
            "description": "Authenticated health check."
          },
          "response": []
        }
      ]
    },
    {
      "name": "Purchases",
      "item": [
        {
          "name": "List purchases",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/purchases?page=1&per_page=15",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "purchases"
              ],
              "query": [
                {
                  "key": "page",
                  "value": "1"
                },
                {
                  "key": "per_page",
                  "value": "15"
                }
              ]
            }
          },
          "response": []
        },
        {
          "name": "Create purchase",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/purchases",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "purchases"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"from_address\": {\n    \"first_name\": \"John\",\n    \"last_name\": \"Doe\",\n    \"company\": \"Acme Inc\",\n    \"street1\": \"123 Main St\",\n    \"street2\": \"Suite 100\",\n    \"city\": \"New York\",\n    \"state\": \"NY\",\n    \"zip\": \"10001\",\n    \"country\": \"US\",\n    \"phone\": \"2125551234\",\n    \"email\": \"ship@acme.example\",\n    \"is_residential\": false\n  },\n  \"to_address\": {\n    \"first_name\": \"Jane\",\n    \"last_name\": \"Smith\",\n    \"company\": \"\",\n    \"street1\": \"456 Oak Ave\",\n    \"street2\": \"\",\n    \"city\": \"Los Angeles\",\n    \"state\": \"CA\",\n    \"zip\": \"90001\",\n    \"country\": \"US\",\n    \"phone\": \"3105559876\",\n    \"email\": \"jane@example.com\",\n    \"is_residential\": true\n  },\n  \"parcel\": [\n    {\n      \"weight\": 2.5,\n      \"weight_unit\": \"lb\",\n      \"length\": 10,\n      \"width\": 8,\n      \"height\": 4,\n      \"dimension_unit\": \"in\",\n      \"package_type\": \"custom_package\",\n      \"package_count\": 1\n    }\n  ],\n  \"service_code\": \"usps_priority\",\n  \"carrier\": \"USPS\",\n  \"rate_amount\": 8.75,\n  \"service_options\": {\n    \"ship_date\": \"2026-07-15\",\n    \"verify_address\": true,\n    \"confirmation\": \"signature\",\n    \"insured_amount\": 100,\n    \"hazmat\": null\n  },\n  \"reference_1\": \"PO-123\",\n  \"reference_2\": \"INV-999\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Create a domestic (US) shipment and buy a label. Optional: service_options, reference_1/2, return_address."
          },
          "response": []
        },
        {
          "name": "Create purchase (international)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/purchases",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "purchases"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"from_address\": {\n    \"company\": \"Acme Inc\",\n    \"first_name\": \"Acme\",\n    \"last_name\": \"Shipping\",\n    \"street1\": \"417 Montgomery St\",\n    \"street2\": \"Suite 5\",\n    \"city\": \"San Francisco\",\n    \"state\": \"CA\",\n    \"zip\": \"94104\",\n    \"country\": \"US\",\n    \"phone\": \"4155551234\",\n    \"email\": \"ship@acme.example\"\n  },\n  \"to_address\": {\n    \"name\": \"Jean Tremblay\",\n    \"street1\": \"100 Rue Peel\",\n    \"city\": \"Montreal\",\n    \"state\": \"QC\",\n    \"zip\": \"H3C 2G7\",\n    \"country\": \"CA\",\n    \"phone\": \"5145559999\"\n  },\n  \"parcel\": [\n    {\n      \"weight\": 2.5,\n      \"length\": 10,\n      \"width\": 8,\n      \"height\": 4,\n      \"package_type\": \"custom_package\",\n      \"weight_unit\": \"lb\",\n      \"dimension_unit\": \"in\",\n      \"package_count\": 1\n    }\n  ],\n  \"service_code\": \"ups_worldwide_saver\",\n  \"carrier\": \"UPS\",\n  \"rate_amount\": 42.1,\n  \"service_options\": {\n    \"ship_date\": \"2026-07-15\",\n    \"verify_address\": true,\n    \"confirmation\": \"signature\",\n    \"insured_amount\": 100,\n    \"hazmat\": null\n  },\n  \"customs\": {\n    \"content_type\": \"merchandise\",\n    \"content_description\": \"Cotton t-shirts\",\n    \"items\": [\n      {\n        \"description\": \"T-shirt\",\n        \"quantity\": 2,\n        \"sku\": \"TS-1\",\n        \"unit_value\": 12.5,\n        \"unit_weight\": 0.4,\n        \"hs_tariff_number\": \"6109.10.0000\",\n        \"country_of_origin\": \"US\"\n      }\n    ]\n  },\n  \"reference_1\": \"PO-123\",\n  \"reference_2\": \"INV-999\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Create an international shipment. `customs` (with at least one item) is REQUIRED when to_address.country != US."
          },
          "response": []
        },
        {
          "name": "Purchase details",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/purchases/{{shipment_id}}",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "purchases",
                "{{shipment_id}}"
              ]
            }
          },
          "response": []
        },
        {
          "name": "Request return-payment",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/purchases/{{shipment_id}}/return-payment",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "purchases",
                "{{shipment_id}}",
                "return-payment"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "Tracking",
      "item": [
        {
          "name": "Track purchase",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/purchases/{{shipment_id}}/tracking",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "purchases",
                "{{shipment_id}}",
                "tracking"
              ]
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "Quotes",
      "item": [
        {
          "name": "Shop rates",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/quotes",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "quotes"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"from_address\": {\n    \"first_name\": \"John\",\n    \"last_name\": \"Doe\",\n    \"company\": \"Acme Inc\",\n    \"street1\": \"123 Main St\",\n    \"street2\": \"Suite 100\",\n    \"city\": \"New York\",\n    \"state\": \"NY\",\n    \"zip\": \"10001\",\n    \"country\": \"US\",\n    \"phone\": \"2125551234\",\n    \"email\": \"ship@acme.example\",\n    \"is_residential\": false\n  },\n  \"to_address\": {\n    \"first_name\": \"Jane\",\n    \"last_name\": \"Smith\",\n    \"company\": \"\",\n    \"street1\": \"456 Oak Ave\",\n    \"street2\": \"\",\n    \"city\": \"Los Angeles\",\n    \"state\": \"CA\",\n    \"zip\": \"90001\",\n    \"country\": \"US\",\n    \"phone\": \"3105559876\",\n    \"email\": \"jane@example.com\",\n    \"is_residential\": true\n  },\n  \"parcel\": [\n    {\n      \"weight\": 2.5,\n      \"weight_unit\": \"lb\",\n      \"length\": 10,\n      \"width\": 8,\n      \"height\": 4,\n      \"dimension_unit\": \"in\",\n      \"package_type\": \"custom_package\",\n      \"package_count\": 1\n    }\n  ],\n  \"service_options\": {\n    \"ship_date\": \"2026-07-15\",\n    \"verify_address\": true,\n    \"confirmation\": \"signature\",\n    \"insured_amount\": 100,\n    \"hazmat\": null\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "Places",
      "item": [
        {
          "name": "Validate address",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/places/verify",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "places",
                "verify"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"street1\": \"1600 Amphitheatre Parkway\",\n  \"street2\": \"Building 40\",\n  \"city\": \"Mountain View\",\n  \"state\": \"CA\",\n  \"zip\": \"94043\",\n  \"country\": \"US\",\n  \"carrier\": \"usps\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "List locations",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/places/locations",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "places",
                "locations"
              ],
              "query": [
                {
                  "key": "type",
                  "value": "0",
                  "disabled": true,
                  "description": "Filter by address role: 0 = From (sender), 1 = To (recipient). Omit for all."
                }
              ]
            }
          },
          "response": []
        },
        {
          "name": "Create location",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/places/locations",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "places",
                "locations"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"East Coast Warehouse\",\n  \"first_name\": \"Warehouse\",\n  \"last_name\": \"Manager\",\n  \"company\": \"Acme Inc\",\n  \"street1\": \"500 Industrial Ave\",\n  \"street2\": \"Building B\",\n  \"city\": \"Newark\",\n  \"state\": \"NJ\",\n  \"zip\": \"07102\",\n  \"country\": \"US\",\n  \"phone\": \"9735551234\",\n  \"email\": \"warehouse@partner.com\",\n  \"is_residential\": false,\n  \"type\": 0\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "Billing",
      "item": [
        {
          "name": "Check balance",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/billing/balance",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "billing",
                "balance"
              ]
            }
          },
          "response": []
        }
      ]
    }
  ],
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{access_token}}",
        "type": "string"
      }
    ]
  }
}