{
  "info": {
    "_postman_id": "8f4c2a9e-7b2f-4a3c-9b1f-2a3c4d5e6f70",
    "name": "APRO External Catalog API",
    "description": "Executable Postman collection for the External Catalog endpoints:\n\n- `GET /api/v1/external/product`\n- `GET /api/v1/external/product-category`\n- `GET /api/v1/external/spot`\n\n## Setup\n\n1. Open the collection's **Variables** tab.\n2. Set `apiKey` to your APRO API key.\n3. Set `locationShortCode` (or `locationId`) for the location you want to read.\n4. Hit **Send** on any request.\n\n## Filter syntax\n\nAll filter fields must be passed as `filter['<name>']=<value>` (bracketed) — plain `?<name>=<value>` is silently ignored and the request fails with `\"location not resolved\"`. Pagination (`skip`, `take`) is a plain query param.\n\nList filters are comma-separated, e.g. `filter['productNrs']=A-100,A-200`.\n\nDocs: https://docs.apro.at/en/apis/external-catalog/",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "apikey",
    "apikey": [
      { "key": "key", "value": "x-api-key", "type": "string" },
      { "key": "value", "value": "{{apiKey}}", "type": "string" },
      { "key": "in", "value": "header", "type": "string" }
    ]
  },
  "variable": [
    {
      "key": "baseUrl",
      "value": "https://my.apro.at",
      "type": "string",
      "description": "API host. Override for staging."
    },
    {
      "key": "apiKey",
      "value": "",
      "type": "string",
      "description": "Your APRO API key. Sent as the x-api-key header."
    },
    {
      "key": "locationShortCode",
      "value": "vienna-main",
      "type": "string",
      "description": "Short code of the location to read from. Mutually exclusive with locationId."
    },
    {
      "key": "locationId",
      "value": "",
      "type": "string",
      "description": "Numeric ID of the location. Alternative to locationShortCode."
    }
  ],
  "item": [
    {
      "name": "Products",
      "item": [
        {
          "name": "List products (basic)",
          "request": {
            "method": "GET",
            "header": [{ "key": "accept", "value": "application/json" }],
            "url": {
              "raw": "{{baseUrl}}/api/v1/external/product?filter['locationShortCode']={{locationShortCode}}&skip=0&take=50",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "external", "product"],
              "query": [
                { "key": "filter['locationShortCode']", "value": "{{locationShortCode}}" },
                { "key": "skip", "value": "0" },
                { "key": "take", "value": "50" }
              ]
            },
            "description": "First page of products at the configured location."
          },
          "response": []
        },
        {
          "name": "List products — full-text search",
          "request": {
            "method": "GET",
            "header": [{ "key": "accept", "value": "application/json" }],
            "url": {
              "raw": "{{baseUrl}}/api/v1/external/product?filter['locationShortCode']={{locationShortCode}}&filter['search']=schnitzel&take=20",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "external", "product"],
              "query": [
                { "key": "filter['locationShortCode']", "value": "{{locationShortCode}}" },
                { "key": "filter['search']", "value": "schnitzel", "description": "Matches name, externalName, productNr, GTIN and externalProductId." },
                { "key": "take", "value": "20" }
              ]
            },
            "description": "Free-text search across name, externalName, productNr, GTIN and externalProductId."
          },
          "response": []
        },
        {
          "name": "List products — by productNr",
          "request": {
            "method": "GET",
            "header": [{ "key": "accept", "value": "application/json" }],
            "url": {
              "raw": "{{baseUrl}}/api/v1/external/product?filter['locationShortCode']={{locationShortCode}}&filter['productNrs']=A-100,A-200",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "external", "product"],
              "query": [
                { "key": "filter['locationShortCode']", "value": "{{locationShortCode}}" },
                { "key": "filter['productNrs']", "value": "A-100,A-200", "description": "Comma-separated list of productNr values. These are the same identifiers passed back as `productNr` to the External Order API." }
              ]
            },
            "description": "Look up specific products by their productNr — the field the External Order API resolves orders against."
          },
          "response": []
        },
        {
          "name": "List products — visible only, by cashbox",
          "request": {
            "method": "GET",
            "header": [{ "key": "accept", "value": "application/json" }],
            "url": {
              "raw": "{{baseUrl}}/api/v1/external/product?filter['locationShortCode']={{locationShortCode}}&filter['cashboxId']=17&filter['isVisible']=true&take=100",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "external", "product"],
              "query": [
                { "key": "filter['locationShortCode']", "value": "{{locationShortCode}}" },
                { "key": "filter['cashboxId']", "value": "17", "description": "Restrict to one cashbox at the location." },
                { "key": "filter['isVisible']", "value": "true" },
                { "key": "take", "value": "100" }
              ]
            },
            "description": "Visible products on a single cashbox."
          },
          "response": []
        },
        {
          "name": "List products — by GTIN",
          "request": {
            "method": "GET",
            "header": [{ "key": "accept", "value": "application/json" }],
            "url": {
              "raw": "{{baseUrl}}/api/v1/external/product?filter['locationShortCode']={{locationShortCode}}&filter['gtins']=9001234567890",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "external", "product"],
              "query": [
                { "key": "filter['locationShortCode']", "value": "{{locationShortCode}}" },
                { "key": "filter['gtins']", "value": "9001234567890", "description": "Comma-separated list of GTINs / barcodes." }
              ]
            },
            "description": "Resolve products by GTIN — useful for scanner integrations."
          },
          "response": []
        },
        {
          "name": "List products — by external POS IDs",
          "request": {
            "method": "GET",
            "header": [{ "key": "accept", "value": "application/json" }],
            "url": {
              "raw": "{{baseUrl}}/api/v1/external/product?filter['locationShortCode']={{locationShortCode}}&filter['externalProductIds']=wiener-schnitzel,tafelspitz",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "external", "product"],
              "query": [
                { "key": "filter['locationShortCode']", "value": "{{locationShortCode}}" },
                { "key": "filter['externalProductIds']", "value": "wiener-schnitzel,tafelspitz", "description": "Comma-separated list of POS product IDs." }
              ]
            },
            "description": "Resolve products by their local POS product IDs (the `externalProductId` field on the DTO)."
          },
          "response": []
        }
      ],
      "description": "Read products. See https://docs.apro.at/en/apis/external-catalog/#products"
    },
    {
      "name": "Product categories",
      "item": [
        {
          "name": "List categories",
          "request": {
            "method": "GET",
            "header": [{ "key": "accept", "value": "application/json" }],
            "url": {
              "raw": "{{baseUrl}}/api/v1/external/product-category?filter['locationShortCode']={{locationShortCode}}&take=200",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "external", "product-category"],
              "query": [
                { "key": "filter['locationShortCode']", "value": "{{locationShortCode}}" },
                { "key": "take", "value": "200" }
              ]
            },
            "description": "All product categories (product groups) at the configured location."
          },
          "response": []
        },
        {
          "name": "List categories — by external POS IDs",
          "request": {
            "method": "GET",
            "header": [{ "key": "accept", "value": "application/json" }],
            "url": {
              "raw": "{{baseUrl}}/api/v1/external/product-category?filter['locationShortCode']={{locationShortCode}}&filter['externalIds']=mains,drinks-alcoholic",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "external", "product-category"],
              "query": [
                { "key": "filter['locationShortCode']", "value": "{{locationShortCode}}" },
                { "key": "filter['externalIds']", "value": "mains,drinks-alcoholic", "description": "Comma-separated POS category IDs." }
              ]
            },
            "description": "Resolve categories by their local POS category IDs (matches `productGroupExternalIds[]` on products)."
          },
          "response": []
        },
        {
          "name": "List categories — search",
          "request": {
            "method": "GET",
            "header": [{ "key": "accept", "value": "application/json" }],
            "url": {
              "raw": "{{baseUrl}}/api/v1/external/product-category?filter['locationShortCode']={{locationShortCode}}&filter['search']=getr",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "external", "product-category"],
              "query": [
                { "key": "filter['locationShortCode']", "value": "{{locationShortCode}}" },
                { "key": "filter['search']", "value": "getr", "description": "Matches name, externalName, externalId." }
              ]
            },
            "description": "Free-text search across category names."
          },
          "response": []
        }
      ],
      "description": "Read product categories. See https://docs.apro.at/en/apis/external-catalog/#product-categories"
    },
    {
      "name": "Spots",
      "item": [
        {
          "name": "List spots (basic)",
          "request": {
            "method": "GET",
            "header": [{ "key": "accept", "value": "application/json" }],
            "url": {
              "raw": "{{baseUrl}}/api/v1/external/spot?filter['locationShortCode']={{locationShortCode}}&take=100",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "external", "spot"],
              "query": [
                { "key": "filter['locationShortCode']", "value": "{{locationShortCode}}" },
                { "key": "take", "value": "100" }
              ]
            },
            "description": "All spots at the configured location."
          },
          "response": []
        },
        {
          "name": "List spots — tables, visible in app",
          "request": {
            "method": "GET",
            "header": [{ "key": "accept", "value": "application/json" }],
            "url": {
              "raw": "{{baseUrl}}/api/v1/external/spot?filter['locationShortCode']={{locationShortCode}}&filter['type']=Table&filter['visibleInApp']=true",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "external", "spot"],
              "query": [
                { "key": "filter['locationShortCode']", "value": "{{locationShortCode}}" },
                { "key": "filter['type']", "value": "Table", "description": "Spot / Table / Room / Pickup / Delivery / …" },
                { "key": "filter['visibleInApp']", "value": "true" }
              ]
            },
            "description": "Visible tables — typical input for an in-house ordering app."
          },
          "response": []
        },
        {
          "name": "List spots — by area",
          "request": {
            "method": "GET",
            "header": [{ "key": "accept", "value": "application/json" }],
            "url": {
              "raw": "{{baseUrl}}/api/v1/external/spot?filter['locationShortCode']={{locationShortCode}}&filter['areaId']=11",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "external", "spot"],
              "query": [
                { "key": "filter['locationShortCode']", "value": "{{locationShortCode}}" },
                { "key": "filter['areaId']", "value": "11", "description": "Restrict to one area / room." }
              ]
            },
            "description": "All spots inside one area (e.g. Gastgarten / room 3)."
          },
          "response": []
        },
        {
          "name": "List spots — by external POS IDs",
          "request": {
            "method": "GET",
            "header": [{ "key": "accept", "value": "application/json" }],
            "url": {
              "raw": "{{baseUrl}}/api/v1/external/spot?filter['locationShortCode']={{locationShortCode}}&filter['externalSpotIds']=table-01,table-02",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "external", "spot"],
              "query": [
                { "key": "filter['locationShortCode']", "value": "{{locationShortCode}}" },
                { "key": "filter['externalSpotIds']", "value": "table-01,table-02", "description": "Comma-separated POS spot IDs." }
              ]
            },
            "description": "Resolve specific spots by their local POS spot IDs."
          },
          "response": []
        },
        {
          "name": "List spots — search by QR code",
          "request": {
            "method": "GET",
            "header": [{ "key": "accept", "value": "application/json" }],
            "url": {
              "raw": "{{baseUrl}}/api/v1/external/spot?filter['locationShortCode']={{locationShortCode}}&filter['search']=QR-01",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "external", "spot"],
              "query": [
                { "key": "filter['locationShortCode']", "value": "{{locationShortCode}}" },
                { "key": "filter['search']", "value": "QR-01", "description": "Matches name, alternativeName, externalSpotId and qrCode." }
              ]
            },
            "description": "Free-text search — includes QR code payload."
          },
          "response": []
        }
      ],
      "description": "Read spots. See https://docs.apro.at/en/apis/external-catalog/#spots"
    }
  ],
  "event": [
    {
      "listen": "test",
      "script": {
        "type": "text/javascript",
        "exec": [
          "// Generic response shape check for the External Catalog endpoints.",
          "pm.test('status is 2xx', () => pm.response.to.be.success);",
          "",
          "pm.test('response is paged envelope', () => {",
          "    const body = pm.response.json();",
          "    pm.expect(body).to.have.property('page');",
          "    pm.expect(body).to.have.property('data');",
          "    pm.expect(body.page).to.have.property('offset');",
          "    pm.expect(body.page).to.have.property('limit');",
          "    pm.expect(body.page).to.have.property('total');",
          "    pm.expect(body.data).to.be.an('array');",
          "});"
        ]
      }
    }
  ]
}
