{
  "openapi": "3.1.0",
  "info": {
    "title": "Staenis floor calculator",
    "version": "1.0.0",
    "description": "Read-only estimated material quantities. Same calculation engine as the website. No price, stock, shipping charge, email, lead, checkout or purchasing action. Protocol keys and item names are English; validation and thermal labels follow culture. Browser tool: staenis_calculate_floor. Do not infer project suitability from a successful calculation."
  },
  "servers": [
    {
      "url": "https://www.staenis.com"
    }
  ],
  "paths": {
    "/api/calculator/v1/calculate": {
      "get": {
        "operationId": "staenisCalculateFloor",
        "summary": "Calculate floor material quantities",
        "parameters": [
          {
            "name": "surfaceM2",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 5000
            }
          },
          {
            "name": "thicknessMm",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 2000
            }
          },
          {
            "name": "filling",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "screed",
                "screed_plus_insulation_screed",
                "stabilise",
                "drainage_mortar",
                "non_tileable_insulation_screed",
                "tileable_insulation_screed",
                "dry_floor_systems",
                "egaline",
                "none"
              ]
            }
          },
          {
            "name": "country",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{2}$",
              "description": "Recognized lowercase ISO country code; availability varies by country."
            }
          },
          {
            "name": "culture",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "nl-BE",
                "nl-NL",
                "fr-BE",
                "fr-FR",
                "de-DE",
                "en-150"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Estimate. Choose one system, include its shared components once, choose one option from EVERY required group. Items within an option belong together. Never sum alternatives. Empty group options mean filler quantities are unavailable for this country, not zero required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Result"
                }
              }
            }
          },
          "400": {
            "description": "Invalid, duplicate, unknown or excessive input. Exactly five parameters, no body or personal data.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown API path.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "GET only.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Material-specific validation failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Budget exhausted; honor Retry-After, use exponential backoff, never loop.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "503": {
            "description": "Disabled or unavailable; use the human calculator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Input": {
        "type": "object",
        "properties": {
          "surfaceM2": {
            "type": "integer",
            "minimum": 1,
            "maximum": 5000
          },
          "thicknessMm": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2000
          },
          "filling": {
            "type": "string",
            "enum": [
              "screed",
              "screed_plus_insulation_screed",
              "stabilise",
              "drainage_mortar",
              "non_tileable_insulation_screed",
              "tileable_insulation_screed",
              "dry_floor_systems",
              "egaline",
              "none"
            ]
          },
          "country": {
            "type": "string",
            "pattern": "^[a-z]{2}$",
            "description": "Recognized lowercase ISO country code; availability varies by country."
          },
          "culture": {
            "type": "string",
            "enum": [
              "nl-BE",
              "nl-NL",
              "fr-BE",
              "fr-FR",
              "de-DE",
              "en-150"
            ]
          }
        },
        "required": [
          "surfaceM2",
          "thicknessMm",
          "filling",
          "country",
          "culture"
        ]
      },
      "Item": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "quantity": {
            "type": "integer"
          },
          "unit": {
            "type": "string",
            "enum": [
              "box",
              "bundle",
              "bag",
              "tonne",
              "kg",
              "container",
              "quarter_pallet",
              "pallet"
            ]
          },
          "packageSize": {
            "type": [
              "number",
              "null"
            ]
          },
          "packageUnit": {
            "type": [
              "string",
              "null"
            ]
          },
          "webshopVariantId": {
            "type": [
              "integer",
              "null"
            ]
          },
          "minimumOrderQuantity": {
            "type": "integer"
          },
          "exceedsMaximumOrder": {
            "type": "boolean"
          },
          "warning": {
            "type": [
              "string",
              "null"
            ]
          },
          "includedInWebshopProposal": {
            "type": "boolean",
            "description": "Included in the calculator model webshop proposals for this country and quantity; not a stock or shipping guarantee."
          }
        },
        "required": [
          "code",
          "name",
          "quantity",
          "unit",
          "packageSize",
          "packageUnit",
          "webshopVariantId",
          "minimumOrderQuantity",
          "exceedsMaximumOrder",
          "warning",
          "includedInWebshopProposal"
        ]
      },
      "Option": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Item"
            }
          }
        },
        "required": [
          "code",
          "items"
        ]
      },
      "Group": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "selection": {
            "const": "choose_one"
          },
          "layer": {
            "type": [
              "integer",
              "null"
            ]
          },
          "thicknessMm": {
            "type": [
              "integer",
              "null"
            ]
          },
          "options": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Option"
            }
          }
        },
        "required": [
          "code",
          "selection",
          "layer",
          "thicknessMm",
          "options"
        ]
      },
      "System": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "sharedComponents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Item"
            }
          },
          "requiredGroups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Group"
            }
          }
        },
        "required": [
          "code",
          "sharedComponents",
          "requiredGroups"
        ]
      },
      "Thermal": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string"
          },
          "thicknessMm": {
            "type": [
              "integer",
              "null"
            ]
          },
          "lambdaValue": {
            "type": [
              "number",
              "null"
            ]
          },
          "rdValue": {
            "type": [
              "number",
              "null"
            ]
          },
          "note": {
            "type": [
              "string",
              "null"
            ]
          },
          "isTotal": {
            "type": "boolean"
          },
          "hasReliableLambda": {
            "type": "boolean"
          }
        },
        "required": [
          "label",
          "thicknessMm",
          "lambdaValue",
          "rdValue",
          "note",
          "isTotal",
          "hasReliableLambda"
        ]
      },
      "Result": {
        "type": "object",
        "properties": {
          "version": {
            "const": "1"
          },
          "input": {
            "$ref": "#/components/schemas/Input"
          },
          "volumeM3": {
            "type": "number"
          },
          "estimate": {
            "const": true
          },
          "resultUrl": {
            "type": "string",
            "format": "uri"
          },
          "systemSelection": {
            "const": "choose_one"
          },
          "systems": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/System"
            }
          },
          "thermalPerformance": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Thermal"
            }
          },
          "notes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "version",
          "input",
          "volumeM3",
          "estimate",
          "resultUrl",
          "systemSelection",
          "systems",
          "thermalPerformance",
          "notes"
        ]
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "messages": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "documentation": {
            "type": "string",
            "format": "uri"
          }
        },
        "required": [
          "error"
        ]
      }
    }
  }
}
