{
  "openapi": "3.1.1",
  "info": {
    "title": "Truss & Frame Solver (Stiffness Method) API",
    "version": "1.0.0",
    "summary": "Forces, moments, reactions and deflections of 2-D/3-D trusses, beams and frames.",
    "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://prooflinetrussframesolver.usefulweb.site"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Forces, moments, reactions and deflections of 2-D/3-D trusses, beams and frames.",
        "description": "Describe a truss, a continuous beam or a 2-D frame line by line — nodes, a steel or timber section, members with optional hinges, pin, roller and fixed supports, springs, point loads and distributed loads — and get the node displacements, the support reactions, the axial force, shear and bending moment of every member, the stress and a utilisation check against the yield strength, an Euler buckling check of the compression members and an equilibrium check. Diagrams show the member forces in colour, the deformed shape and the bending moments. Solved with the direct stiffness method and a sparse Cholesky solver; part of the Proofline math notebook. A checking and teaching model, not certified design.\n\nMethodology:\n- Direct stiffness method: bar elements (axial stiffness EA/L along the member direction) for trusses in 2-D and 3-D; Euler–Bernoulli beam-column elements (EA/L, 12EI/L³, 6EI/L², 4EI/L, 2EI/L) for 2-D frames, transformed to global axes and assembled into a sparse matrix.\n- Uniform member loads enter as consistent fixed-end forces (wL/2, wL²/12). Hinges release the end moment by static condensation of the element; the released rotation is recovered afterwards. A node where only hinged or pin-ended members meet has an undefined rotation, which is held fixed.\n- The system is reordered with reverse Cuthill–McKee and solved by an envelope Cholesky factorisation; a failing pivot means the structure is a mechanism and names the free direction.\n- Member forces from the element end forces; shear and moment along each member from equilibrium, deflections from Hermite shape functions plus the exact fixed-end solution of the uniform load — exact for Euler–Bernoulli beams.\n- Checks (not design-code verifications): stress |N|/A + |M|/W against fy, Euler load Pcr = π²EI/(KL)² for compression members, span deflection against L/limit, and the sum of reactions against the applied loads.\n- Verified against Hibbeler Statics Example 6.1 (forces 500 N T, 707.1 N C, 500 N T), PL³/3EI and 5wL⁴/384EI, the propped cantilever (3wL/8, wL²/8), the symmetric three-bar truss P/(1 + 2cos³θ), a tripod and mechanism detection.\n\nNot certified engineering. A linear-elastic, first-order model for checking and teaching: no safety factors, second-order (P-Δ) effects, imperfections, lateral-torsional or local buckling, shear deformation, connection design or code combinations. Have structures that matter designed by a qualified engineer.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "proofline_truss_frame_solver",
        "x-owner-app": "proofline",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProoflineTrussFrameSolverInput"
              },
              "examples": {
                "example1": {
                  "summary": "Simply supported steel beam with a uniform load (5wL⁴/384EI)",
                  "value": {
                    "type": "frame2d",
                    "model": "# IPE 200, 6 m span, 5 kN/m\nnode A 0 0\nnode B 6 0\nmaterial steel E=210 fy=235\nsection IPE200 A=28.5 I=1943 W=194\nmember M1 A B\nsupport A pin\nsupport B roller\nudl M1 qy=-5"
                  }
                },
                "example2": {
                  "summary": "Propped cantilever: statically indeterminate (prop reaction 3wL/8)",
                  "value": {
                    "type": "frame2d",
                    "model": "node A 0 0\nnode B 6 0\nmaterial steel E=210 fy=235\nsection IPE200 A=28.5 I=1943 W=194\nmember M1 A B\nsupport A fixed\nsupport B roller\nudl M1 qy=-5"
                  }
                },
                "example3": {
                  "summary": "Hibbeler Statics Example 6.1: three-bar truss with a 500 N load",
                  "value": {
                    "type": "truss2d",
                    "model": "# 0.5 kN = 500 N horizontal at B\nnode A 0 0\nnode B 0 2\nnode C 2 0\nsection S A=10 I=100\nmember AB A B\nmember BC B C\nmember CA C A\nsupport A pin\nsupport C roller\nload B Fx=0.5"
                  }
                },
                "example4": {
                  "summary": "Warren roof truss, 12 m span, with buckling check",
                  "value": {
                    "type": "truss2d",
                    "model": "# steel tubes 60.3 × 4 mm: A = 7.07 cm², I = 28.2 cm⁴\nnode A 0 0\nnode B 3 0\nnode C 6 0\nnode D 9 0\nnode E 12 0\nnode F 1.5 2\nnode G 4.5 2\nnode H 7.5 2\nnode I 10.5 2\nmaterial S235 E=210 fy=235\nsection CHS60 A=7.07 I=28.2\nmember AB A B\nmember BC B C\nmember CD C D\nmember DE D E\nmember FG F G\nmember GH G H\nmember HI H I\nmember AF A F\nmember FB F B\nmember BG B G\nmember GC G C\nmember CH C H\nmember HD H D\nmember DI D I\nmember IE I E\nsupport A pin\nsupport E roller\nload F Fy=-10\nload G Fy=-10\nload H Fy=-10\nload I Fy=-10"
                  }
                },
                "example5": {
                  "summary": "Portal frame with a hinge and wind load",
                  "value": {
                    "type": "frame2d",
                    "model": "node A 0 0\nnode B 0 4\nnode C 5 4\nnode D 5 0\nmaterial steel E=210 fy=235\nsection HEA200 A=53.8 I=3692 W=389\nmember COL1 A B\nmember BEAM B C hinge=end\nmember COL2 C D\nsupport A fixed\nsupport D fixed\nudl BEAM qy=-8\nload B Fx=6"
                  }
                },
                "example6": {
                  "summary": "3-D tripod: three legs under a vertical load",
                  "value": {
                    "type": "truss3d",
                    "model": "node A 1 0 0\nnode B -0.5 0.8660254 0\nnode C -0.5 -0.8660254 0\nnode D 0 0 2\nmaterial aluminium E=70 fy=160\nsection TUBE A=5 I=20\nmember AD A D\nmember BD B D\nmember CD C D\nsupport A pin\nsupport B pin\nsupport C pin\nload D Fz=-30"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProoflineTrussFrameSolverResult"
                }
              }
            }
          },
          "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"
                }
              }
            }
          }
        }
      },
      "ProoflineTrussFrameSolverInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "type": {
            "title": "Structure type",
            "type": "string",
            "enum": [
              "frame2d",
              "truss2d",
              "truss3d"
            ],
            "default": "frame2d"
          },
          "model": {
            "title": "Structure (one statement per line)",
            "description": "One statement per line, # starts a comment. node A 0 0 (x y in m; 3-D: x y z) · material steel E=210 fy=235 (GPa, MPa) · section S1 A=28.5 I=1943 W=194 (cm², cm⁴, cm³; I needed for beams and buckling checks, W for bending stress) · member M1 A B [section=S1] [material=steel] [hinge=start|end|both] [K=1] [truss] · support A pin | fixed | roller | roller-x | ux uy rz · spring B ky=5000 (kN/m; kr in kN·m/rad) · load B Fx=10 Fy=-20 M=5 (kN, kN·m) · udl M1 qy=-5 (kN/m per metre of member; qx, qn = normal to the member).",
            "type": "string",
            "maxLength": 100000
          },
          "deflectionLimit": {
            "title": "Deflection limit L/…",
            "description": "Beam spans that sag more than span/limit are flagged (250 is a common serviceability figure; check the code that applies).",
            "type": "number",
            "minimum": 50,
            "maximum": 5000,
            "default": 250
          }
        },
        "required": [
          "model"
        ]
      },
      "ProoflineTrussFrameSolverResult": {
        "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",
            "additionalProperties": false,
            "required": [
              "type",
              "units",
              "nodes",
              "reactions",
              "members",
              "equilibrium",
              "maxDisplacement",
              "maxUtilisation",
              "freeRotations",
              "solver"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "frame2d",
                  "truss2d",
                  "truss3d"
                ]
              },
              "units": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "length",
                  "displacement",
                  "rotation",
                  "force",
                  "moment",
                  "stress"
                ],
                "properties": {
                  "length": {
                    "type": "string"
                  },
                  "displacement": {
                    "type": "string"
                  },
                  "rotation": {
                    "type": "string"
                  },
                  "force": {
                    "type": "string"
                  },
                  "moment": {
                    "type": "string"
                  },
                  "stress": {
                    "type": "string"
                  }
                }
              },
              "nodes": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "id",
                    "x",
                    "y",
                    "z",
                    "ux",
                    "uy",
                    "uz",
                    "rz"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "x": {
                      "type": "number"
                    },
                    "y": {
                      "type": "number"
                    },
                    "z": {
                      "type": "number"
                    },
                    "ux": {
                      "type": "number"
                    },
                    "uy": {
                      "type": "number"
                    },
                    "uz": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "rz": {
                      "type": [
                        "number",
                        "null"
                      ]
                    }
                  }
                },
                "description": "Displacements in m, rotations in rad (null where undefined)."
              },
              "reactions": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "node",
                    "kind",
                    "fx",
                    "fy",
                    "fz",
                    "m"
                  ],
                  "properties": {
                    "node": {
                      "type": "string"
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "support",
                        "spring"
                      ]
                    },
                    "fx": {
                      "type": "number"
                    },
                    "fy": {
                      "type": "number"
                    },
                    "fz": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "m": {
                      "type": [
                        "number",
                        "null"
                      ]
                    }
                  }
                },
                "description": "Forces in kN and moments in kN·m that the supports and springs exert on the structure."
              },
              "members": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "id",
                    "from",
                    "to",
                    "kind",
                    "length",
                    "axialStart",
                    "axialEnd",
                    "state",
                    "shearMax",
                    "momentMax",
                    "momentMaxAt",
                    "stressMax",
                    "utilisation",
                    "spanDeflection",
                    "buckling",
                    "hinges",
                    "stations"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "from": {
                      "type": "string"
                    },
                    "to": {
                      "type": "string"
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "bar",
                        "beam"
                      ]
                    },
                    "length": {
                      "type": "number"
                    },
                    "axialStart": {
                      "type": "number",
                      "description": "Axial force at the start node, kN (tension positive)."
                    },
                    "axialEnd": {
                      "type": "number"
                    },
                    "state": {
                      "type": "string",
                      "enum": [
                        "tension",
                        "compression",
                        "zero"
                      ]
                    },
                    "shearMax": {
                      "type": "number"
                    },
                    "momentMax": {
                      "type": "number",
                      "description": "Bending moment with the largest magnitude, kN·m (sagging positive)."
                    },
                    "momentMaxAt": {
                      "type": "number"
                    },
                    "stressMax": {
                      "type": "number",
                      "description": "Largest |N|/A + |M|/W along the member, MPa."
                    },
                    "utilisation": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "spanDeflection": {
                      "type": "number",
                      "description": "Largest deflection from the chord between the member ends, m."
                    },
                    "buckling": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "additionalProperties": false,
                      "required": [
                        "pcr",
                        "ratio",
                        "slenderness"
                      ],
                      "properties": {
                        "pcr": {
                          "type": "number"
                        },
                        "ratio": {
                          "type": "number"
                        },
                        "slenderness": {
                          "type": "number"
                        }
                      }
                    },
                    "hinges": {
                      "type": "string"
                    },
                    "stations": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "x",
                          "N",
                          "V",
                          "M",
                          "deflection"
                        ],
                        "properties": {
                          "x": {
                            "type": "number"
                          },
                          "N": {
                            "type": "number"
                          },
                          "V": {
                            "type": "number"
                          },
                          "M": {
                            "type": "number"
                          },
                          "deflection": {
                            "type": "number"
                          }
                        }
                      }
                    }
                  }
                }
              },
              "equilibrium": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "appliedFx",
                  "appliedFy",
                  "appliedFz",
                  "reactionFx",
                  "reactionFy",
                  "reactionFz",
                  "momentResidual",
                  "maxError"
                ],
                "properties": {
                  "appliedFx": {
                    "type": "number"
                  },
                  "appliedFy": {
                    "type": "number"
                  },
                  "appliedFz": {
                    "type": "number"
                  },
                  "reactionFx": {
                    "type": "number"
                  },
                  "reactionFy": {
                    "type": "number"
                  },
                  "reactionFz": {
                    "type": "number"
                  },
                  "momentResidual": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "maxError": {
                    "type": "number"
                  }
                }
              },
              "maxDisplacement": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "at",
                  "value"
                ],
                "properties": {
                  "at": {
                    "type": "string"
                  },
                  "value": {
                    "type": "number"
                  }
                }
              },
              "maxUtilisation": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "required": [
                  "member",
                  "value"
                ],
                "properties": {
                  "member": {
                    "type": "string"
                  },
                  "value": {
                    "type": "number"
                  }
                }
              },
              "freeRotations": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "solver": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "method",
                  "unknowns",
                  "nonZeros",
                  "bandwidthBefore",
                  "bandwidthAfter",
                  "relativeResidual"
                ],
                "properties": {
                  "method": {
                    "type": "string"
                  },
                  "unknowns": {
                    "type": "integer"
                  },
                  "nonZeros": {
                    "type": "integer"
                  },
                  "bandwidthBefore": {
                    "type": "integer"
                  },
                  "bandwidthAfter": {
                    "type": "integer"
                  },
                  "relativeResidual": {
                    "type": "number"
                  }
                }
              }
            }
          },
          "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"
              }
            }
          }
        }
      }
    }
  }
}