{
  "openapi": "3.1.1",
  "info": {
    "title": "Ohmforge RF Calculator: Antenna, Link Budget & VSWR API",
    "version": "1.0.0",
    "summary": "Dipole and quarter-wave lengths, free-space path loss and link margin, VSWR ↔ return loss.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://ohmforgerfcalculator.usefulweb.app"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Dipole and quarter-wave lengths, free-space path loss and link margin, VSWR ↔ return loss.",
        "description": "Three everyday radio calculations in one place: antenna element lengths for a frequency (half-wave dipole, quarter-wave monopole, coax stubs), a Friis link budget with free-space path loss, received power, margin and the maximum range for the fade margin you want, and the conversions between VSWR, return loss, reflection coefficient and mismatch loss — also straight from a load impedance.\n\nMethodology:\n- Wavelength λ = c/f with c = 299 792 458 m/s. Half-wave dipole = λ/2 × k × VF and quarter-wave monopole = λ/4 × k × VF, where k is the end-effect factor (0.95 reproduces the ARRL rule 468/f(MHz) ft within 0.2 %) and VF the velocity factor of the element. Coax stubs use the cable's velocity factor. All lengths are starting points: trim the real antenna with an analyser.\n- Free-space path loss FSPL = 20·log10(4π·d·f/c) between isotropic antennas (ITU-R P.525). Friis link budget: received power = Ptx − Ltx + Gtx − FSPL − Lother + Grx − Lrx; margin = received power − sensitivity. The maximum range is the free-space distance at which the margin equals the fade margin you ask for.\n- The first Fresnel zone radius at mid-path is ½·√(λ·d); keeping 60 % of it free of obstacles is the usual rule for line-of-sight links.\n- Mismatch: |Γ| = (VSWR − 1)/(VSWR + 1) = 10^(−RL/20); Γ = (ZL − Z0)/(ZL + Z0) for a load impedance; mismatch loss = −10·log10(1 − |Γ|²); reflected power = |Γ|².\n\nFree-space values: real links lose more to the ground, buildings, foliage and multipath, and the received power fluctuates (fading). Transmit power and antenna gain limits are set by your country's radio regulations — this calculator gives no licensing or legal advice.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "ohmforge_rf_calculator",
        "x-owner-app": "ohmforge",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OhmforgeRfCalculatorInput"
              },
              "examples": {
                "example1": {
                  "summary": "Wi-Fi link: 2.4 GHz over 100 m",
                  "value": {
                    "mode": "link",
                    "frequencyMHz": 2400,
                    "distanceM": 100,
                    "txPowerDbm": 20,
                    "txGainDbi": 2,
                    "rxGainDbi": 2,
                    "txCableLossDb": 1,
                    "rxCableLossDb": 1,
                    "sensitivityDbm": -90,
                    "fadeMarginDb": 10
                  }
                },
                "example2": {
                  "summary": "Dipole for the 20 m band (14.2 MHz)",
                  "value": {
                    "mode": "antenna",
                    "frequencyMHz": 14.2,
                    "endEffect": 0.95,
                    "velocityFactor": 1,
                    "cableVelocityFactor": 0.66
                  }
                },
                "example3": {
                  "summary": "VSWR 2:1 → return loss and mismatch loss",
                  "value": {
                    "mode": "mismatch",
                    "mismatchFrom": "vswr",
                    "value": 2
                  }
                },
                "example4": {
                  "summary": "75 Ω antenna on a 50 Ω radio",
                  "value": {
                    "mode": "mismatch",
                    "mismatchFrom": "impedance",
                    "loadR": 75,
                    "loadX": 0,
                    "z0": 50
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OhmforgeRfCalculatorResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "OhmforgeRfCalculatorInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "mode": {
            "title": "Calculation",
            "type": "string",
            "enum": [
              "link",
              "antenna",
              "mismatch"
            ],
            "default": "link"
          },
          "frequencyMHz": {
            "title": "Frequency",
            "description": "Antenna lengths and link budget.",
            "type": "number",
            "minimum": 0.000001,
            "maximum": 1000000,
            "default": 2400,
            "x-unit": "MHz"
          },
          "distanceM": {
            "title": "Distance",
            "description": "Link budget: distance between the antennas.",
            "type": "number",
            "minimum": 0.001,
            "maximum": 10000000000,
            "default": 100,
            "x-unit": "m"
          },
          "txPowerDbm": {
            "title": "Transmit power",
            "description": "20 dBm = 100 mW, 30 dBm = 1 W.",
            "type": "number",
            "minimum": -200,
            "maximum": 100,
            "default": 20,
            "x-unit": "dBm"
          },
          "txGainDbi": {
            "title": "Transmit antenna gain",
            "type": "number",
            "minimum": -50,
            "maximum": 80,
            "default": 2,
            "x-unit": "dBi"
          },
          "rxGainDbi": {
            "title": "Receive antenna gain",
            "type": "number",
            "minimum": -50,
            "maximum": 80,
            "default": 2,
            "x-unit": "dBi"
          },
          "txCableLossDb": {
            "title": "Transmit cable and connector loss",
            "type": "number",
            "minimum": 0,
            "maximum": 200,
            "default": 0,
            "x-unit": "dB"
          },
          "rxCableLossDb": {
            "title": "Receive cable and connector loss",
            "type": "number",
            "minimum": 0,
            "maximum": 200,
            "default": 0,
            "x-unit": "dB"
          },
          "otherLossDb": {
            "title": "Other losses",
            "description": "Walls, bodies, foliage, polarisation mismatch, rain — whatever free space does not include.",
            "type": "number",
            "minimum": 0,
            "maximum": 300,
            "default": 0,
            "x-unit": "dB"
          },
          "sensitivityDbm": {
            "title": "Receiver sensitivity",
            "description": "Weakest signal the receiver decodes at the data rate you use (datasheet).",
            "type": "number",
            "minimum": -250,
            "maximum": 50,
            "default": -90,
            "x-unit": "dBm"
          },
          "fadeMarginDb": {
            "title": "Fade margin you want",
            "description": "Reserve for fading and obstacles; the maximum range is computed for it.",
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "default": 10,
            "x-unit": "dB"
          },
          "endEffect": {
            "title": "End-effect factor (antenna)",
            "description": "Shortening of a thin wire element because of the end capacitance; 0.95 is the usual approximation (thicker elements need less).",
            "type": "number",
            "minimum": 0.5,
            "maximum": 1,
            "default": 0.95
          },
          "velocityFactor": {
            "title": "Velocity factor of the element (antenna)",
            "description": "1 for bare wire in air; insulated wire about 0.95–0.98.",
            "type": "number",
            "minimum": 0.1,
            "maximum": 1,
            "default": 1
          },
          "cableVelocityFactor": {
            "title": "Velocity factor of the coax (stubs)",
            "description": "Solid PE coax (RG-58, RG-213) 0.66, foam PE about 0.80–0.85.",
            "type": "number",
            "minimum": 0.1,
            "maximum": 1,
            "default": 0.66
          },
          "mismatchFrom": {
            "title": "You know (mismatch)",
            "type": "string",
            "enum": [
              "vswr",
              "returnLoss",
              "gamma",
              "impedance"
            ],
            "default": "vswr"
          },
          "value": {
            "title": "Value (VSWR, return loss or |Γ|)",
            "description": "VSWR ≥ 1, return loss in dB as a positive number, or |Γ| from 0 to 1.",
            "type": "number",
            "minimum": 0,
            "maximum": 1000000,
            "default": 2
          },
          "loadR": {
            "title": "Load resistance R",
            "description": "Mismatch from a load impedance.",
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000,
            "default": 75,
            "x-unit": "Ω"
          },
          "loadX": {
            "title": "Load reactance X",
            "description": "Positive = inductive, negative = capacitive.",
            "type": "number",
            "minimum": -1000000000,
            "maximum": 1000000000,
            "default": 0,
            "x-unit": "Ω"
          },
          "z0": {
            "title": "Reference impedance Z0",
            "type": "number",
            "minimum": 0.001,
            "maximum": 1000000,
            "default": 50,
            "x-unit": "Ω"
          }
        },
        "required": []
      },
      "OhmforgeRfCalculatorResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "required": [
              "mode",
              "antenna",
              "link",
              "mismatch"
            ],
            "additionalProperties": false,
            "properties": {
              "mode": {
                "type": "string",
                "enum": [
                  "antenna",
                  "link",
                  "mismatch"
                ]
              },
              "antenna": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "properties": {
                  "frequencyHz": {
                    "type": "number"
                  },
                  "wavelengthM": {
                    "type": "number"
                  },
                  "endEffect": {
                    "type": "number"
                  },
                  "velocityFactor": {
                    "type": "number"
                  },
                  "cableVelocityFactor": {
                    "type": "number"
                  },
                  "shortening": {
                    "type": "number"
                  },
                  "halfWaveElectricalM": {
                    "type": "number"
                  },
                  "dipoleLengthM": {
                    "type": "number"
                  },
                  "dipoleLegM": {
                    "type": "number"
                  },
                  "quarterWaveMonopoleM": {
                    "type": "number"
                  },
                  "rule468M": {
                    "type": "number"
                  },
                  "fullWaveLoopM": {
                    "type": "number"
                  },
                  "quarterWaveStubM": {
                    "type": "number"
                  },
                  "halfWaveStubM": {
                    "type": "number"
                  }
                }
              },
              "link": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "properties": {
                  "frequencyHz": {
                    "type": "number"
                  },
                  "distanceM": {
                    "type": "number"
                  },
                  "wavelengthM": {
                    "type": "number"
                  },
                  "fsplDb": {
                    "type": "number"
                  },
                  "eirpDbm": {
                    "type": "number"
                  },
                  "rxPowerDbm": {
                    "type": "number"
                  },
                  "rxPowerW": {
                    "type": "number"
                  },
                  "sensitivityDbm": {
                    "type": "number"
                  },
                  "marginDb": {
                    "type": "number"
                  },
                  "fadeMarginDb": {
                    "type": "number"
                  },
                  "maxRangeM": {
                    "type": "number"
                  },
                  "maxRangeNoMarginM": {
                    "type": "number"
                  },
                  "fresnelRadiusM": {
                    "type": "number"
                  },
                  "fresnel60M": {
                    "type": "number"
                  },
                  "meetsFadeMargin": {
                    "type": "boolean"
                  },
                  "lines": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "properties": {
                        "item": {
                          "type": "string"
                        },
                        "db": {
                          "type": "number"
                        },
                        "levelDbm": {
                          "type": "number"
                        }
                      }
                    }
                  },
                  "distanceTable": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "properties": {
                        "distanceM": {
                          "type": "number"
                        },
                        "rxPowerDbm": {
                          "type": "number"
                        },
                        "marginDb": {
                          "type": "number"
                        }
                      }
                    }
                  }
                }
              },
              "mismatch": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "properties": {
                  "from": {
                    "type": "string"
                  },
                  "gammaMagnitude": {
                    "type": "number"
                  },
                  "gammaReal": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "gammaImag": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "gammaAngleDeg": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "vswr": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "description": "null = infinite (total reflection)."
                  },
                  "returnLossDb": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "description": "null = infinite (perfect match)."
                  },
                  "mismatchLossDb": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "reflectedPercent": {
                    "type": "number"
                  },
                  "transmittedPercent": {
                    "type": "number"
                  },
                  "z0": {
                    "type": [
                      "number",
                      "null"
                    ]
                  }
                }
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}