{
  "openapi": "3.1.1",
  "info": {
    "title": "Crysalt API",
    "description": "IMPORTANT - read before relying on any output.\n\nCrysalt computes ESTIMATES and PREDICTIONS of mineral-scale behaviour using thermodynamic models. Those models have known limitations and their parameter sets cover a bounded range of temperature, pressure, composition and ionic strength. Outputs may be inaccurate or incomplete and depend entirely on the inputs supplied. A result whose 'converged' flag is false is unreliable and must not be used, and any accompanying 'warnings' must be read alongside the numbers.\n\nYou are solely responsible for independently verifying every output. Crysalt is not a substitute for professional engineering judgement and must not be used as the sole basis for any safety-critical, operational, financial, environmental, or design decision. Use of this API does not create any advisory, fiduciary or professional relationship, and no duty of care is assumed. Outputs must not be represented to third parties as warranted, certified or guaranteed.\n\nProvided 'as is' and 'as available', without warranty of any kind, with liability limited as set out in the terms of use: https://crysalt.com/terms",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://api.crysalt.com/"
    }
  ],
  "paths": {
    "/api/v1/metadata": {
      "get": {
        "tags": [
          "Crysalt.Api"
        ],
        "summary": "Supported minerals, input species, and current engine capabilities/limits.",
        "operationId": "GetCapabilities",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EngineCapabilities"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/scale/predict": {
      "post": {
        "tags": [
          "Crysalt.Api"
        ],
        "summary": "Predict scale for a single brine at one temperature/pressure condition.",
        "description": "Estimates from a thermodynamic model with known limitations and bounded parameter coverage. Verify independently before use. Not professional engineering advice, and not to be used as the sole basis for any safety-critical, operational, financial, environmental, or design decision. Provided as is, without warranty. See https://crysalt.com/terms",
        "operationId": "PredictScale",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScalePredictionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScalePredictionResult"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/scale/mix": {
      "post": {
        "tags": [
          "Crysalt.Api"
        ],
        "summary": "Mix two brines at a volume fraction, then predict scale (water-incompatibility case).",
        "description": "Estimates from a thermodynamic model with known limitations and bounded parameter coverage. Verify independently before use. Not professional engineering advice, and not to be used as the sole basis for any safety-critical, operational, financial, environmental, or design decision. Provided as is, without warranty. See https://crysalt.com/terms",
        "operationId": "MixAndPredict",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MixRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScalePredictionResult"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/scale/profile": {
      "post": {
        "tags": [
          "Crysalt.Api"
        ],
        "summary": "Evaluate one brine along a sequence of conditions (reservoir → wellhead → topside).",
        "description": "Estimates from a thermodynamic model with known limitations and bounded parameter coverage. Verify independently before use. Not professional engineering advice, and not to be used as the sole basis for any safety-critical, operational, financial, environmental, or design decision. Provided as is, without warranty. See https://crysalt.com/terms",
        "operationId": "ProfileScale",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProfileRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProfileResult"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ActivityModelKind": {
        "enum": [
          "Ideal",
          "Pitzer"
        ],
        "default": "Ideal"
      },
      "BrineComposition": {
        "required": [
          "ions"
        ],
        "type": "object",
        "properties": {
          "ions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IonAmount"
            }
          },
          "ph": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          }
        }
      },
      "Condition": {
        "required": [
          "temperatureC"
        ],
        "type": "object",
        "properties": {
          "temperatureC": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "pressureBar": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double",
            "default": 1
          },
          "ph": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "dissolvedCo2MgPerL": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "co2MoleFractionInGas": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "h2sMoleFractionInGas": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "ch4MoleFractionInGas": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          }
        }
      },
      "EngineCapabilities": {
        "required": [
          "minerals",
          "species",
          "pressureDependence",
          "vaporLiquidEquilibrium",
          "version"
        ],
        "type": "object",
        "properties": {
          "minerals": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SupportedMineral"
            }
          },
          "species": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SupportedSpecies"
            }
          },
          "pressureDependence": {
            "type": "boolean"
          },
          "vaporLiquidEquilibrium": {
            "type": "boolean"
          },
          "version": {
            "type": "string"
          },
          "gasPartitioning": {
            "type": "boolean",
            "default": false
          },
          "disclaimer": {
            "type": "string",
            "default": "Estimates from a thermodynamic model with known limitations and bounded parameter coverage. Verify independently before use. Not professional engineering advice, and not to be used as the sole basis for any safety-critical, operational, financial, environmental, or design decision. Provided as is, without warranty. See https://crysalt.com/terms"
          }
        }
      },
      "GasExchange": {
        "required": [
          "gas",
          "partialPressureBar",
          "exsolvedMolPerKg",
          "exsolvedMgPerKg"
        ],
        "type": "object",
        "properties": {
          "gas": {
            "type": "string"
          },
          "partialPressureBar": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "exsolvedMolPerKg": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "exsolvedMgPerKg": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          }
        }
      },
      "IonAmount": {
        "required": [
          "species",
          "mgPerL"
        ],
        "type": "object",
        "properties": {
          "species": {
            "type": "string"
          },
          "mgPerL": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          }
        }
      },
      "MineralResult": {
        "required": [
          "mineral",
          "saturationRatio",
          "saturationIndex",
          "precipitatedMoles",
          "precipitatedMassGrams",
          "ksp"
        ],
        "type": "object",
        "properties": {
          "mineral": {
            "type": "string"
          },
          "saturationRatio": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "saturationIndex": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "precipitatedMoles": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "precipitatedMassGrams": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "ksp": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          }
        }
      },
      "MixRequest": {
        "required": [
          "brineA",
          "brineB",
          "fractionA",
          "condition"
        ],
        "type": "object",
        "properties": {
          "brineA": {
            "$ref": "#/components/schemas/BrineComposition"
          },
          "brineB": {
            "$ref": "#/components/schemas/BrineComposition"
          },
          "fractionA": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "condition": {
            "$ref": "#/components/schemas/Condition"
          },
          "options": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/PredictionOptions"
              }
            ]
          }
        }
      },
      "PredictionOptions": {
        "type": "object",
        "properties": {
          "activityModel": {
            "$ref": "#/components/schemas/ActivityModelKind"
          }
        }
      },
      "ProfilePoint": {
        "required": [
          "condition",
          "result"
        ],
        "type": "object",
        "properties": {
          "condition": {
            "$ref": "#/components/schemas/Condition"
          },
          "result": {
            "$ref": "#/components/schemas/ScalePredictionResult"
          }
        }
      },
      "ProfileRequest": {
        "required": [
          "brine",
          "path"
        ],
        "type": "object",
        "properties": {
          "brine": {
            "$ref": "#/components/schemas/BrineComposition"
          },
          "path": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Condition"
            }
          },
          "options": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/PredictionOptions"
              }
            ]
          }
        }
      },
      "ProfileResult": {
        "required": [
          "points"
        ],
        "type": "object",
        "properties": {
          "points": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProfilePoint"
            }
          },
          "disclaimer": {
            "type": "string",
            "default": "Estimates from a thermodynamic model with known limitations and bounded parameter coverage. Verify independently before use. Not professional engineering advice, and not to be used as the sole basis for any safety-critical, operational, financial, environmental, or design decision. Provided as is, without warranty. See https://crysalt.com/terms"
          }
        }
      },
      "ReactionConstant": {
        "required": [
          "reaction",
          "logK"
        ],
        "type": "object",
        "properties": {
          "reaction": {
            "type": "string"
          },
          "logK": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          }
        }
      },
      "ScalePredictionRequest": {
        "required": [
          "brine",
          "condition"
        ],
        "type": "object",
        "properties": {
          "brine": {
            "$ref": "#/components/schemas/BrineComposition"
          },
          "condition": {
            "$ref": "#/components/schemas/Condition"
          },
          "options": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/PredictionOptions"
              }
            ]
          }
        }
      },
      "ScalePredictionResult": {
        "required": [
          "converged",
          "ph",
          "ionicStrength",
          "minerals",
          "aqueous",
          "reactions",
          "warnings",
          "gases"
        ],
        "type": "object",
        "properties": {
          "converged": {
            "type": "boolean"
          },
          "ph": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "ionicStrength": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "minerals": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MineralResult"
            }
          },
          "aqueous": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SpeciesAmount"
            }
          },
          "reactions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReactionConstant"
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "gases": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/GasExchange"
            }
          },
          "disclaimer": {
            "type": "string",
            "default": "Estimates from a thermodynamic model with known limitations and bounded parameter coverage. Verify independently before use. Not professional engineering advice, and not to be used as the sole basis for any safety-critical, operational, financial, environmental, or design decision. Provided as is, without warranty. See https://crysalt.com/terms"
          }
        }
      },
      "SpeciesAmount": {
        "required": [
          "species",
          "molalityMolPerKg",
          "mgPerL",
          "activityCoefficient"
        ],
        "type": "object",
        "properties": {
          "species": {
            "type": "string"
          },
          "molalityMolPerKg": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "mgPerL": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "activityCoefficient": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          }
        }
      },
      "SupportedMineral": {
        "required": [
          "id",
          "name",
          "formula"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "formula": {
            "type": "string"
          }
        }
      },
      "SupportedSpecies": {
        "required": [
          "id",
          "charge"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "charge": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "Crysalt.Api"
    }
  ]
}