{
  "info": {
    "name": "FS Logistik Partner API",
    "description": "Create shipments in the FS Logistik order system and follow their status.\n\nDocumentation: https://docs.fslogistik.com\n\nThis collection is preloaded with the shared SANDBOX account. Nothing here is dispatched or invoiced.\n\nSetup:\n1. Run \"Get an API token\". It stores the token in the `apiKey` variable; every other request uses it.\n2. Change `reference` to something of your own before creating a shipment — the sandbox account is shared.\n3. For production, switch `baseUrl` to https://admin.fslogistik.com/api/v1 and set `email` / `password` to the account FS Logistik opens for you.\n\nThe sandbox is shared and cleared periodically: use made-up names and addresses, never real customer data.\n\nGenerated from openapi.json — do not edit by hand.",
    "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://test-admin.sendpakke.nu/api/v1",
      "type": "string"
    },
    {
      "key": "email",
      "value": "sandbox@fslogistik.com",
      "type": "string"
    },
    {
      "key": "password",
      "value": "Sandbox-2026!",
      "type": "string"
    },
    {
      "key": "apiKey",
      "value": "",
      "type": "string"
    },
    {
      "key": "reference",
      "value": "REF-889271",
      "type": "string"
    }
  ],
  "item": [
    {
      "name": "Get an API token",
      "request": {
        "auth": {
          "type": "noauth"
        },
        "method": "POST",
        "header": [
          {
            "key": "Content-Type",
            "value": "application/json"
          },
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "url": {
          "raw": "{{baseUrl}}/token",
          "host": [
            "{{baseUrl}}"
          ],
          "path": [
            "token"
          ]
        },
        "description": "Exchanges the account's panel credentials for a long-lived API token. Run this once and store the token; the password is never sent again. Wrong credentials return 401. After five failed attempts in a minute the endpoint returns 429.",
        "body": {
          "mode": "raw",
          "options": {
            "raw": {
              "language": "json"
            }
          },
          "raw": "{\n  \"email\": \"{{email}}\",\n  \"password\": \"{{password}}\",\n  \"name\": \"Partner integration\"\n}"
        }
      },
      "response": [
        {
          "name": "201 Token created",
          "originalRequest": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/token",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "token"
              ]
            }
          },
          "code": 201,
          "status": "Token created",
          "header": [
            {
              "key": "Content-Type",
              "value": "application/json"
            }
          ],
          "body": "{\n  \"token\": \"sk_live_9f2c41a7e8b34d05a6c1e7fbd9204e83\",\n  \"token_type\": \"Bearer\",\n  \"account\": \"Your Company A/S\",\n  \"created_at\": \"2026-08-27T14:02:11+02:00\"\n}"
        },
        {
          "name": "401 Invalid credentials",
          "originalRequest": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/token",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "token"
              ]
            }
          },
          "code": 401,
          "status": "Invalid credentials",
          "header": [
            {
              "key": "Content-Type",
              "value": "application/json"
            }
          ],
          "body": "{\n  \"success\": false,\n  \"message\": \"Invalid credentials.\"\n}"
        },
        {
          "name": "403 Account cannot use the partner API",
          "originalRequest": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/token",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "token"
              ]
            }
          },
          "code": 403,
          "status": "Account cannot use the partner API",
          "header": [
            {
              "key": "Content-Type",
              "value": "application/json"
            }
          ],
          "body": "{\n  \"success\": false,\n  \"message\": \"This account cannot be used with the partner API.\"\n}"
        }
      ],
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "const body = pm.response.json();",
              "if (body.token) {",
              "    pm.collectionVariables.set('apiKey', body.token);",
              "    console.log('API token stored in the apiKey variable.');",
              "}"
            ]
          }
        }
      ]
    },
    {
      "name": "Create a shipment",
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "Content-Type",
            "value": "application/json"
          },
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "url": {
          "raw": "{{baseUrl}}/shipments",
          "host": [
            "{{baseUrl}}"
          ],
          "path": [
            "shipments"
          ]
        },
        "description": "Registers a shipment on your account and returns the FS Logistik order number. No pricing fields are accepted; any that are sent are ignored. The reference is the idempotency key: sending the same reference twice returns the existing shipment with 200 instead of creating a duplicate, so retrying after a timeout is safe.",
        "body": {
          "mode": "raw",
          "options": {
            "raw": {
              "language": "json"
            }
          },
          "raw": "{\n  \"reference\": \"REF-889271\",\n  \"order_type\": \"package\",\n  \"content_description\": \"Textile samples\",\n  \"sender\": {\n    \"name\": \"Atlas Tekstil A.S.\",\n    \"phone\": \"+90 212 555 0134\",\n    \"email\": \"export@atlastekstil.com\",\n    \"address\": {\n      \"street\": \"Mahmutbey Mah. Tasocagi Cad. No 12\",\n      \"city\": \"Istanbul\",\n      \"postal_code\": \"34218\",\n      \"country_code\": \"TR\"\n    }\n  },\n  \"receiver\": {\n    \"name\": \"Lise Andersen\",\n    \"phone\": \"+45 26 13 42 16\",\n    \"email\": \"lise.andersen@example.dk\",\n    \"address\": {\n      \"street\": \"Nyholms Alle 30 B\",\n      \"city\": \"Rodovre\",\n      \"postal_code\": \"2610\",\n      \"country_code\": \"DK\"\n    }\n  },\n  \"packages\": [\n    {\n      \"quantity\": 1,\n      \"weight_kg\": 2.4,\n      \"length_cm\": 40,\n      \"width_cm\": 30,\n      \"height_cm\": 20\n    }\n  ]\n}"
        }
      },
      "response": [
        {
          "name": "200 Reference already used — the existing shipment is returned",
          "originalRequest": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/shipments",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "shipments"
              ]
            }
          },
          "code": 200,
          "status": "Reference already used — the existing shipment is returned",
          "header": [
            {
              "key": "Content-Type",
              "value": "application/json"
            }
          ],
          "body": "{\n  \"reference\": \"REF-889271\",\n  \"order_number\": \"20260827004\",\n  \"status\": \"pending\",\n  \"created_at\": \"2026-08-27T14:12:08+02:00\"\n}"
        },
        {
          "name": "201 Shipment created",
          "originalRequest": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/shipments",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "shipments"
              ]
            }
          },
          "code": 201,
          "status": "Shipment created",
          "header": [
            {
              "key": "Content-Type",
              "value": "application/json"
            }
          ],
          "body": "{\n  \"reference\": \"REF-889271\",\n  \"order_number\": \"20260827004\",\n  \"status\": \"pending\",\n  \"created_at\": \"2026-08-27T14:12:08+02:00\"\n}"
        },
        {
          "name": "422 Validation failed",
          "originalRequest": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/shipments",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "shipments"
              ]
            }
          },
          "code": 422,
          "status": "Validation failed",
          "header": [
            {
              "key": "Content-Type",
              "value": "application/json"
            }
          ],
          "body": "{\n  \"success\": false,\n  \"message\": \"Validation failed\",\n  \"errors\": {\n    \"packages.0.weight_kg\": [\n      \"The weight must not be greater than 30.\"\n    ]\n  }\n}"
        }
      ]
    },
    {
      "name": "Track a shipment",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "url": {
          "raw": "{{baseUrl}}/shipments/track/{{reference}}",
          "host": [
            "{{baseUrl}}"
          ],
          "path": [
            "shipments",
            "track",
            "{{reference}}"
          ]
        },
        "description": "Returns the current status of one shipment and how it got there. Only shipments created by your own token are visible; anything else returns 404. carrier and tracking_number are null until the shipment is handed to a carrier. The response carries no prices, no invoice data, and no billing details."
      },
      "response": [
        {
          "name": "200 Shipment status",
          "originalRequest": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/shipments/track/{{reference}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "shipments",
                "track",
                "{{reference}}"
              ]
            }
          },
          "code": 200,
          "status": "Shipment status",
          "header": [
            {
              "key": "Content-Type",
              "value": "application/json"
            }
          ],
          "body": "{\n  \"reference\": \"REF-889271\",\n  \"order_number\": \"20260827004\",\n  \"status\": \"shipped\",\n  \"status_label\": \"Shipped\",\n  \"carrier\": \"ups\",\n  \"tracking_number\": \"1ZK919J46899000001\",\n  \"carrier_status\": \"In Transit to Destination\",\n  \"carrier_status_at\": \"2026-08-29T09:41:55+02:00\",\n  \"updated_at\": \"2026-08-29T09:44:02+02:00\",\n  \"history\": [\n    {\n      \"status\": \"pending\",\n      \"occurred_at\": \"2026-08-27T14:12:08+02:00\"\n    },\n    {\n      \"status\": \"processing\",\n      \"occurred_at\": \"2026-08-28T08:30:11+02:00\"\n    },\n    {\n      \"status\": \"shipped\",\n      \"occurred_at\": \"2026-08-29T09:41:55+02:00\"\n    }\n  ]\n}"
        },
        {
          "name": "404 Not found on this account",
          "originalRequest": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/shipments/track/{{reference}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "shipments",
                "track",
                "{{reference}}"
              ]
            }
          },
          "code": 404,
          "status": "Not found on this account",
          "header": [
            {
              "key": "Content-Type",
              "value": "application/json"
            }
          ],
          "body": "{\n  \"success\": false,\n  \"message\": \"No shipment with that reference on this account.\"\n}"
        }
      ]
    }
  ]
}
