{
  "openapi": "3.1.0",
  "info": {
    "title": "HeartCalc API",
    "version": "1.0.0",
    "summary": "Verified pediatric cardiology and neonatal hemodynamics calculators, computed with the same code as the web pages.",
    "description": "Public, unauthenticated JSON API for the verified HeartCalc calculators (https://heartcalc.doctorarichai.com). Use it to compute rather than reciting equations. GET with query parameters or POST a JSON object; parameter names equal the web page form ids, so the same query string opens the prefilled page. Every response has state (ok, missing, not_applicable, invalid), the result with units, messages worded as on the page, citations with DOIs, a prefilled calculator_url and a disclaimer. Rules for AI use: cite the source; surface not-applicable and guard messages; decision support only; never send names, MRNs or dates of birth (send age instead). Inputs are not stored or logged. A remote MCP server with the same tools is at https://heartcalc.doctorarichai.com/mcp. Decision support only; verify against the primary references and clinical judgement. Inputs are not stored.",
    "contact": {
      "name": "Piyawat Arichai, MD, FAAP",
      "url": "https://heartcalc.doctorarichai.com/developers"
    }
  },
  "servers": [
    {
      "url": "https://heartcalc.doctorarichai.com"
    }
  ],
  "security": [],
  "externalDocs": {
    "description": "Developer guide",
    "url": "https://heartcalc.doctorarichai.com/developers"
  },
  "paths": {
    "/api/v1": {
      "get": {
        "operationId": "listCalculators",
        "summary": "List the verified calculators and their parameters",
        "description": "Returns the three verified HeartCalc calculators with endpoints, MCP tool names and parameter lists. Experimental tools on the site are not available through the API.",
        "responses": {
          "200": {
            "description": "Calculator list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "405": {
            "description": "Only GET (and OPTIONS) are allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/cath": {
      "get": {
        "operationId": "calculateCathHemodynamicsGet",
        "summary": "Cath Hemodynamics (query parameters)",
        "description": "Pediatric and congenital cardiac catheterization Fick calculator (any age). Predicted VO2 by Seckeler (all ages; adjusts for single ventricle and ICU), Lundell (any age; separate under/over 3 y equations) or LaFarge (3 y and older), or a measured VO2 or a typed VO2 index. Computes Qs, Qp, Qep (L/min and indexed L/min/m2), Qp:Qs, TPG, PVR/PVRi and SVR/SVRi (Wood units, WU and WU·m2), Rp:Rs and, when requested, per-lung flow and PVRi for unequal right/left lung perfusion. Saturations are percent, pressures are MEAN pressures in mmHg, hemoglobin g/dL, height cm, weight kg. BSA is Mosteller unless bsaOv is given. Pulmonary vein saturation is assumed 98% when blank (flagged). Dissolved oxygen is ignored, so accuracy falls on supplemental oxygen. Predicted VO2 carries wide individual error (SD about 28 to 39 mL/min/m2); a measured VO2 is preferred and overrides everything. Qp:Qs does not depend on VO2; flows and resistances do. The result is decision support: cite HeartCalc (calculator_url) and the primary reference in citations, and show the user any not_applicable reason and caution/danger message. Never send names, MRNs or other identifiers; prefer age to a date of birth.",
        "parameters": [
          {
            "name": "dob",
            "in": "query",
            "required": false,
            "description": "Date of birth (YYYY-MM-DD). Prefer ageY/ageM/ageD: AI assistants should not send dates of birth. With cathDate, age = days / 365.25 and overrides ageY/ageM/ageD. Privacy: do not send dates of birth from AI assistants; use the age parameters.",
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "x-privacy": "avoid",
              "x-group": "Patient"
            }
          },
          {
            "name": "cathDate",
            "in": "query",
            "required": false,
            "description": "Cath date (YYYY-MM-DD), used only with dob. Defaults to today (UTC) when dob is given.",
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "x-group": "Patient"
            }
          },
          {
            "name": "ageY",
            "in": "query",
            "required": false,
            "description": "Age, whole years (decimals accepted). Age = ageY + ageM/12 + ageD/365.25. Needed for predicted VO2. Expected range: 0 to … years (out-of-range values are answered by the calculator's own guard messages, not rejected).",
            "schema": {
              "type": "number",
              "x-unit": "years",
              "x-expected-minimum": 0,
              "x-group": "Patient"
            }
          },
          {
            "name": "ageM",
            "in": "query",
            "required": false,
            "description": "Additional months of age. Expected range: 0 to … months (out-of-range values are answered by the calculator's own guard messages, not rejected).",
            "schema": {
              "type": "number",
              "x-unit": "months",
              "x-expected-minimum": 0,
              "x-group": "Patient"
            }
          },
          {
            "name": "ageD",
            "in": "query",
            "required": false,
            "description": "Additional days of age (useful for neonates). Expected range: 0 to … days (out-of-range values are answered by the calculator's own guard messages, not rejected).",
            "schema": {
              "type": "number",
              "x-unit": "days",
              "x-expected-minimum": 0,
              "x-group": "Patient"
            }
          },
          {
            "name": "sex",
            "in": "query",
            "required": false,
            "description": "M or F. Used by Lundell (3 y and older) and LaFarge.",
            "schema": {
              "type": "string",
              "enum": [
                "M",
                "F"
              ],
              "x-group": "Patient"
            }
          },
          {
            "name": "ht",
            "in": "query",
            "required": false,
            "description": "Height in cm (BSA by Mosteller; Lundell under 3 y).",
            "schema": {
              "type": "number",
              "x-unit": "cm",
              "x-group": "Patient"
            }
          },
          {
            "name": "wt",
            "in": "query",
            "required": false,
            "description": "Weight in kg (BSA by Mosteller; Seckeler; Lundell under 3 y).",
            "schema": {
              "type": "number",
              "x-unit": "kg",
              "x-group": "Patient"
            }
          },
          {
            "name": "bsaOv",
            "in": "query",
            "required": false,
            "description": "Body surface area in m2; overrides the Mosteller BSA from height and weight. Unit: m².",
            "schema": {
              "type": "number",
              "x-unit": "m²",
              "x-group": "Patient"
            }
          },
          {
            "name": "hgb",
            "in": "query",
            "required": false,
            "description": "Hemoglobin in g/dL. O2 capacity = 13.6 x Hgb mL O2/L. Required for flows.",
            "schema": {
              "type": "number",
              "x-unit": "g/dL",
              "x-group": "Patient"
            }
          },
          {
            "name": "vo2Method",
            "in": "query",
            "required": false,
            "description": "VO2 source when no measured VO2 is given: seckeler (default; all ages), auto (Lundell under 3 y, LaFarge from 3 y), lundell, lafarge (3 y and older only), or manual (use vo2i). If omitted: manual when vo2i is given, otherwise seckeler (as the page's prefill links do).",
            "schema": {
              "type": "string",
              "enum": [
                "seckeler",
                "auto",
                "lundell",
                "lafarge",
                "manual"
              ],
              "default": "seckeler",
              "x-group": "VO2"
            }
          },
          {
            "name": "sv",
            "in": "query",
            "required": false,
            "description": "Single ventricle anatomy (Seckeler: -9.6 mL/min/m2).",
            "schema": {
              "type": "boolean",
              "description": "true/false (also 1/0, on/off, yes/no)"
            }
          },
          {
            "name": "ci",
            "in": "query",
            "required": false,
            "description": "Critically ill / ICU patient (Seckeler: -11.2 mL/min/m2).",
            "schema": {
              "type": "boolean",
              "description": "true/false (also 1/0, on/off, yes/no)"
            }
          },
          {
            "name": "hr",
            "in": "query",
            "required": false,
            "description": "Heart rate in beats/min (Lundell and LaFarge only). Unit: bpm.",
            "schema": {
              "type": "number",
              "x-unit": "bpm",
              "x-group": "VO2"
            }
          },
          {
            "name": "vo2i",
            "in": "query",
            "required": false,
            "description": "VO2 index in mL/min/m2, used only when vo2Method = manual. Unit: mL/min/m².",
            "schema": {
              "type": "number",
              "x-unit": "mL/min/m²",
              "x-group": "VO2"
            }
          },
          {
            "name": "vo2abs",
            "in": "query",
            "required": false,
            "description": "Measured VO2 in mL/min. Overrides every predicted or manual value.",
            "schema": {
              "type": "number",
              "x-unit": "mL/min",
              "x-group": "VO2"
            }
          },
          {
            "name": "sao2",
            "in": "query",
            "required": false,
            "description": "Systemic arterial O2 saturation, %.",
            "schema": {
              "type": "number",
              "x-unit": "%",
              "x-group": "Saturations"
            }
          },
          {
            "name": "mvDirect",
            "in": "query",
            "required": false,
            "description": "Mixed venous O2 saturation, % (as entered; no SVC/IVC formula is applied).",
            "schema": {
              "type": "number",
              "x-unit": "%",
              "x-group": "Saturations"
            }
          },
          {
            "name": "pa",
            "in": "query",
            "required": false,
            "description": "Pulmonary artery O2 saturation, %.",
            "schema": {
              "type": "number",
              "x-unit": "%",
              "x-group": "Saturations"
            }
          },
          {
            "name": "pv",
            "in": "query",
            "required": false,
            "description": "Pulmonary vein O2 saturation, %. 98% is assumed when blank (reported as an assumption).",
            "schema": {
              "type": "number",
              "x-unit": "%",
              "x-group": "Saturations"
            }
          },
          {
            "name": "mAo",
            "in": "query",
            "required": false,
            "description": "Mean aortic pressure, mmHg.",
            "schema": {
              "type": "number",
              "x-unit": "mmHg",
              "x-group": "Mean pressures"
            }
          },
          {
            "name": "mRA",
            "in": "query",
            "required": false,
            "description": "Mean right atrial pressure, mmHg.",
            "schema": {
              "type": "number",
              "x-unit": "mmHg",
              "x-group": "Mean pressures"
            }
          },
          {
            "name": "mPA",
            "in": "query",
            "required": false,
            "description": "Mean pulmonary artery pressure, mmHg.",
            "schema": {
              "type": "number",
              "x-unit": "mmHg",
              "x-group": "Mean pressures"
            }
          },
          {
            "name": "mLA",
            "in": "query",
            "required": false,
            "description": "Mean left atrial or pulmonary capillary wedge pressure, mmHg.",
            "schema": {
              "type": "number",
              "x-unit": "mmHg",
              "x-group": "Mean pressures"
            }
          },
          {
            "name": "diffOn",
            "in": "query",
            "required": false,
            "description": "Correct for unequal right and left lung flow (lung perfusion scan or MRI flow split, branch PA stenosis, unilateral pulmonary vein disease). If omitted, it is turned on when any of pctR, mRPA, mLPA, rpv or lpv is given (as the page's prefill links do).",
            "schema": {
              "type": "boolean",
              "description": "true/false (also 1/0, on/off, yes/no)"
            }
          },
          {
            "name": "pctR",
            "in": "query",
            "required": false,
            "description": "Right lung share of pulmonary flow, % (strictly between 0 and 100). Left = 100 - right. Used only with diffOn. Expected range: 0 to 100 % (out-of-range values are answered by the calculator's own guard messages, not rejected).",
            "schema": {
              "type": "number",
              "x-unit": "%",
              "x-expected-minimum": 0,
              "x-expected-maximum": 100,
              "x-group": "Differential lung perfusion"
            }
          },
          {
            "name": "mRPA",
            "in": "query",
            "required": false,
            "description": "Mean right PA pressure, mmHg (main PA pressure if blank). Used only with diffOn.",
            "schema": {
              "type": "number",
              "x-unit": "mmHg",
              "x-group": "Differential lung perfusion"
            }
          },
          {
            "name": "mLPA",
            "in": "query",
            "required": false,
            "description": "Mean left PA pressure, mmHg (main PA pressure if blank). Used only with diffOn.",
            "schema": {
              "type": "number",
              "x-unit": "mmHg",
              "x-group": "Differential lung perfusion"
            }
          },
          {
            "name": "rpv",
            "in": "query",
            "required": false,
            "description": "Right pulmonary vein saturation, % (PV sat if blank). Used only with diffOn.",
            "schema": {
              "type": "number",
              "x-unit": "%",
              "x-group": "Differential lung perfusion"
            }
          },
          {
            "name": "lpv",
            "in": "query",
            "required": false,
            "description": "Left pulmonary vein saturation, % (PV sat if blank). Used only with diffOn.",
            "schema": {
              "type": "number",
              "x-unit": "%",
              "x-group": "Differential lung perfusion"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Computed, incomplete (missing), not applicable or invalid input: see state and messages.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CathResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request: invalid JSON, a non-object body, or a value outside an enumerated set.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "calculateCathHemodynamics",
        "summary": "Cath Hemodynamics (JSON body)",
        "description": "Pediatric and congenital cardiac catheterization Fick calculator (any age). Predicted VO2 by Seckeler (all ages; adjusts for single ventricle and ICU), Lundell (any age; separate under/over 3 y equations) or LaFarge (3 y and older), or a measured VO2 or a typed VO2 index. Computes Qs, Qp, Qep (L/min and indexed L/min/m2), Qp:Qs, TPG, PVR/PVRi and SVR/SVRi (Wood units, WU and WU·m2), Rp:Rs and, when requested, per-lung flow and PVRi for unequal right/left lung perfusion. Saturations are percent, pressures are MEAN pressures in mmHg, hemoglobin g/dL, height cm, weight kg. BSA is Mosteller unless bsaOv is given. Pulmonary vein saturation is assumed 98% when blank (flagged). Dissolved oxygen is ignored, so accuracy falls on supplemental oxygen. Predicted VO2 carries wide individual error (SD about 28 to 39 mL/min/m2); a measured VO2 is preferred and overrides everything. Qp:Qs does not depend on VO2; flows and resistances do. The result is decision support: cite HeartCalc (calculator_url) and the primary reference in citations, and show the user any not_applicable reason and caution/danger message. Never send names, MRNs or other identifiers; prefer age to a date of birth.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CathInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Computed, incomplete (missing), not applicable or invalid input: see state and messages.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CathResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request: invalid JSON, a non-object body, or a value outside an enumerated set.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/scd": {
      "get": {
        "operationId": "calculateHcmScdRiskGet",
        "summary": "Sudden Cardiac Death Risk (HCM) (query parameters)",
        "description": "For patients with hypertrophic cardiomyopathy (HCM), primary prevention, at baseline evaluation. Age in completed years chooses the model: under 1 none; 1-15 HCM Risk-Kids (Norrish 2019); 16 both; 17-80 HCM Risk-SCD (O'Mahony 2014, as in the AHA calculator); over 80 none. HCM Risk-Kids needs sex, weight (kg), maximal LV wall thickness and LA diameter in mm (converted to Z scores exactly as hcmriskkids.org) or PHN/Neilan Z scores (mode = z), maximal LVOT gradient (mmHg), unexplained syncope and NSVT. HCM Risk-SCD needs wall thickness (10-35 mm), LA diameter (28-67 mm), LVOT gradient (2-154 mmHg), family history of SCD, syncope and NSVT. Risk groups: low <4%, intermediate 4 to <6%, high >=6% (ESC 2023 thresholds). Neither model applies after prior VF/sustained VT/cardiac arrest (secondary prevention), in syndromic/metabolic/neuromuscular HCM, in infant-onset HCM (Risk-Kids) or in competitive athletes (Risk-SCD); the response then says not_applicable with the reason. The 2024 AHA/ACC rows additionally need fh50, massive (children) or the wall thickness (adults), aneur, lvef and lge. Prefer age (ageY) to a date of birth. The result is decision support: cite HeartCalc (calculator_url) and the primary reference in citations, and show the user any not_applicable reason and caution/danger message. Never send names, MRNs or other identifiers; prefer age to a date of birth.",
        "parameters": [
          {
            "name": "dob",
            "in": "query",
            "required": false,
            "description": "Date of birth (YYYY-MM-DD). Prefer ageY: AI assistants should not send dates of birth. With evalDate it overrides ageY (completed years plus fraction). Privacy: do not send dates of birth from AI assistants; use the age parameters.",
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "x-privacy": "avoid",
              "x-group": "Patient"
            }
          },
          {
            "name": "evalDate",
            "in": "query",
            "required": false,
            "description": "Evaluation date (YYYY-MM-DD), used only with dob. Defaults to today (UTC) when dob is given.",
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "x-group": "Patient"
            }
          },
          {
            "name": "ageY",
            "in": "query",
            "required": false,
            "description": "Age in years (decimals allowed). Completed years choose the model: <1 none, 1-15 HCM Risk-Kids, 16 both, 17-80 HCM Risk-SCD, >80 none. Expected range: 0 to … years (out-of-range values are answered by the calculator's own guard messages, not rejected).",
            "schema": {
              "type": "number",
              "x-unit": "years",
              "x-expected-minimum": 0,
              "x-group": "Patient"
            }
          },
          {
            "name": "sex",
            "in": "query",
            "required": false,
            "description": "male or female. HCM Risk-Kids, mm mode only (LA diameter Z score is sex-specific).",
            "schema": {
              "type": "string",
              "enum": [
                "male",
                "female"
              ],
              "x-group": "Patient"
            }
          },
          {
            "name": "wt",
            "in": "query",
            "required": false,
            "description": "Weight in kg (HCM Risk-Kids, mm mode; accepted 2-150 kg). BSA = 0.1023 x weight^0.68 (hcmriskkids.org formula, not Mosteller).",
            "schema": {
              "type": "number",
              "x-unit": "kg",
              "x-group": "Patient"
            }
          },
          {
            "name": "priorArrest",
            "in": "query",
            "required": false,
            "description": "Secondary prevention. Both models then do not apply; 2024 AHA/ACC: ICD recommended (Class 1).",
            "schema": {
              "type": "boolean",
              "description": "true/false (also 1/0, on/off, yes/no)"
            }
          },
          {
            "name": "infantOnset",
            "in": "query",
            "required": false,
            "description": "Infant-onset HCM: HCM Risk-Kids does not apply.",
            "schema": {
              "type": "boolean",
              "description": "true/false (also 1/0, on/off, yes/no)"
            }
          },
          {
            "name": "syndromic",
            "in": "query",
            "required": false,
            "description": "RASopathy (Noonan), Pompe, Anderson-Fabry, other inborn errors of metabolism, Friedreich ataxia: neither model applies.",
            "schema": {
              "type": "boolean",
              "description": "true/false (also 1/0, on/off, yes/no)"
            }
          },
          {
            "name": "athlete",
            "in": "query",
            "required": false,
            "description": "HCM Risk-SCD does not apply to elite or competitive athletes.",
            "schema": {
              "type": "boolean",
              "description": "true/false (also 1/0, on/off, yes/no)"
            }
          },
          {
            "name": "septal",
            "in": "query",
            "required": false,
            "description": "Adds the AHA calculator caution for HCM Risk-SCD after septal reduction.",
            "schema": {
              "type": "boolean",
              "description": "true/false (also 1/0, on/off, yes/no)"
            }
          },
          {
            "name": "mode",
            "in": "query",
            "required": false,
            "description": "HCM Risk-Kids input: mm (default; measurements converted to Z as hcmriskkids.org does) or z (Z scores entered in mwtZ/laZ). HCM Risk-SCD always uses mm. If omitted, z is used when mwtZ or laZ is given without mwtMm or laMm (as the page's prefill links do).",
            "schema": {
              "type": "string",
              "enum": [
                "mm",
                "z"
              ],
              "default": "mm",
              "x-group": "Echo"
            }
          },
          {
            "name": "mwtMm",
            "in": "query",
            "required": false,
            "description": "Maximal LV wall thickness, mm (2D echo). Risk-Kids accepts 4-70; Risk-SCD 10-35. Adults: >=30 mm counts as massive LVH for the AHA rows.",
            "schema": {
              "type": "number",
              "x-unit": "mm",
              "x-group": "Echo"
            }
          },
          {
            "name": "laMm",
            "in": "query",
            "required": false,
            "description": "Left atrial diameter, mm (M-mode or 2D, parasternal long axis). Risk-Kids accepts 3-80; Risk-SCD 28-67.",
            "schema": {
              "type": "number",
              "x-unit": "mm",
              "x-group": "Echo"
            }
          },
          {
            "name": "mwtZ",
            "in": "query",
            "required": false,
            "description": "Maximal wall thickness Z score, BSA-adjusted PHN (Lopez 2017) reference only; mode = z. Accepted -5 to 60. Unit: Z (PHN).",
            "schema": {
              "type": "number",
              "x-unit": "Z (PHN)",
              "x-group": "Echo"
            }
          },
          {
            "name": "laZ",
            "in": "query",
            "required": false,
            "description": "LA diameter Z score, Neilan 2009 reference only; mode = z. Accepted -6 to 20. Unit: Z (Neilan).",
            "schema": {
              "type": "number",
              "x-unit": "Z (Neilan)",
              "x-group": "Echo"
            }
          },
          {
            "name": "lvot",
            "in": "query",
            "required": false,
            "description": "Maximal LVOT gradient at rest or Valsalva, mmHg. Risk-Kids accepts 0-200 (0 valid); Risk-SCD 2-154.",
            "schema": {
              "type": "number",
              "x-unit": "mmHg",
              "x-group": "Echo"
            }
          },
          {
            "name": "syncope",
            "in": "query",
            "required": false,
            "description": "Unexplained syncope (yes/no). Used by both models and the AHA rows.",
            "schema": {
              "type": "string",
              "enum": [
                "yes",
                "no"
              ],
              "x-group": "History"
            }
          },
          {
            "name": "nsvt",
            "in": "query",
            "required": false,
            "description": "Non-sustained VT on ambulatory ECG, >=3 beats at >=120 bpm, <30 s (yes/no). Used by both models and the AHA rows.",
            "schema": {
              "type": "string",
              "enum": [
                "yes",
                "no"
              ],
              "x-group": "History"
            }
          },
          {
            "name": "fh",
            "in": "query",
            "required": false,
            "description": "HCM Risk-SCD (ESC 2014) family history of SCD: >=1 first-degree relative under 40 y, or a first-degree relative with confirmed HCM at any age (yes/no). Adult model only.",
            "schema": {
              "type": "string",
              "enum": [
                "yes",
                "no"
              ],
              "x-group": "History"
            }
          },
          {
            "name": "fh50",
            "in": "query",
            "required": false,
            "description": "2024 AHA/ACC: sudden death definitively or likely attributable to HCM in >=1 first-degree or close relatives aged <=50 (yes/no).",
            "schema": {
              "type": "string",
              "enum": [
                "yes",
                "no"
              ],
              "x-group": "2024 AHA/ACC"
            }
          },
          {
            "name": "massive",
            "in": "query",
            "required": false,
            "description": "2024 AHA/ACC, under 16 y only: massive LVH by clinician judgement (no fixed threshold; Z >=20, or >10 with other risk factors, appears reasonable). Adults derive it from mwtMm >= 30.",
            "schema": {
              "type": "string",
              "enum": [
                "yes",
                "no"
              ],
              "x-group": "2024 AHA/ACC"
            }
          },
          {
            "name": "aneur",
            "in": "query",
            "required": false,
            "description": "2024 AHA/ACC: LV apical aneurysm (yes/no).",
            "schema": {
              "type": "string",
              "enum": [
                "yes",
                "no"
              ],
              "x-group": "2024 AHA/ACC"
            }
          },
          {
            "name": "lvef",
            "in": "query",
            "required": false,
            "description": "2024 AHA/ACC: LV systolic dysfunction, EF <50% (yes/no).",
            "schema": {
              "type": "string",
              "enum": [
                "yes",
                "no"
              ],
              "x-group": "2024 AHA/ACC"
            }
          },
          {
            "name": "lge",
            "in": "query",
            "required": false,
            "description": "2024 AHA/ACC: extensive LGE on CMR, >=15% of LV mass: yes, no or notdone.",
            "schema": {
              "type": "string",
              "enum": [
                "yes",
                "no",
                "notdone"
              ],
              "x-group": "2024 AHA/ACC"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Computed, incomplete (missing), not applicable or invalid input: see state and messages.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScdResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request: invalid JSON, a non-object body, or a value outside an enumerated set.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "calculateHcmScdRisk",
        "summary": "Sudden Cardiac Death Risk (HCM) (JSON body)",
        "description": "For patients with hypertrophic cardiomyopathy (HCM), primary prevention, at baseline evaluation. Age in completed years chooses the model: under 1 none; 1-15 HCM Risk-Kids (Norrish 2019); 16 both; 17-80 HCM Risk-SCD (O'Mahony 2014, as in the AHA calculator); over 80 none. HCM Risk-Kids needs sex, weight (kg), maximal LV wall thickness and LA diameter in mm (converted to Z scores exactly as hcmriskkids.org) or PHN/Neilan Z scores (mode = z), maximal LVOT gradient (mmHg), unexplained syncope and NSVT. HCM Risk-SCD needs wall thickness (10-35 mm), LA diameter (28-67 mm), LVOT gradient (2-154 mmHg), family history of SCD, syncope and NSVT. Risk groups: low <4%, intermediate 4 to <6%, high >=6% (ESC 2023 thresholds). Neither model applies after prior VF/sustained VT/cardiac arrest (secondary prevention), in syndromic/metabolic/neuromuscular HCM, in infant-onset HCM (Risk-Kids) or in competitive athletes (Risk-SCD); the response then says not_applicable with the reason. The 2024 AHA/ACC rows additionally need fh50, massive (children) or the wall thickness (adults), aneur, lvef and lge. Prefer age (ageY) to a date of birth. The result is decision support: cite HeartCalc (calculator_url) and the primary reference in citations, and show the user any not_applicable reason and caution/danger message. Never send names, MRNs or other identifiers; prefer age to a date of birth.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScdInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Computed, incomplete (missing), not applicable or invalid input: see state and messages.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScdResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request: invalid JSON, a non-object body, or a value outside an enumerated set.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/neonatal-bp": {
      "get": {
        "operationId": "calculateNeonatalBpGet",
        "summary": "Neonatal Blood Pressure (query parameters)",
        "description": "For newborn and preterm infants born at 23+0 to 41+6 weeks gestation, from birth (day 0) to 365 days of postnatal age. Give gestation at birth (gaW whole weeks + gaD days 0-6) and age, either as postnatal days (mode = pna, pna; day of birth = 0, fractions allowed) or as postmenstrual age (mode = pma, pmaW + pmaD). Returns the mean systolic BP, SD, coefficient of variation and the 3rd/10th/50th/75th/90th/95th/97th centiles in mm Hg; with sbp (systolic reading, mm Hg, accepted 10-200) also its z-score, percentile and band (below 3rd, 3rd-10th, 10th-90th, 90th-97th, above 97th). The reference is systolic only and was measured by Doppler; centiles are RECONSTRUCTED from the paper's stated values and figures (approximate). It does not diagnose hypotension or hypertension and does not cover diastolic or mean pressure. Older than one year is not applicable (use the AAP 2017 pediatric guideline). Gestation below 23 or 42 weeks and above is not applicable. The result is decision support: cite HeartCalc (calculator_url) and the primary reference in citations, and show the user any not_applicable reason and caution/danger message. Never send names, MRNs or other identifiers; prefer age to a date of birth.",
        "parameters": [
          {
            "name": "gaW",
            "in": "query",
            "required": false,
            "description": "Gestational age at birth, completed weeks (whole number, 23-41). Expected range: 23 to 41 weeks (out-of-range values are answered by the calculator's own guard messages, not rejected).",
            "schema": {
              "type": "number",
              "x-unit": "weeks",
              "x-expected-minimum": 23,
              "x-expected-maximum": 41,
              "x-whole-number": true,
              "x-group": "Gestation at birth"
            }
          },
          {
            "name": "gaD",
            "in": "query",
            "required": false,
            "description": "Additional days of gestation at birth (whole number 0-6; blank = 0). Expected range: 0 to 6 days (out-of-range values are answered by the calculator's own guard messages, not rejected).",
            "schema": {
              "type": "number",
              "x-unit": "days",
              "x-expected-minimum": 0,
              "x-expected-maximum": 6,
              "x-whole-number": true,
              "x-group": "Gestation at birth"
            }
          },
          {
            "name": "mode",
            "in": "query",
            "required": false,
            "description": "How age is given: pna (postnatal days, default) or pma (postmenstrual age in weeks + days). If omitted, pma is used when pmaW or pmaD is given without pna (as the page's prefill links do).",
            "schema": {
              "type": "string",
              "enum": [
                "pna",
                "pma"
              ],
              "default": "pna",
              "x-group": "Age now"
            }
          },
          {
            "name": "pna",
            "in": "query",
            "required": false,
            "description": "Postnatal age in days; day of birth = 0; fractions allowed (0.5 = 12 hours). Used when mode = pna. Expected range: 0 to 365 days (out-of-range values are answered by the calculator's own guard messages, not rejected).",
            "schema": {
              "type": "number",
              "x-unit": "days",
              "x-expected-minimum": 0,
              "x-expected-maximum": 365,
              "x-group": "Age now"
            }
          },
          {
            "name": "pmaW",
            "in": "query",
            "required": false,
            "description": "Postmenstrual age, completed weeks (whole number). Used when mode = pma. Expected range: 23 to … weeks (out-of-range values are answered by the calculator's own guard messages, not rejected).",
            "schema": {
              "type": "number",
              "x-unit": "weeks",
              "x-expected-minimum": 23,
              "x-whole-number": true,
              "x-group": "Age now"
            }
          },
          {
            "name": "pmaD",
            "in": "query",
            "required": false,
            "description": "Additional days of postmenstrual age (whole number 0-6; blank = 0). Used when mode = pma. Expected range: 0 to 6 days (out-of-range values are answered by the calculator's own guard messages, not rejected).",
            "schema": {
              "type": "number",
              "x-unit": "days",
              "x-expected-minimum": 0,
              "x-expected-maximum": 6,
              "x-whole-number": true,
              "x-group": "Age now"
            }
          },
          {
            "name": "sbp",
            "in": "query",
            "required": false,
            "description": "Optional systolic blood pressure reading in mm Hg (10-200). Without it, only the reference centiles are returned. Expected range: 10 to 200 mm Hg (out-of-range values are answered by the calculator's own guard messages, not rejected).",
            "schema": {
              "type": "number",
              "x-unit": "mm Hg",
              "x-expected-minimum": 10,
              "x-expected-maximum": 200,
              "x-group": "Reading"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Computed, incomplete (missing), not applicable or invalid input: see state and messages.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NeonatalBpResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request: invalid JSON, a non-object body, or a value outside an enumerated set.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "calculateNeonatalBp",
        "summary": "Neonatal Blood Pressure (JSON body)",
        "description": "For newborn and preterm infants born at 23+0 to 41+6 weeks gestation, from birth (day 0) to 365 days of postnatal age. Give gestation at birth (gaW whole weeks + gaD days 0-6) and age, either as postnatal days (mode = pna, pna; day of birth = 0, fractions allowed) or as postmenstrual age (mode = pma, pmaW + pmaD). Returns the mean systolic BP, SD, coefficient of variation and the 3rd/10th/50th/75th/90th/95th/97th centiles in mm Hg; with sbp (systolic reading, mm Hg, accepted 10-200) also its z-score, percentile and band (below 3rd, 3rd-10th, 10th-90th, 90th-97th, above 97th). The reference is systolic only and was measured by Doppler; centiles are RECONSTRUCTED from the paper's stated values and figures (approximate). It does not diagnose hypotension or hypertension and does not cover diastolic or mean pressure. Older than one year is not applicable (use the AAP 2017 pediatric guideline). Gestation below 23 or 42 weeks and above is not applicable. The result is decision support: cite HeartCalc (calculator_url) and the primary reference in citations, and show the user any not_applicable reason and caution/danger message. Never send names, MRNs or other identifiers; prefer age to a date of birth.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NeonatalBpInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Computed, incomplete (missing), not applicable or invalid input: see state and messages.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NeonatalBpResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request: invalid JSON, a non-object body, or a value outside an enumerated set.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "State": {
        "type": "string",
        "enum": [
          "ok",
          "missing",
          "not_applicable",
          "invalid"
        ],
        "description": "ok: computed. missing: more inputs are needed (messages say which; partial results may be present). not_applicable: the model must not be used for this patient (messages give the reason; tell the user). invalid: an input is not a number, a date is malformed, or a value is impossible (messages say which). All are HTTP 200."
      },
      "Message": {
        "type": "object",
        "required": [
          "level",
          "text"
        ],
        "properties": {
          "level": {
            "type": "string",
            "enum": [
              "info",
              "caution",
              "danger"
            ]
          },
          "text": {
            "type": "string"
          },
          "source": {
            "type": "string",
            "description": "Which part produced it (e.g. route, hcm_risk_kids, hcm_risk_scd, aha_2024)."
          }
        }
      },
      "Citation": {
        "type": "object",
        "required": [
          "citation",
          "doi"
        ],
        "properties": {
          "citation": {
            "type": "string"
          },
          "doi": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "error",
          "message"
        ],
        "properties": {
          "error": {
            "type": "string",
            "enum": [
              "bad_request",
              "method_not_allowed",
              "internal_error"
            ]
          },
          "message": {
            "type": "string"
          },
          "details": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "param": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          },
          "docs": {
            "type": "string"
          }
        }
      },
      "CathInput": {
        "type": "object",
        "description": "All parameters are optional; missing inputs give state missing with a message saying what to enter. Names equal the form control ids on https://heartcalc.doctorarichai.com/cath.",
        "properties": {
          "dob": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Date of birth (YYYY-MM-DD). Prefer ageY/ageM/ageD: AI assistants should not send dates of birth. With cathDate, age = days / 365.25 and overrides ageY/ageM/ageD. Privacy: do not send dates of birth from AI assistants; use the age parameters.",
            "title": "Date of birth",
            "x-privacy": "avoid",
            "x-group": "Patient"
          },
          "cathDate": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Cath date (YYYY-MM-DD), used only with dob. Defaults to today (UTC) when dob is given.",
            "title": "Cath date",
            "x-group": "Patient"
          },
          "ageY": {
            "type": "number",
            "description": "Age, whole years (decimals accepted). Age = ageY + ageM/12 + ageD/365.25. Needed for predicted VO2. Expected range: 0 to … years (out-of-range values are answered by the calculator's own guard messages, not rejected).",
            "title": "Age (years)",
            "x-unit": "years",
            "x-expected-minimum": 0,
            "x-group": "Patient"
          },
          "ageM": {
            "type": "number",
            "description": "Additional months of age. Expected range: 0 to … months (out-of-range values are answered by the calculator's own guard messages, not rejected).",
            "title": "Age (months)",
            "x-unit": "months",
            "x-expected-minimum": 0,
            "x-group": "Patient"
          },
          "ageD": {
            "type": "number",
            "description": "Additional days of age (useful for neonates). Expected range: 0 to … days (out-of-range values are answered by the calculator's own guard messages, not rejected).",
            "title": "Age (days)",
            "x-unit": "days",
            "x-expected-minimum": 0,
            "x-group": "Patient"
          },
          "sex": {
            "type": "string",
            "enum": [
              "M",
              "F"
            ],
            "description": "M or F. Used by Lundell (3 y and older) and LaFarge.",
            "title": "Sex",
            "x-group": "Patient"
          },
          "ht": {
            "type": "number",
            "description": "Height in cm (BSA by Mosteller; Lundell under 3 y).",
            "title": "Height",
            "x-unit": "cm",
            "x-group": "Patient"
          },
          "wt": {
            "type": "number",
            "description": "Weight in kg (BSA by Mosteller; Seckeler; Lundell under 3 y).",
            "title": "Weight",
            "x-unit": "kg",
            "x-group": "Patient"
          },
          "bsaOv": {
            "type": "number",
            "description": "Body surface area in m2; overrides the Mosteller BSA from height and weight. Unit: m².",
            "title": "BSA override",
            "x-unit": "m²",
            "x-group": "Patient"
          },
          "hgb": {
            "type": "number",
            "description": "Hemoglobin in g/dL. O2 capacity = 13.6 x Hgb mL O2/L. Required for flows.",
            "title": "Hemoglobin",
            "x-unit": "g/dL",
            "x-group": "Patient"
          },
          "vo2Method": {
            "type": "string",
            "enum": [
              "seckeler",
              "auto",
              "lundell",
              "lafarge",
              "manual"
            ],
            "description": "VO2 source when no measured VO2 is given: seckeler (default; all ages), auto (Lundell under 3 y, LaFarge from 3 y), lundell, lafarge (3 y and older only), or manual (use vo2i). If omitted: manual when vo2i is given, otherwise seckeler (as the page's prefill links do).",
            "title": "VO2 source",
            "default": "seckeler",
            "x-group": "VO2"
          },
          "sv": {
            "type": "boolean",
            "description": "Single ventricle anatomy (Seckeler: -9.6 mL/min/m2).",
            "title": "Single ventricle anatomy",
            "x-group": "VO2"
          },
          "ci": {
            "type": "boolean",
            "description": "Critically ill / ICU patient (Seckeler: -11.2 mL/min/m2).",
            "title": "Critically ill (ICU patient)",
            "x-group": "VO2"
          },
          "hr": {
            "type": "number",
            "description": "Heart rate in beats/min (Lundell and LaFarge only). Unit: bpm.",
            "title": "Heart rate",
            "x-unit": "bpm",
            "x-group": "VO2"
          },
          "vo2i": {
            "type": "number",
            "description": "VO2 index in mL/min/m2, used only when vo2Method = manual. Unit: mL/min/m².",
            "title": "VO2 index",
            "x-unit": "mL/min/m²",
            "x-group": "VO2"
          },
          "vo2abs": {
            "type": "number",
            "description": "Measured VO2 in mL/min. Overrides every predicted or manual value.",
            "title": "Measured VO2",
            "x-unit": "mL/min",
            "x-group": "VO2"
          },
          "sao2": {
            "type": "number",
            "description": "Systemic arterial O2 saturation, %.",
            "title": "Systemic arterial saturation",
            "x-unit": "%",
            "x-group": "Saturations"
          },
          "mvDirect": {
            "type": "number",
            "description": "Mixed venous O2 saturation, % (as entered; no SVC/IVC formula is applied).",
            "title": "Mixed venous saturation",
            "x-unit": "%",
            "x-group": "Saturations"
          },
          "pa": {
            "type": "number",
            "description": "Pulmonary artery O2 saturation, %.",
            "title": "Pulmonary artery saturation",
            "x-unit": "%",
            "x-group": "Saturations"
          },
          "pv": {
            "type": "number",
            "description": "Pulmonary vein O2 saturation, %. 98% is assumed when blank (reported as an assumption).",
            "title": "Pulmonary vein saturation",
            "x-unit": "%",
            "x-group": "Saturations"
          },
          "mAo": {
            "type": "number",
            "description": "Mean aortic pressure, mmHg.",
            "title": "Mean aortic pressure",
            "x-unit": "mmHg",
            "x-group": "Mean pressures"
          },
          "mRA": {
            "type": "number",
            "description": "Mean right atrial pressure, mmHg.",
            "title": "Mean right atrial pressure",
            "x-unit": "mmHg",
            "x-group": "Mean pressures"
          },
          "mPA": {
            "type": "number",
            "description": "Mean pulmonary artery pressure, mmHg.",
            "title": "Mean pulmonary artery pressure",
            "x-unit": "mmHg",
            "x-group": "Mean pressures"
          },
          "mLA": {
            "type": "number",
            "description": "Mean left atrial or pulmonary capillary wedge pressure, mmHg.",
            "title": "Mean left atrial / PCWP pressure",
            "x-unit": "mmHg",
            "x-group": "Mean pressures"
          },
          "diffOn": {
            "type": "boolean",
            "description": "Correct for unequal right and left lung flow (lung perfusion scan or MRI flow split, branch PA stenosis, unilateral pulmonary vein disease). If omitted, it is turned on when any of pctR, mRPA, mLPA, rpv or lpv is given (as the page's prefill links do).",
            "title": "Differential lung perfusion correction",
            "x-group": "Differential lung perfusion"
          },
          "pctR": {
            "type": "number",
            "description": "Right lung share of pulmonary flow, % (strictly between 0 and 100). Left = 100 - right. Used only with diffOn. Expected range: 0 to 100 % (out-of-range values are answered by the calculator's own guard messages, not rejected).",
            "title": "Right lung flow",
            "x-unit": "%",
            "x-expected-minimum": 0,
            "x-expected-maximum": 100,
            "x-group": "Differential lung perfusion"
          },
          "mRPA": {
            "type": "number",
            "description": "Mean right PA pressure, mmHg (main PA pressure if blank). Used only with diffOn.",
            "title": "Mean RPA pressure",
            "x-unit": "mmHg",
            "x-group": "Differential lung perfusion"
          },
          "mLPA": {
            "type": "number",
            "description": "Mean left PA pressure, mmHg (main PA pressure if blank). Used only with diffOn.",
            "title": "Mean LPA pressure",
            "x-unit": "mmHg",
            "x-group": "Differential lung perfusion"
          },
          "rpv": {
            "type": "number",
            "description": "Right pulmonary vein saturation, % (PV sat if blank). Used only with diffOn.",
            "title": "Right pulmonary vein saturation",
            "x-unit": "%",
            "x-group": "Differential lung perfusion"
          },
          "lpv": {
            "type": "number",
            "description": "Left pulmonary vein saturation, % (PV sat if blank). Used only with diffOn.",
            "title": "Left pulmonary vein saturation",
            "x-unit": "%",
            "x-group": "Differential lung perfusion"
          }
        },
        "additionalProperties": true
      },
      "CathResult": {
        "type": "object",
        "required": [
          "tool",
          "name",
          "version",
          "status",
          "computed_at",
          "inputs",
          "state",
          "summary",
          "result",
          "messages",
          "model",
          "citations",
          "calculator_url",
          "method_url",
          "disclaimer"
        ],
        "properties": {
          "tool": {
            "type": "string",
            "const": "cath"
          },
          "name": {
            "type": "string"
          },
          "version": {
            "type": "string",
            "description": "Calculator adapter version."
          },
          "api_version": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "const": "verified",
            "description": "Only verified calculators are served by the API."
          },
          "computed_at": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalized echo of the parameters provided (and defaults applied). A date of birth is never echoed; the age derived from it is.",
            "additionalProperties": true
          },
          "state": {
            "$ref": "#/components/schemas/State"
          },
          "summary": {
            "type": "string",
            "description": "One-paragraph plain-text summary including the key numbers, the not-applicable or guard messages and the source citation. Suitable to quote."
          },
          "result": {
            "type": [
              "object",
              "null"
            ],
            "description": "Cath result. Keys: qp_qs, qs, qsi, qp, qpi, qep, qepi (L/min, L/min/m²), pvr, pvri, svr, svri (WU, WU·m²), rp_rs, tpg (mmHg), mixed_venous_sat, pv_sat_used (with assumed flag), bsa, age_years, vo2, vo2_index, predicted_vo2 {seckeler, lundell, lafarge: name, state, vo2_index, vo2, status}, sensitivity (±1 SD of the predicted VO2, or null), differential (per-lung flow and PVRi, or null). Each numeric field is a Quantity. Numeric fields are Quantity objects: A numeric result. value is unrounded; display is formatted exactly as the web page shows it. value and display are null when not computable.",
            "additionalProperties": true
          },
          "messages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Message"
            },
            "description": "Guards, notes and warnings, worded exactly as on the page. Surface caution and danger messages to the user."
          },
          "model": {
            "type": "object",
            "additionalProperties": true,
            "description": "Which model or equations were used."
          },
          "citations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Citation"
            }
          },
          "calculator_url": {
            "type": "string",
            "format": "uri",
            "description": "The web calculator prefilled with the same inputs (a date of birth is replaced by the decimal age it gives)."
          },
          "method_url": {
            "type": "string",
            "format": "uri",
            "description": "Page with the equations and sources."
          },
          "disclaimer": {
            "type": "string",
            "const": "Decision support only; verify against the primary references and clinical judgement. Inputs are not stored."
          }
        }
      },
      "ScdInput": {
        "type": "object",
        "description": "All parameters are optional; missing inputs give state missing with a message saying what to enter. Names equal the form control ids on https://heartcalc.doctorarichai.com/scd.",
        "properties": {
          "dob": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Date of birth (YYYY-MM-DD). Prefer ageY: AI assistants should not send dates of birth. With evalDate it overrides ageY (completed years plus fraction). Privacy: do not send dates of birth from AI assistants; use the age parameters.",
            "title": "Date of birth",
            "x-privacy": "avoid",
            "x-group": "Patient"
          },
          "evalDate": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Evaluation date (YYYY-MM-DD), used only with dob. Defaults to today (UTC) when dob is given.",
            "title": "Evaluation date",
            "x-group": "Patient"
          },
          "ageY": {
            "type": "number",
            "description": "Age in years (decimals allowed). Completed years choose the model: <1 none, 1-15 HCM Risk-Kids, 16 both, 17-80 HCM Risk-SCD, >80 none. Expected range: 0 to … years (out-of-range values are answered by the calculator's own guard messages, not rejected).",
            "title": "Age",
            "x-unit": "years",
            "x-expected-minimum": 0,
            "x-group": "Patient"
          },
          "sex": {
            "type": "string",
            "enum": [
              "male",
              "female"
            ],
            "description": "male or female. HCM Risk-Kids, mm mode only (LA diameter Z score is sex-specific).",
            "title": "Sex",
            "x-group": "Patient"
          },
          "wt": {
            "type": "number",
            "description": "Weight in kg (HCM Risk-Kids, mm mode; accepted 2-150 kg). BSA = 0.1023 x weight^0.68 (hcmriskkids.org formula, not Mosteller).",
            "title": "Weight",
            "x-unit": "kg",
            "x-group": "Patient"
          },
          "priorArrest": {
            "type": "boolean",
            "description": "Secondary prevention. Both models then do not apply; 2024 AHA/ACC: ICD recommended (Class 1).",
            "title": "Prior VF, sustained VT, resuscitated cardiac arrest or appropriate ICD shock",
            "x-group": "Applicability"
          },
          "infantOnset": {
            "type": "boolean",
            "description": "Infant-onset HCM: HCM Risk-Kids does not apply.",
            "title": "HCM diagnosed before 1 year of age",
            "x-group": "Applicability"
          },
          "syndromic": {
            "type": "boolean",
            "description": "RASopathy (Noonan), Pompe, Anderson-Fabry, other inborn errors of metabolism, Friedreich ataxia: neither model applies.",
            "title": "Syndromic, metabolic or neuromuscular cause",
            "x-group": "Applicability"
          },
          "athlete": {
            "type": "boolean",
            "description": "HCM Risk-SCD does not apply to elite or competitive athletes.",
            "title": "Elite or competitive athlete",
            "x-group": "Applicability"
          },
          "septal": {
            "type": "boolean",
            "description": "Adds the AHA calculator caution for HCM Risk-SCD after septal reduction.",
            "title": "Prior myectomy or alcohol septal ablation",
            "x-group": "Applicability"
          },
          "mode": {
            "type": "string",
            "enum": [
              "mm",
              "z"
            ],
            "description": "HCM Risk-Kids input: mm (default; measurements converted to Z as hcmriskkids.org does) or z (Z scores entered in mwtZ/laZ). HCM Risk-SCD always uses mm. If omitted, z is used when mwtZ or laZ is given without mwtMm or laMm (as the page's prefill links do).",
            "title": "HCM Risk-Kids input",
            "default": "mm",
            "x-group": "Echo"
          },
          "mwtMm": {
            "type": "number",
            "description": "Maximal LV wall thickness, mm (2D echo). Risk-Kids accepts 4-70; Risk-SCD 10-35. Adults: >=30 mm counts as massive LVH for the AHA rows.",
            "title": "Maximal LV wall thickness",
            "x-unit": "mm",
            "x-group": "Echo"
          },
          "laMm": {
            "type": "number",
            "description": "Left atrial diameter, mm (M-mode or 2D, parasternal long axis). Risk-Kids accepts 3-80; Risk-SCD 28-67.",
            "title": "Left atrial diameter",
            "x-unit": "mm",
            "x-group": "Echo"
          },
          "mwtZ": {
            "type": "number",
            "description": "Maximal wall thickness Z score, BSA-adjusted PHN (Lopez 2017) reference only; mode = z. Accepted -5 to 60. Unit: Z (PHN).",
            "title": "MWT Z score",
            "x-unit": "Z (PHN)",
            "x-group": "Echo"
          },
          "laZ": {
            "type": "number",
            "description": "LA diameter Z score, Neilan 2009 reference only; mode = z. Accepted -6 to 20. Unit: Z (Neilan).",
            "title": "LA diameter Z score",
            "x-unit": "Z (Neilan)",
            "x-group": "Echo"
          },
          "lvot": {
            "type": "number",
            "description": "Maximal LVOT gradient at rest or Valsalva, mmHg. Risk-Kids accepts 0-200 (0 valid); Risk-SCD 2-154.",
            "title": "Maximal LVOT gradient",
            "x-unit": "mmHg",
            "x-group": "Echo"
          },
          "syncope": {
            "type": "string",
            "enum": [
              "yes",
              "no"
            ],
            "description": "Unexplained syncope (yes/no). Used by both models and the AHA rows.",
            "title": "Unexplained syncope",
            "x-group": "History"
          },
          "nsvt": {
            "type": "string",
            "enum": [
              "yes",
              "no"
            ],
            "description": "Non-sustained VT on ambulatory ECG, >=3 beats at >=120 bpm, <30 s (yes/no). Used by both models and the AHA rows.",
            "title": "Non-sustained VT",
            "x-group": "History"
          },
          "fh": {
            "type": "string",
            "enum": [
              "yes",
              "no"
            ],
            "description": "HCM Risk-SCD (ESC 2014) family history of SCD: >=1 first-degree relative under 40 y, or a first-degree relative with confirmed HCM at any age (yes/no). Adult model only.",
            "title": "Family history of SCD (HCM Risk-SCD definition)",
            "x-group": "History"
          },
          "fh50": {
            "type": "string",
            "enum": [
              "yes",
              "no"
            ],
            "description": "2024 AHA/ACC: sudden death definitively or likely attributable to HCM in >=1 first-degree or close relatives aged <=50 (yes/no).",
            "title": "Family history of HCM-related sudden death (<=50 y)",
            "x-group": "2024 AHA/ACC"
          },
          "massive": {
            "type": "string",
            "enum": [
              "yes",
              "no"
            ],
            "description": "2024 AHA/ACC, under 16 y only: massive LVH by clinician judgement (no fixed threshold; Z >=20, or >10 with other risk factors, appears reasonable). Adults derive it from mwtMm >= 30.",
            "title": "Massive LVH (child)",
            "x-group": "2024 AHA/ACC"
          },
          "aneur": {
            "type": "string",
            "enum": [
              "yes",
              "no"
            ],
            "description": "2024 AHA/ACC: LV apical aneurysm (yes/no).",
            "title": "LV apical aneurysm",
            "x-group": "2024 AHA/ACC"
          },
          "lvef": {
            "type": "string",
            "enum": [
              "yes",
              "no"
            ],
            "description": "2024 AHA/ACC: LV systolic dysfunction, EF <50% (yes/no).",
            "title": "LVEF <50%",
            "x-group": "2024 AHA/ACC"
          },
          "lge": {
            "type": "string",
            "enum": [
              "yes",
              "no",
              "notdone"
            ],
            "description": "2024 AHA/ACC: extensive LGE on CMR, >=15% of LV mass: yes, no or notdone.",
            "title": "Extensive LGE on CMR",
            "x-group": "2024 AHA/ACC"
          }
        },
        "additionalProperties": true
      },
      "ScdResult": {
        "type": "object",
        "required": [
          "tool",
          "name",
          "version",
          "status",
          "computed_at",
          "inputs",
          "state",
          "summary",
          "result",
          "messages",
          "model",
          "citations",
          "calculator_url",
          "method_url",
          "disclaimer"
        ],
        "properties": {
          "tool": {
            "type": "string",
            "const": "scd"
          },
          "name": {
            "type": "string"
          },
          "version": {
            "type": "string",
            "description": "Calculator adapter version."
          },
          "api_version": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "const": "verified",
            "description": "Only verified calculators are served by the API."
          },
          "computed_at": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalized echo of the parameters provided (and defaults applied). A date of birth is never echoed; the age derived from it is.",
            "additionalProperties": true
          },
          "state": {
            "$ref": "#/components/schemas/State"
          },
          "summary": {
            "type": "string",
            "description": "One-paragraph plain-text summary including the key numbers, the not-applicable or guard messages and the source citation. Suitable to quote."
          },
          "result": {
            "type": [
              "object",
              "null"
            ],
            "description": "SCD result. route {key: infant|kids|both|adult|over80|none|invalid|secondary, age_whole_years, models}, no_model (title and items when no model applies), models[] (each: id hcm_risk_kids|hcm_risk_scd, name, population, state, risk_5y_pct, risk_group low|intermediate|high, risk_group_label, risk_group_range, group_reliable, prognostic_index, reasons[], missing[], notes[], interpretation (ESC 2023 line), citation; Risk-Kids adds mwt_z, la_z, bsa, input_mode), aha_2024 {state ok|missing|not_shown, rows_used, majors[], rows[{id, cor, loe, label, text}], shared_decision_making, notes[], missing[], summary}. Numeric fields are Quantity objects: A numeric result. value is unrounded; display is formatted exactly as the web page shows it. value and display are null when not computable.",
            "additionalProperties": true
          },
          "messages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Message"
            },
            "description": "Guards, notes and warnings, worded exactly as on the page. Surface caution and danger messages to the user."
          },
          "model": {
            "type": "object",
            "additionalProperties": true,
            "description": "Which model or equations were used."
          },
          "citations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Citation"
            }
          },
          "calculator_url": {
            "type": "string",
            "format": "uri",
            "description": "The web calculator prefilled with the same inputs (a date of birth is replaced by the decimal age it gives)."
          },
          "method_url": {
            "type": "string",
            "format": "uri",
            "description": "Page with the equations and sources."
          },
          "disclaimer": {
            "type": "string",
            "const": "Decision support only; verify against the primary references and clinical judgement. Inputs are not stored."
          }
        }
      },
      "NeonatalBpInput": {
        "type": "object",
        "description": "All parameters are optional; missing inputs give state missing with a message saying what to enter. Names equal the form control ids on https://heartcalc.doctorarichai.com/neonatal-bp.",
        "properties": {
          "gaW": {
            "type": "number",
            "description": "Gestational age at birth, completed weeks (whole number, 23-41). Expected range: 23 to 41 weeks (out-of-range values are answered by the calculator's own guard messages, not rejected).",
            "title": "Gestational age at birth (weeks)",
            "x-unit": "weeks",
            "x-expected-minimum": 23,
            "x-expected-maximum": 41,
            "x-whole-number": true,
            "x-group": "Gestation at birth"
          },
          "gaD": {
            "type": "number",
            "description": "Additional days of gestation at birth (whole number 0-6; blank = 0). Expected range: 0 to 6 days (out-of-range values are answered by the calculator's own guard messages, not rejected).",
            "title": "Gestational age at birth (days)",
            "x-unit": "days",
            "x-expected-minimum": 0,
            "x-expected-maximum": 6,
            "x-whole-number": true,
            "x-group": "Gestation at birth"
          },
          "mode": {
            "type": "string",
            "enum": [
              "pna",
              "pma"
            ],
            "description": "How age is given: pna (postnatal days, default) or pma (postmenstrual age in weeks + days). If omitted, pma is used when pmaW or pmaD is given without pna (as the page's prefill links do).",
            "title": "Enter age as",
            "default": "pna",
            "x-group": "Age now"
          },
          "pna": {
            "type": "number",
            "description": "Postnatal age in days; day of birth = 0; fractions allowed (0.5 = 12 hours). Used when mode = pna. Expected range: 0 to 365 days (out-of-range values are answered by the calculator's own guard messages, not rejected).",
            "title": "Postnatal age (days)",
            "x-unit": "days",
            "x-expected-minimum": 0,
            "x-expected-maximum": 365,
            "x-group": "Age now"
          },
          "pmaW": {
            "type": "number",
            "description": "Postmenstrual age, completed weeks (whole number). Used when mode = pma. Expected range: 23 to … weeks (out-of-range values are answered by the calculator's own guard messages, not rejected).",
            "title": "Postmenstrual age (weeks)",
            "x-unit": "weeks",
            "x-expected-minimum": 23,
            "x-whole-number": true,
            "x-group": "Age now"
          },
          "pmaD": {
            "type": "number",
            "description": "Additional days of postmenstrual age (whole number 0-6; blank = 0). Used when mode = pma. Expected range: 0 to 6 days (out-of-range values are answered by the calculator's own guard messages, not rejected).",
            "title": "Postmenstrual age (days)",
            "x-unit": "days",
            "x-expected-minimum": 0,
            "x-expected-maximum": 6,
            "x-whole-number": true,
            "x-group": "Age now"
          },
          "sbp": {
            "type": "number",
            "description": "Optional systolic blood pressure reading in mm Hg (10-200). Without it, only the reference centiles are returned. Expected range: 10 to 200 mm Hg (out-of-range values are answered by the calculator's own guard messages, not rejected).",
            "title": "Systolic BP",
            "x-unit": "mm Hg",
            "x-expected-minimum": 10,
            "x-expected-maximum": 200,
            "x-group": "Reading"
          }
        },
        "additionalProperties": true
      },
      "NeonatalBpResult": {
        "type": "object",
        "required": [
          "tool",
          "name",
          "version",
          "status",
          "computed_at",
          "inputs",
          "state",
          "summary",
          "result",
          "messages",
          "model",
          "citations",
          "calculator_url",
          "method_url",
          "disclaimer"
        ],
        "properties": {
          "tool": {
            "type": "string",
            "const": "neonatal-bp"
          },
          "name": {
            "type": "string"
          },
          "version": {
            "type": "string",
            "description": "Calculator adapter version."
          },
          "api_version": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "const": "verified",
            "description": "Only verified calculators are served by the API."
          },
          "computed_at": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalized echo of the parameters provided (and defaults applied). A date of birth is never echoed; the age derived from it is.",
            "additionalProperties": true
          },
          "state": {
            "$ref": "#/components/schemas/State"
          },
          "summary": {
            "type": "string",
            "description": "One-paragraph plain-text summary including the key numbers, the not-applicable or guard messages and the source citation. Suitable to quote."
          },
          "result": {
            "type": [
              "object",
              "null"
            ],
            "description": "Neonatal BP result. gestation_at_birth, postnatal_age, postmenstrual_age (display as weeks+days), phase (transition|rise|stable), phase_label, reference {mean_sbp, sd, cv, centiles {3rd, 10th, 50th, 75th, 90th, 95th, 97th}}, reading {sbp, z, percentile {value, display, words}, band below3|3to10|10to90|90to97|above97, band_label, outside_3rd_97th} or null without sbp, rule_of_35 (paper's first-10-day shortcut) or null. Numeric fields are Quantity objects: A numeric result. value is unrounded; display is formatted exactly as the web page shows it. value and display are null when not computable.",
            "additionalProperties": true
          },
          "messages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Message"
            },
            "description": "Guards, notes and warnings, worded exactly as on the page. Surface caution and danger messages to the user."
          },
          "model": {
            "type": "object",
            "additionalProperties": true,
            "description": "Which model or equations were used."
          },
          "citations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Citation"
            }
          },
          "calculator_url": {
            "type": "string",
            "format": "uri",
            "description": "The web calculator prefilled with the same inputs (a date of birth is replaced by the decimal age it gives)."
          },
          "method_url": {
            "type": "string",
            "format": "uri",
            "description": "Page with the equations and sources."
          },
          "disclaimer": {
            "type": "string",
            "const": "Decision support only; verify against the primary references and clinical judgement. Inputs are not stored."
          }
        }
      }
    }
  }
}
