{
  "openapi": "3.1.0",
  "info": {
    "title": "BlueLux API",
    "version": "2.0.0",
    "description": "Public, deterministic pool calculations and operating knowledge. Calculations are grounded in the same engine that supports BlueLux field operations. Public callers need no authentication; requests are rate limited. Product labels, manufacturer instructions, controlling codes, and emergency directions take precedence."
  },
  "servers": [{ "url": "https://bluelux.com" }],
  "paths": {
    "/api/v1/tools": {
      "get": {
        "operationId": "listPoolKnowledgeTools",
        "summary": "List tools and their JSON Schemas",
        "responses": { "200": { "description": "Tool catalog", "content": { "application/json": { "schema": { "type": "object" } } } } }
      }
    },
    "/api/v1/tools/{name}": {
      "post": {
        "operationId": "callPoolKnowledgeTool",
        "summary": "Call a public BlueLux tool",
        "parameters": [{ "name": "name", "in": "path", "required": true, "schema": { "type": "string", "enum": ["calculate_pool_dose", "calculate_lsi", "get_metals_protocol", "get_nutrient_thresholds", "diagnose_filter_circulation", "get_seasonal_checklist", "search_playbook"] } }],
        "description": "Send the JSON object defined for the selected tool. The live tool catalog is canonical. The schemas below fully describe dosing and LSI inputs, including product overrides and calculation profiles.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "oneOf": [{ "$ref": "#/components/schemas/DoseInput" }, { "$ref": "#/components/schemas/LsiInput" }, { "type": "object" }] },
              "examples": {
                "liquidChlorine": { "summary": "Default 12.5% liquid chlorine", "value": { "chemical": "liquid_chlorine", "volume_gallons": 10000, "current": 1, "target": 5 } },
                "muriaticAcid": { "summary": "31.45% muriatic acid with required alkalinity", "value": { "chemical": "muriatic_acid", "volume_gallons": 10000, "current": 8.2, "target": 7.4, "total_alkalinity_ppm": 100 } },
                "lsi": { "summary": "BlueLux continuous LSI profile", "value": { "ph": 7.8, "total_alkalinity_ppm": 100, "calcium_hardness_ppm": 400, "temperature_f": 80, "tds_ppm": 3200, "cyanuric_acid_ppm": 50, "calculation_profile": "bluelux_equilibrium_v1" } }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "A structured result containing value, unit, source_page, confidence, rationale, and data_version.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ToolResponse" } } } },
          "400": { "description": "Invalid arguments" },
          "404": { "description": "Unknown tool" },
          "429": { "description": "Rate limit exceeded" },
          "503": { "description": "Canonical calculation service unavailable" }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "DoseInput": {
        "type": "object",
        "additionalProperties": false,
        "required": ["chemical", "volume_gallons", "current", "target"],
        "properties": {
          "chemical": { "type": "string", "enum": ["liquid_chlorine", "muriatic_acid", "sodium_bicarbonate", "calcium_chloride", "cyanuric_acid", "pool_salt", "soda_ash"] },
          "volume_gallons": { "type": "integer", "minimum": 100, "maximum": 2000000 },
          "current": { "type": "number", "description": "Current ppm for concentration tools or current pH for acid and soda ash." },
          "target": { "type": "number", "description": "Target ppm for concentration tools or target pH for acid and soda ash." },
          "product_profile_id": { "type": "string", "description": "Optional profile ID from /datasets/v1/product-profiles.json." },
          "product_strength_percent": { "type": "number", "exclusiveMinimum": 0, "maximum": 100, "description": "Explicit strength or purity override. Omit to use the disclosed default profile." },
          "product_density_g_ml": { "type": "number", "exclusiveMinimum": 0, "maximum": 3, "description": "Optional liquid density override in grams per milliliter." },
          "total_alkalinity_ppm": { "type": "number", "minimum": 0, "maximum": 1000, "description": "Required for muriatic acid and soda ash." },
          "cyanuric_acid_ppm": { "type": "number", "minimum": 0, "maximum": 1000 },
          "borates_ppm_as_boron": { "type": "number", "minimum": 0, "maximum": 1000 },
          "free_chlorine_ppm": { "type": "number", "minimum": 0, "maximum": 100 },
          "temperature_f": { "type": "number", "minimum": 32, "maximum": 140 },
          "tds_ppm": { "type": "number", "exclusiveMinimum": 0, "maximum": 100000 }
        }
      },
      "LsiInput": {
        "type": "object",
        "additionalProperties": false,
        "required": ["ph", "total_alkalinity_ppm", "calcium_hardness_ppm"],
        "properties": {
          "ph": { "type": "number", "minimum": 0, "maximum": 14 },
          "total_alkalinity_ppm": { "type": "number", "exclusiveMinimum": 0, "maximum": 1000 },
          "calcium_hardness_ppm": { "type": "number", "exclusiveMinimum": 0, "maximum": 10000 },
          "temperature_f": { "type": "number", "minimum": 32, "maximum": 140, "default": 77 },
          "tds_ppm": { "type": "number", "exclusiveMinimum": 0, "maximum": 100000, "default": 1000 },
          "cyanuric_acid_ppm": { "type": "number", "minimum": 0, "maximum": 1000, "default": 0 },
          "calculation_profile": { "type": "string", "enum": ["bluelux_equilibrium_v1", "phta_2024_table_v1"], "default": "bluelux_equilibrium_v1" }
        }
      },
      "ToolResponse": {
        "type": "object",
        "required": ["schema_version", "tool", "generated_at", "result"],
        "properties": {
          "schema_version": { "const": "1.0" },
          "tool": { "type": "string" },
          "generated_at": { "type": "string", "format": "date-time" },
          "result": {
            "type": "object",
            "required": ["value", "unit", "source_page", "confidence", "rationale", "data_version"],
            "properties": {
              "value": { "description": "Tool-specific result. Dosing results use exact_amount for the full mathematical correction, exact_step_amount for a bounded current step when present, and field_amount for the practical amount to apply now." },
              "unit": { "type": "string" },
              "source_page": { "type": "string", "format": "uri" },
              "confidence": { "type": "string", "enum": ["high", "medium", "low"] },
              "rationale": { "type": "string" },
              "data_version": { "type": "string", "description": "For calculation tools, the deployed engine revision." },
              "provenance": { "type": "object", "description": "Canonical engine revision, module, function, and contract version." }
            }
          }
        }
      }
    }
  }
}
