{
  "openapi": "3.1.0",
  "info": {
    "title": "Which Sensor Produkt-API",
    "version": "1.0.0",
    "description": "Lesender Zugriff auf das Sortiment von Which Sensor, einem herstellerunabhängigen B2B-Shop für Industriesensoren: Volltextsuche mit Facetten und Produktdetails mit technischen Daten und Listenpreisen (netto, EUR). Ohne Authentifizierung.",
    "contact": {
      "name": "Which Sensor",
      "url": "https://www.whichsensor.com/de/kontakt"
    }
  },
  "servers": [
    {
      "url": "https://www.whichsensor.com"
    }
  ],
  "externalDocs": {
    "url": "https://www.whichsensor.com/de/docs/api"
  },
  "security": [],
  "paths": {
    "/api/products": {
      "get": {
        "operationId": "searchProducts",
        "summary": "Produkte suchen",
        "description": "Volltextsuche über das aktive Sortiment. Die Antwort enthält neben den Treffern die Facetten (`filter_options`) der Treffermenge; deren `key`-Werte sind die Filterschlüssel für `filters`.",
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "description": "Suchbegriff, z. B. eine Typbezeichnung, Artikelnummer oder „induktiver Sensor M12“.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "filters",
            "in": "query",
            "description": "JSON-Array von Filtern, URL-kodiert. Werte einer Auswahl-Facette als `{\"value\": \"<key>\"}`, Zahlenbereiche als `{\"min\": 10, \"max\": 50}`. Beispiel: `[{\"key\":\"category\",\"values\":[{\"value\":\"pressure_sensor\"}]}]`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Sortierschlüssel aus `sorting_options[].key` einer vorherigen Antwort.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort-order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Treffer pro Seite, höchstens 50.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 48
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          },
          {
            "name": "lang",
            "in": "query",
            "description": "Sprache der Bezeichnungen und Facetten.",
            "schema": {
              "type": "string",
              "enum": [
                "de",
                "en"
              ],
              "default": "de"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Treffer und Facetten.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "query": {
                      "type": "string"
                    },
                    "total_results": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "offset": {
                      "type": "integer"
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "integer",
                            "description": "Produkt-ID für GET /api/products/{id}."
                          },
                          "name": {
                            "type": "string"
                          },
                          "sku": {
                            "type": "string",
                            "description": "Artikelnummer bei Which Sensor."
                          },
                          "manufacturer_pid": {
                            "type": "string",
                            "description": "Typbezeichnung des Herstellers."
                          },
                          "manufacturer_name": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "image": {
                            "type": "string"
                          },
                          "price": {
                            "type": "number",
                            "description": "Listenpreis netto in EUR, falls vorhanden."
                          },
                          "categories": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "facts": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "description": "Ein technisches Merkmal des Produkts.",
                              "properties": {
                                "key": {
                                  "type": "string",
                                  "description": "Merkmalsschlüssel, z. B. eine ECLASS-ID."
                                },
                                "name": {
                                  "type": "string",
                                  "description": "Anzeigename in der angefragten Sprache."
                                },
                                "text_value": {
                                  "type": "string"
                                },
                                "numeric_value": {
                                  "type": "number"
                                },
                                "unit": {
                                  "type": "string"
                                },
                                "section": {
                                  "type": "string"
                                },
                                "section_key": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key",
                                "name"
                              ]
                            }
                          }
                        },
                        "required": [
                          "id",
                          "name"
                        ]
                      }
                    },
                    "filter_options": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "description": "Eine Facette der aktuellen Treffermenge. `key` ist der Schlüssel für den Parameter `filters`.",
                        "properties": {
                          "key": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "filter_type": {
                            "type": "string",
                            "enum": [
                              "COLLECTION",
                              "SINGLE_NUMERIC",
                              "RANGE_PAIR"
                            ]
                          },
                          "values": {
                            "type": "array",
                            "description": "Wählbare Werte einer COLLECTION-Facette.",
                            "items": {
                              "type": "object",
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "count": {
                                  "type": "integer"
                                }
                              }
                            }
                          },
                          "min": {
                            "type": "number"
                          },
                          "max": {
                            "type": "number"
                          },
                          "unit": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "key",
                          "name",
                          "filter_type"
                        ]
                      }
                    },
                    "sorting_options": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "key": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "sort": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  },
                  "required": [
                    "total_results",
                    "limit",
                    "offset",
                    "results",
                    "filter_options"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Limit erreicht: höchstens 30 Anfragen pro Minute und 1500 Produkte pro Tag je Absender (eine Suche zählt mit ihrem `limit`). `Retry-After` nennt die Wartezeit in Sekunden.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "503": {
            "description": "Die Suche ist vorübergehend nicht erreichbar.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/products/{id}": {
      "get": {
        "operationId": "getProduct",
        "summary": "Produktdetails abrufen",
        "description": "Ein Produkt mit allen technischen Merkmalen, Bildern, Listenpreis und Mengenrabattstaffel. Ohne Anmeldung gilt der Listenpreis; kundenspezifische Rabatte erscheinen nur in einer angemeldeten Browser-Sitzung.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "lang",
            "in": "query",
            "description": "Sprache der Bezeichnungen und Facetten.",
            "schema": {
              "type": "string",
              "enum": [
                "de",
                "en"
              ],
              "default": "de"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Das Produkt.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer",
                          "description": "Produkt-ID für GET /api/products/{id}."
                        },
                        "name": {
                          "type": "string"
                        },
                        "sku": {
                          "type": "string",
                          "description": "Artikelnummer bei Which Sensor."
                        },
                        "manufacturer_pid": {
                          "type": "string",
                          "description": "Typbezeichnung des Herstellers."
                        },
                        "manufacturer_name": {
                          "type": "string"
                        },
                        "description": {
                          "type": "string"
                        },
                        "image": {
                          "type": "string"
                        },
                        "price": {
                          "type": "number",
                          "description": "Listenpreis netto in EUR, falls vorhanden."
                        },
                        "categories": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "facts": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "description": "Ein technisches Merkmal des Produkts.",
                            "properties": {
                              "key": {
                                "type": "string",
                                "description": "Merkmalsschlüssel, z. B. eine ECLASS-ID."
                              },
                              "name": {
                                "type": "string",
                                "description": "Anzeigename in der angefragten Sprache."
                              },
                              "text_value": {
                                "type": "string"
                              },
                              "numeric_value": {
                                "type": "number"
                              },
                              "unit": {
                                "type": "string"
                              },
                              "section": {
                                "type": "string"
                              },
                              "section_key": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "key",
                              "name"
                            ]
                          }
                        }
                      },
                      "required": [
                        "id",
                        "name"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "supplierName": {
                          "type": "string",
                          "description": "Hersteller."
                        },
                        "images": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "format": "uri"
                          }
                        },
                        "features": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "pricing": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "Preis für 1 Stück; `null`, wenn das Produkt nur auf Anfrage erhältlich ist.",
                          "properties": {
                            "listPriceNet": {
                              "type": "number"
                            },
                            "unitPriceNet": {
                              "type": "number"
                            },
                            "unitPriceGross": {
                              "type": "number"
                            },
                            "taxRate": {
                              "type": "number"
                            }
                          }
                        },
                        "tiers": {
                          "type": "array",
                          "description": "Mengenrabatte des Herstellers.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "minQuantity": {
                                "type": "integer"
                              },
                              "discountPercent": {
                                "type": "number"
                              }
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Die ID ist keine Zahl.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Kein Produkt mit dieser ID im Sortiment.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Limit erreicht: höchstens 30 Anfragen pro Minute und 1500 Produkte pro Tag je Absender (eine Suche zählt mit ihrem `limit`). `Retry-After` nennt die Wartezeit in Sekunden.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        }
      }
    }
  }
}