{
  "openapi": "3.1.0",
  "info": {
    "title": "SOH Stage Lights – katalog techniky k pronájmu",
    "version": "2026-10-13",
    "summary": "Veřejné katalogové API půjčovny SOH v Praze 4 (jen čtení).",
    "description": "Katalog zvukové a světelné techniky k pronájmu na stagelights.cz. API jen čte: hledání a výpis techniky, detail produktu, dohledání podle názvů a ID. Rezervace ani poptávky přes API nevznikají – do košíku vede odkaz `https://stagelights.cz/?cart=ID:KS,ID:KS&od=RRRR-MM-DD&do=RRRR-MM-DD` (ID bez mezer a interpunkce) a poptávku odesílá zákazník sám. Ceny jsou za pronájem 1 kusu na 1–2 dny (48 h) včetně DPH; od 3. dne se platí 50 % ceny za den, od 6 dnů sleva 20 %, od 8 dnů 30 %, od 12 dnů 40 % (viz llms.txt). Pole `prWeb` je cena, kterou web zobrazuje; `pr` je základní cena v databázi před úpravou webu. Dostupnost a rezervaci vždy potvrzuje půjčovna. Každá akce je dostupná i jako `/catalog-api.php?action=<akce>` (by-ids = by_ids); obě adresy vracejí totéž. Limit: 10 požadavků za sekundu na IP (nárazově 60), jinak HTTP 429.",
    "contact": {
      "name": "SOH Sound & Lights s.r.o. – půjčovna",
      "email": "pronajem@soh.cz",
      "url": "https://stagelights.cz/kontakt"
    }
  },
  "externalDocs": {
    "description": "Pravidla pro AI, ceník a formát odkazu do košíku",
    "url": "https://stagelights.cz/llms.txt"
  },
  "servers": [
    { "url": "https://stagelights.cz", "description": "stagelights.cz (čeština; ?lang=en|de|es přepne jazyk katalogu)" }
  ],
  "tags": [
    { "name": "katalog", "description": "Čtení katalogu techniky" }
  ],
  "paths": {
    "/api/catalog/status": {
      "get": {
        "tags": ["katalog"],
        "operationId": "getStatus",
        "summary": "Stav katalogu (počet produktů)",
        "responses": {
          "200": {
            "description": "Stav databáze katalogu",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StatusResponse" } } }
          },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/api/catalog/bootstrap": {
      "get": {
        "tags": ["katalog"],
        "operationId": "getBootstrap",
        "summary": "Kategorie, nastavení katalogu a první stránka výpisu",
        "parameters": [
          { "$ref": "#/components/parameters/lang" },
          { "name": "category", "in": "query", "description": "ID kategorie (z pole categories); výchozí všechny", "schema": { "type": "string" } },
          { "name": "limit", "in": "query", "description": "Počet položek první stránky", "schema": { "type": "integer", "minimum": 1, "maximum": 100 } }
        ],
        "responses": {
          "200": {
            "description": "Kategorie a první stránka",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BootstrapResponse" } } }
          },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/api/catalog/list": {
      "get": {
        "tags": ["katalog"],
        "operationId": "listProducts",
        "summary": "Hledání a výpis techniky s filtry",
        "description": "Fulltext `q` hledá v názvu, ID, popisu, štítcích a parametrech. Filtry (fazety) berou hodnoty přesně podle pole `facets` v odpovědi; víc hodnot oddělte čárkou.",
        "parameters": [
          { "$ref": "#/components/parameters/lang" },
          { "name": "q", "in": "query", "description": "Hledaný text, např. „LED PAR“ nebo „reprobox 12“", "schema": { "type": "string", "maxLength": 200 } },
          { "name": "category", "in": "query", "description": "ID kategorie, výchozí `all`", "schema": { "type": "string", "default": "all" } },
          { "name": "sort", "in": "query", "schema": { "type": "string", "enum": ["default", "price", "name", "manufacturer", "power", "weight", "dmx"], "default": "default" } },
          { "name": "dir", "in": "query", "schema": { "type": "string", "enum": ["asc", "desc"], "default": "asc" } },
          { "name": "offset", "in": "query", "schema": { "type": "integer", "minimum": 0, "default": 0 } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 24 } },
          { "name": "view", "in": "query", "description": "`card` = odlehčené položky bez plného popisu (fullDe) a hledacího textu", "schema": { "type": "string", "enum": ["card"] } },
          { "name": "domain", "in": "query", "description": "Typ techniky (hodnoty z facets.domain, např. zvuk, svetla, konstrukce, dmx)", "schema": { "type": "string" } },
          { "name": "manufacturer", "in": "query", "schema": { "type": "string" } },
          { "name": "lightColor", "in": "query", "schema": { "type": "string" } },
          { "name": "lightSource", "in": "query", "schema": { "type": "string" } },
          { "name": "beamAngle", "in": "query", "schema": { "type": "string" } },
          { "name": "ipRating", "in": "query", "schema": { "type": "string" } },
          { "name": "speakerSize", "in": "query", "schema": { "type": "string" } },
          { "name": "dmxChannels", "in": "query", "description": "Počet DMX kanálů, např. `8ch`", "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Stránka výpisu, fazety a počty v kategoriích",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListResponse" } } }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "429": { "$ref": "#/components/responses/TooManyRequests" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/api/catalog/product": {
      "get": {
        "tags": ["katalog"],
        "operationId": "getProduct",
        "summary": "Detail produktu podle slugu nebo ID",
        "parameters": [
          { "$ref": "#/components/parameters/lang" },
          { "name": "slug", "in": "query", "description": "Slug z adresy produktu (/produkt/<slug>)", "schema": { "type": "string" } },
          { "name": "id", "in": "query", "description": "ID produktu (pole id)", "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Produkt a až 8 souvisejících položek",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProductResponse" } } }
          },
          "404": { "$ref": "#/components/responses/NotFound" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/api/catalog/lookup": {
      "get": {
        "tags": ["katalog"],
        "operationId": "lookupProducts",
        "summary": "Dohledání produktů podle názvů (tolerantní k velikosti písmen a interpunkci)",
        "parameters": [
          { "$ref": "#/components/parameters/lang" },
          { "name": "needles", "in": "query", "description": "Hledané názvy nebo ID: JSON pole nebo seznam oddělený čárkou", "schema": { "type": "string" } },
          { "name": "q", "in": "query", "description": "Jeden hledaný název (místo needles)", "schema": { "type": "string" } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 50, "default": 20 } }
        ],
        "responses": {
          "200": {
            "description": "Nalezené produkty a mapa hledaný výraz → ID",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LookupResponse" } } }
          },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/api/catalog/by-ids": {
      "get": {
        "tags": ["katalog"],
        "operationId": "getProductsByIds",
        "summary": "Produkty podle ID (i v kompaktním tvaru bez mezer a interpunkce)",
        "parameters": [
          { "$ref": "#/components/parameters/lang" },
          { "name": "ids", "in": "query", "required": true, "description": "ID oddělená čárkou, např. `LEDFLATPAR,RCFART912A`", "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Nalezené produkty (neznámá ID se vynechají)",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ItemsResponse" } } }
          },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    }
  },
  "components": {
    "parameters": {
      "lang": {
        "name": "lang",
        "in": "query",
        "description": "Jazyk katalogu; výchozí čeština",
        "schema": { "type": "string", "enum": ["cs", "en", "de", "es"] }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Neplatný požadavek (neznámá akce, neplatné UTF-8)",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "NotFound": {
        "description": "Produkt nebyl nalezen",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "TooManyRequests": {
        "description": "Překročený limit požadavků (odpověď serveru nginx, ne JSON)",
        "content": { "text/html": { "schema": { "type": "string" } } }
      },
      "ServerError": {
        "description": "Chyba serveru",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": ["success", "error"],
        "properties": {
          "success": { "const": false },
          "error": { "type": "string" }
        }
      },
      "StatusResponse": {
        "type": "object",
        "required": ["success", "products"],
        "properties": {
          "success": { "const": true },
          "products": { "type": "integer", "description": "Počet produktů v katalogu jazyka" },
          "source": { "type": "string" },
          "db": { "type": "string" }
        }
      },
      "Category": {
        "type": "object",
        "required": ["id", "label"],
        "properties": {
          "id": { "type": "string", "description": "`all` = všechny kategorie" },
          "label": { "type": "string" },
          "icon": { "type": "string" }
        }
      },
      "FacetValue": {
        "type": "object",
        "required": ["value", "count"],
        "properties": {
          "value": { "type": "string" },
          "label": { "type": "string", "description": "Jen u facets.domain" },
          "count": { "type": "integer" }
        }
      },
      "Facets": {
        "type": "object",
        "additionalProperties": { "type": "array", "items": { "$ref": "#/components/schemas/FacetValue" } },
        "properties": {
          "domain": { "type": "array", "items": { "$ref": "#/components/schemas/FacetValue" } },
          "manufacturer": { "type": "array", "items": { "$ref": "#/components/schemas/FacetValue" } },
          "lightColor": { "type": "array", "items": { "$ref": "#/components/schemas/FacetValue" } },
          "lightSource": { "type": "array", "items": { "$ref": "#/components/schemas/FacetValue" } },
          "beamAngle": { "type": "array", "items": { "$ref": "#/components/schemas/FacetValue" } },
          "ipRating": { "type": "array", "items": { "$ref": "#/components/schemas/FacetValue" } },
          "speakerSize": { "type": "array", "items": { "$ref": "#/components/schemas/FacetValue" } },
          "dmxChannels": { "type": "array", "items": { "$ref": "#/components/schemas/FacetValue" } }
        }
      },
      "DmxMode": {
        "type": "object",
        "required": ["name", "channels"],
        "properties": {
          "name": { "type": "string", "description": "Název DMX módu doslova z GDTF" },
          "channels": { "type": "integer", "minimum": 0 },
          "default": { "const": true, "description": "Jen u výchozího módu" },
          "breaks": {
            "type": "array",
            "items": { "type": "object", "properties": { "break": { "type": "integer" }, "channels": { "type": "integer" } } }
          },
          "description": { "type": "string" },
          "grandMA2_url": { "type": "string", "description": "Knihovna grandMA2 pro tento mód (relativní URL)" }
        }
      },
      "Product": {
        "type": "object",
        "required": ["id", "n", "url"],
        "properties": {
          "id": { "type": "string", "description": "Stálé ID produktu; do odkazu ?cart= bez mezer a interpunkce" },
          "n": { "type": "string", "description": "Zobrazovaný název" },
          "rawName": { "type": "string" },
          "fullName": { "type": "string" },
          "slug": { "type": "string" },
          "url": { "type": "string", "description": "Relativní adresa stránky produktu" },
          "cat": { "type": "string", "description": "ID kategorie" },
          "i": { "type": "string", "description": "Ikona (emoji)" },
          "img": { "type": "string", "description": "Relativní URL obrázku" },
          "imgW": { "type": "integer" },
          "imgH": { "type": "integer" },
          "pr": { "type": ["number", "null"], "description": "Základní cena v databázi (vč. DPH, 1 kus na 1–2 dny) před úpravou webu" },
          "prWeb": { "type": ["number", "null"], "description": "Cena, kterou web zobrazuje (na stagelights.cz po slevě 10 % pro online objednávku), 1 kus na 1–2 dny vč. DPH; null = cena skrytá nebo na dotaz" },
          "sp": { "type": "array", "items": { "type": "string" }, "description": "Štítky" },
          "de": { "type": "string", "description": "Krátký popis" },
          "fullDe": { "type": "string", "description": "Plný popis (ve view=card chybí)" },
          "dt": { "type": "object", "additionalProperties": { "type": "string" }, "description": "Parametry (klíče v jazyce katalogu)" },
          "ai": { "type": "string", "description": "Podklad pro AI vizualizaci" },
          "manualUrl": { "type": "string" },
          "videoUrl": { "type": "string" },
          "fixtureGdtf": { "type": "string" },
          "fixtureGdtfShare": { "type": "string" },
          "fixtureOfl": { "type": "string" },
          "fixtureTxt": { "type": "string" },
          "fixtureTitan": { "type": "string" },
          "fixtureMa2": { "type": ["object", "array"], "description": "Starý formát knihoven grandMA2 {mód: url}; nový je v modes" },
          "modes": { "type": ["array", "null"], "items": { "$ref": "#/components/schemas/DmxMode" }, "description": "DMX módy v pořadí z GDTF; null = produkt bez údaje o módech" },
          "gdtfRid": { "type": "string" },
          "manufacturer": { "type": "string" },
          "lightColor": { "type": "string" },
          "beamAngle": { "type": "string" },
          "lightSource": { "type": "string" },
          "ipRating": { "type": "string" },
          "speakerSizes": { "type": "array", "items": { "type": "string" } },
          "searchText": { "type": "string" },
          "dmxModes": { "type": "array", "items": { "type": "integer" }, "description": "Počty DMX kanálů (pro filtr)" },
          "stock": { "type": "integer", "description": "Počet kusů ve skladu podle katalogu (dostupnost v termínu potvrzuje půjčovna)" },
          "powerWatts": { "type": "integer" },
          "updatedAt": { "type": "string", "description": "Datum poslední změny obsahu (ISO 8601)" },
          "lite": { "const": 1, "description": "Jen ve view=card" }
        }
      },
      "ProductList": {
        "type": "object",
        "required": ["items", "total"],
        "properties": {
          "items": { "type": "array", "items": { "$ref": "#/components/schemas/Product" } },
          "total": { "type": "integer" },
          "offset": { "type": "integer" },
          "limit": { "type": "integer" },
          "remaining": { "type": "integer" },
          "category": { "type": "string" },
          "sort": { "type": "string" },
          "dir": { "type": "string" },
          "q": { "type": "string" },
          "filters": { "type": ["object", "array"] }
        }
      },
      "ListResponse": {
        "type": "object",
        "required": ["success", "list"],
        "properties": {
          "success": { "const": true },
          "list": { "$ref": "#/components/schemas/ProductList" },
          "facets": { "$ref": "#/components/schemas/Facets" },
          "category_counts": { "type": "object", "additionalProperties": { "type": "integer" } },
          "catalog": {
            "type": "object",
            "properties": { "product_url_prefix": { "type": "string" }, "page_size": { "type": "integer" } }
          }
        }
      },
      "BootstrapResponse": {
        "type": "object",
        "required": ["success", "categories", "list"],
        "properties": {
          "success": { "const": true },
          "categories": { "type": "array", "items": { "$ref": "#/components/schemas/Category" } },
          "category_gradients": { "type": ["object", "array"] },
          "category_counts": { "type": "object", "additionalProperties": { "type": "integer" } },
          "settings": { "type": ["object", "array"] },
          "catalog_info": { "type": ["object", "array"] },
          "catalog": {
            "type": "object",
            "properties": {
              "initial_category": { "type": "string" },
              "page_size": { "type": "integer" },
              "product_url_prefix": { "type": "string" }
            }
          },
          "list": { "$ref": "#/components/schemas/ProductList" },
          "facets": { "$ref": "#/components/schemas/Facets" }
        }
      },
      "ProductResponse": {
        "type": "object",
        "required": ["success", "product"],
        "properties": {
          "success": { "const": true },
          "product": { "$ref": "#/components/schemas/Product" },
          "related": { "type": "array", "items": { "$ref": "#/components/schemas/Product" } }
        }
      },
      "LookupResponse": {
        "type": "object",
        "required": ["success", "items", "matches"],
        "properties": {
          "success": { "const": true },
          "items": { "type": "array", "items": { "$ref": "#/components/schemas/Product" } },
          "matches": { "type": "object", "additionalProperties": { "type": "string" }, "description": "Hledaný výraz → ID nalezeného produktu" }
        }
      },
      "ItemsResponse": {
        "type": "object",
        "required": ["success", "items"],
        "properties": {
          "success": { "const": true },
          "items": { "type": "array", "items": { "$ref": "#/components/schemas/Product" } }
        }
      }
    }
  }
}
