{
  "openapi": "3.0.4",
  "info": {
    "title": "SPACE GASS API",
    "description": "REST API for SPACE GASS — structural analysis and design software.",
    "contact": {
      "name": "SPACE GASS API Support",
      "email": "support@spacegass.com"
    },
    "license": {
      "name": "SPACE GASS License",
      "url": "https://www.spacegass.com/manual/Introduction/End_User_Licence_Agreement.htm"
    },
    "version": "1",
    "x-space-gass-build": "14.50.84"
  },
  "servers": [
    {
      "url": "/api/v1"
    }
  ],
  "paths": {
    "/job/analysis/buckling/settings": {
      "get": {
        "tags": [
          "Analysis"
        ],
        "summary": "Get Buckling Analysis Settings",
        "description": "Returns the current Buckling Analysis settings.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BucklingSettings"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Analysis"
        ],
        "summary": "Update Buckling Analysis Settings",
        "description": "Partially updates the Buckling Analysis settings.\r\nOnly fields included in the request body are updated; omitted fields remain unchanged.",
        "requestBody": {
          "description": "Partial settings to apply",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BucklingSettingsUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/BucklingSettingsUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/BucklingSettingsUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BucklingSettings"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/analysis/dynamic-frequency/settings": {
      "get": {
        "tags": [
          "Analysis"
        ],
        "summary": "Get Dynamic Frequency Analysis Settings",
        "description": "Returns the current Dynamic Frequency Analysis settings.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DynamicFrequencySettings"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Analysis"
        ],
        "summary": "Update Dynamic Frequency Analysis Settings",
        "description": "Partially updates the Dynamic Frequency Analysis settings.\r\nOnly fields included in the request body are updated; omitted fields remain unchanged.",
        "requestBody": {
          "description": "Partial settings to apply",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DynamicFrequencySettingsUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/DynamicFrequencySettingsUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/DynamicFrequencySettingsUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DynamicFrequencySettings"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/analysis/runs": {
      "get": {
        "tags": [
          "Analysis"
        ],
        "summary": "List Analysis Runs",
        "description": "Lists the current analysis run (if any) and recent run history.\r\nHistory is capped at the 10 most recent runs.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AnalysisRun"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/analysis/runs/{runId}": {
      "get": {
        "tags": [
          "Analysis"
        ],
        "summary": "Get Analysis Run Status",
        "description": "Gets the current status of an analysis run. Use this to poll for completion.",
        "parameters": [
          {
            "name": "runId",
            "in": "path",
            "description": "The unique run ID returned when the analysis was started",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnalysisRun"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Analysis"
        ],
        "summary": "Cancel Analysis Run",
        "description": "Cancels a running analysis. Returns 204 if cancellation was initiated.\r\nReturns 404 if the run is not found or has already completed.",
        "parameters": [
          {
            "name": "runId",
            "in": "path",
            "description": "The unique run ID to cancel",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/analysis/runs/{runId}/result": {
      "get": {
        "tags": [
          "Analysis"
        ],
        "summary": "Get Analysis Run Result",
        "description": "Gets a summary of the completed analysis run.\r\nReturns 409 Conflict if the analysis is still running.\r\n            \r\nFor actual result data (reactions, displacements, etc.), use the query endpoints:\r\n- GET /api/v1/job/query/analysis/static/node-reactions\r\n- GET /api/v1/job/query/analysis/static/node-displacements",
        "parameters": [
          {
            "name": "runId",
            "in": "path",
            "description": "The unique run ID",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnalysisRunResult"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/analysis/static/settings": {
      "get": {
        "tags": [
          "Analysis"
        ],
        "summary": "Get Static Analysis Settings",
        "description": "Returns the current Static Analysis settings.\r\nThese settings are shared between Linear Static and Non-Linear Static analysis types.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StaticSettings"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Analysis"
        ],
        "summary": "Update Static Analysis Settings",
        "description": "Partially updates the Static Analysis settings.\r\nOnly fields included in the request body are updated; omitted fields remain unchanged.\r\nThese settings are shared between Linear Static and Non-Linear Static analysis types.",
        "requestBody": {
          "description": "Partial settings to apply",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StaticSettingsUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/StaticSettingsUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/StaticSettingsUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StaticSettings"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/analysis/buckling/run": {
      "post": {
        "tags": [
          "Analysis"
        ],
        "summary": "Run Buckling Analysis",
        "description": "Starts a Buckling Analysis run. The analysis executes asynchronously in the background.\r\nPoll the returned status URL to track progress. Only one analysis can run at a time.\r\n            \r\nThe request body is optional. If provided, only fields included are applied as setting\r\noverrides before the analysis starts; omitted fields remain unchanged.",
        "requestBody": {
          "description": "Optional partial settings overrides to apply before running",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BucklingSettingsUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/BucklingSettingsUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/BucklingSettingsUpdate"
              }
            }
          },
          "required": false
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnalysisRun"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/analysis/dynamic-frequency/run": {
      "post": {
        "tags": [
          "Analysis"
        ],
        "summary": "Run Dynamic Frequency Analysis",
        "description": "Starts a Dynamic Frequency Analysis run. The analysis executes asynchronously in the background.\r\nPoll the returned status URL to track progress. Only one analysis can run at a time.\r\n            \r\nThe request body is optional. If provided, only fields included are applied as setting\r\noverrides before the analysis starts; omitted fields remain unchanged.",
        "requestBody": {
          "description": "Optional partial settings overrides to apply before running",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DynamicFrequencySettingsUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/DynamicFrequencySettingsUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/DynamicFrequencySettingsUpdate"
              }
            }
          },
          "required": false
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnalysisRun"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/analysis/static/run-linear": {
      "post": {
        "tags": [
          "Analysis"
        ],
        "summary": "Run Linear Static Analysis",
        "description": "Starts a Linear Static Analysis run. The analysis executes asynchronously in the background.\r\nPoll the returned status URL to track progress. Only one analysis can run at a time.\r\n            \r\nThe request body is optional. If provided, only fields included are applied as setting\r\noverrides before the analysis starts; omitted fields remain unchanged.\r\nIf omitted, the analysis runs with the current job settings as-is.\r\n            \r\nOnce complete, results are available via the query endpoints\r\n(e.g., GET /api/v1/job/query/analysis/static/node-reactions).",
        "requestBody": {
          "description": "Optional partial settings overrides to apply before running",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StaticSettingsUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/StaticSettingsUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/StaticSettingsUpdate"
              }
            }
          },
          "required": false
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnalysisRun"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/analysis/static/run-non-linear": {
      "post": {
        "tags": [
          "Analysis"
        ],
        "summary": "Run Non-Linear Static Analysis",
        "description": "Starts a Non-Linear Static Analysis run. The analysis executes asynchronously in the background.\r\nUses the same settings as Linear Static (shared via GET/PATCH /static/settings).\r\n            \r\nThe request body is optional. If provided, only fields included are applied as setting\r\noverrides before the analysis starts; omitted fields remain unchanged.",
        "requestBody": {
          "description": "Optional partial settings overrides to apply before running",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StaticSettingsUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/StaticSettingsUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/StaticSettingsUpdate"
              }
            }
          },
          "required": false
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnalysisRun"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/analysis/buckling/load-factors": {
      "get": {
        "tags": [
          "Buckling Results"
        ],
        "summary": "List Buckling Load Factors",
        "description": "Gets buckling load factor results for all load cases and modes.",
        "parameters": [
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the buckling load factor results.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BucklingLoadFactorQueryResult"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/analysis/buckling/load-factors/metadata": {
      "get": {
        "tags": [
          "Buckling Results"
        ],
        "summary": "Get Buckling Load Factors Metadata",
        "description": "Returns the field schema for `GET load-factors` — units resolved against current job units.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/analysis/buckling/member-effective-lengths": {
      "get": {
        "tags": [
          "Buckling Results"
        ],
        "summary": "List Buckling Effective Lengths",
        "description": "Gets buckling effective length results, optionally filtered by load cases, members and modes.",
        "parameters": [
          {
            "name": "cases",
            "in": "query",
            "description": "Load case Ids in SG list format (e.g. `\"1,3-7,10\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "members",
            "in": "query",
            "description": "Member Ids in SG list format (e.g. `\"1,3-7,10\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "modes",
            "in": "query",
            "description": "Buckling mode numbers in SG list format (e.g. `\"1-3\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1-3"
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the buckling effective length results.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BucklingEffectiveLengthQueryResult"
                }
              }
            }
          },
          "400": {
            "description": "Filter is malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/analysis/buckling/member-effective-lengths/metadata": {
      "get": {
        "tags": [
          "Buckling Results"
        ],
        "summary": "Get Buckling Effective Lengths Metadata",
        "description": "Returns the field schema for `GET member-effective-lengths` — units resolved against current job units.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/combination-load-cases": {
      "get": {
        "tags": [
          "Combination Load Cases"
        ],
        "summary": "List Combination Load Cases",
        "description": "Returns all combination load cases (load cases of type `Combination`) in the open job.\r\nFilter by case-Id list or by title substring. Results are sorted by Id ascending.\r\nPagination metadata is returned in response headers (`Total-Count`, `Offset`, `Limit`).\r\n`Expand` defaults to `none` on this list endpoint; pass `Expand=all` to hydrate\r\neach case's `combinationItems` array (otherwise `hasCombinationItems` is populated\r\nbut the array is omitted from the wire).",
        "parameters": [
          {
            "name": "Cases",
            "in": "query",
            "description": "Combination case Ids to filter by, in SG list format (e.g. `\"1,3-7,10\"`).\r\nOmit to return all combination cases.",
            "schema": {
              "type": "string",
              "example": "1,3-7,10"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "TitleSearch",
            "in": "query",
            "description": "Search text to filter by title (case-insensitive contains).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Expand",
            "in": "query",
            "description": "Sub-resource expansion. Defaults to `none`; pass `all` to hydrate combination items.",
            "schema": {
              "$ref": "#/components/schemas/ExpandOption"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the list of combination load cases",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/LoadCase"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Combination Load Cases"
        ],
        "summary": "Create Combination Load Case",
        "description": "Creates a combination load case (case + items) in a single atomic call. The\r\n`combinationItems` list is required and must contain at least one item; on\r\nfailure during item creation the parent case row is rolled back so the operation is\r\nall-or-nothing. Each component case must exist and be of type Primary, Combination\r\nor Unused (Step cases are rejected); no item may reference the parent case\r\n(self-reference); item `case` values must be unique within the request.",
        "requestBody": {
          "description": "The combination load case data (load-case fields plus a non-empty `combinationItems` list)",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CombinationLoadCaseCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CombinationLoadCaseCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CombinationLoadCaseCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Combination load case created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoadCase"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed (missing items, self-reference, wrong-type component, duplicate items, etc.)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "A load case with the supplied Id already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/combination-load-cases/{combinationCase}/items": {
      "get": {
        "tags": [
          "Combination Load Cases"
        ],
        "summary": "Get Combination Items",
        "description": "Gets the combination items for a specific combination case.\r\nReturns 404 if no combination case exists with the supplied Id (Primary,\r\nStep or Unused load cases are not exposed by this endpoint).",
        "parameters": [
          {
            "name": "combinationCase",
            "in": "path",
            "description": "The combination case Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the combination items",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CombinationLoadCaseItem"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Combination case not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Combination Load Cases"
        ],
        "summary": "Set Combination Items",
        "description": "Replaces the combination items for a combination case atomically.\r\nThe case must already exist and be of type Combination.\r\nAll standard item rules apply: non-empty list, no duplicates, no self-reference,\r\nand every component case must exist and be of type Primary, Combination or Unused\r\n(Step cases are rejected).",
        "parameters": [
          {
            "name": "combinationCase",
            "in": "path",
            "description": "The combination case Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The combination items to set",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/CombinationLoadCaseItem"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/CombinationLoadCaseItem"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/CombinationLoadCaseItem"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Items set successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CombinationLoadCaseItem"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid items (empty array, duplicates, self-reference, or wrong-type component)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Combination case not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/combination-load-cases/{id}": {
      "get": {
        "tags": [
          "Combination Load Cases"
        ],
        "summary": "Get Combination Load Case",
        "description": "Gets a single combination load case by Id. Returns 404 if no case exists with that Id\r\nor if the case is not of type `Combination` (Primary, Step and Unused cases are\r\nnot exposed by this endpoint — use `GET /load-cases/{id}` for those).\r\n`Expand` defaults to `all`, which hydrates `combinationItems`;\r\npass `Expand=none` to suppress.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The combination load case Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Expand",
            "in": "query",
            "description": "Sub-resource expansion. Defaults to `all`.",
            "schema": {
              "$ref": "#/components/schemas/ExpandOption"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the combination load case",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoadCase"
                }
              }
            }
          },
          "404": {
            "description": "Combination load case not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Combination Load Cases"
        ],
        "summary": "Update Combination Load Case",
        "description": "Partially updates a combination load case. Only fields supplied in the body are\r\nchanged; omitted fields are left as-is. The optional `combinationItems` field is\r\na full-replace when provided — it must be a non-empty list, and the same item rules\r\nfrom create apply (existence, type, no self-reference, no duplicates). Omit\r\n`combinationItems` to leave the existing items untouched. To remove all items,\r\ndelete the case (`DELETE /{id}`).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The combination load case Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The partial update data (any of: title, notes, combinationItems)",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CombinationLoadCaseUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CombinationLoadCaseUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CombinationLoadCaseUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the updated combination load case",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoadCase"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Combination load case not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Combination Load Cases"
        ],
        "summary": "Delete Combination Load Case",
        "description": "Deletes the combination load case and all of its component items atomically.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The combination load case Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Combination load case deleted"
          },
          "404": {
            "description": "Combination load case not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/combination-load-cases/items/metadata": {
      "get": {
        "tags": [
          "Combination Load Cases"
        ],
        "summary": "Get Items Metadata",
        "description": "Returns the schema for a single combination item: field definitions,\r\nunits resolved against current job units, and allowed values for enum fields.",
        "responses": {
          "200": {
            "description": "Returns combination-item schema metadata",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/combination-load-cases/metadata": {
      "get": {
        "tags": [
          "Combination Load Cases"
        ],
        "summary": "Get Combination Load Case Metadata",
        "description": "Returns the schema for a combination load case: field definitions, units resolved\r\nagainst current job units, and allowed values for enum fields. The item DTO schema\r\n(component case + multiplying factor) is available at `GET /combination-load-cases/items/metadata`.",
        "responses": {
          "200": {
            "description": "Returns combination load case schema metadata",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/combination-load-cases/next": {
      "get": {
        "tags": [
          "Combination Load Cases"
        ],
        "summary": "Get Next Combination Load Case Id",
        "description": "Returns the next available (unused) load case Id, starting from start.\r\nThe Id space is shared with regular load cases — combination cases and primary cases\r\ncannot have the same Id.",
        "parameters": [
          {
            "name": "start",
            "in": "query",
            "description": "The Id to start searching from (inclusive). Defaults to 1.",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the next available Id",
            "content": {
              "application/json": {
                "schema": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/combination-load-cases/bulk": {
      "post": {
        "tags": [
          "Combination Load Cases"
        ],
        "summary": "Create Combination Load Cases (Bulk)",
        "description": "Creates multiple combination load cases in a single request. Each item is a full\r\ncase + items payload; validation runs upfront on the whole request. With\r\n`continueOnError=false` (default) any failure rejects the whole request; with\r\n`continueOnError=true`, valid items are created and failures are reported per-item.\r\nEach created case is atomic individually (case + items, with rollback on failure).",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "If true, process valid items even when some fail. Default: false.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of combination load cases to create",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/CombinationLoadCaseCreate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/CombinationLoadCaseCreate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/CombinationLoadCaseCreate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the bulk result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoadCaseBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Combination Load Cases"
        ],
        "summary": "Update Combination Load Cases (Bulk)",
        "description": "Partially updates multiple combination load cases. Each item must include its `id`.\r\nAs with the single-item PATCH, an optional `combinationItems` list on a row\r\nperforms a full-replace of that case's items. Validation runs upfront on the whole\r\nrequest; with `continueOnError=true`, valid rows are applied and failures are reported per-item.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "If true, process valid items even when some fail. Default: false.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of partial updates (each must include `id`)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/CombinationLoadCaseUpdate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/CombinationLoadCaseUpdate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/CombinationLoadCaseUpdate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the bulk result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoadCaseBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Combination Load Cases"
        ],
        "summary": "Delete Combination Load Cases (Bulk)",
        "description": "Deletes multiple combination load cases by Id. The body is a JSON array of integer Ids\r\n(e.g. `[10, 11, 12]`). Each deletion removes the case and its items atomically.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "If true, continue processing remaining Ids after a failure. Default: false.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "JSON array of combination load case Ids to delete",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the bulk result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Request body is missing or empty",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/analysis/dynamic/mode-shapes": {
      "get": {
        "tags": [
          "Dynamic Results"
        ],
        "summary": "List Mode Shapes",
        "description": "Gets mode shape results grouped by load case and mode.\r\nEach result contains displacement values at each node.\r\nOptionally filtered by load cases, modes and node Ids.",
        "parameters": [
          {
            "name": "cases",
            "in": "query",
            "description": "Load case Ids in SG list format (e.g. `\"1,3-7,10\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "modes",
            "in": "query",
            "description": "Mode numbers in SG list format (e.g. `\"1-3\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1-3"
          },
          {
            "name": "nodes",
            "in": "query",
            "description": "Node Ids in SG list format (e.g. `\"1,5-10\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1,5-10"
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the mode shape results.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModeShapeQueryResult"
                }
              }
            }
          },
          "400": {
            "description": "Filter is malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/analysis/dynamic/mode-shapes/metadata": {
      "get": {
        "tags": [
          "Dynamic Results"
        ],
        "summary": "Get Mode Shapes Metadata",
        "description": "Returns the field schema for `GET mode-shapes` — units resolved against current job units.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/analysis/dynamic/natural-frequencies": {
      "get": {
        "tags": [
          "Dynamic Results"
        ],
        "summary": "List Natural Frequencies",
        "description": "Gets natural frequency results, optionally filtered by load cases and modes.",
        "parameters": [
          {
            "name": "cases",
            "in": "query",
            "description": "Load case Ids in SG list format (e.g. `\"1,3-7,10\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "modes",
            "in": "query",
            "description": "Mode numbers in SG list format (e.g. `\"1-3\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1-3"
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the natural frequency results.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NaturalFrequencyQueryResult"
                }
              }
            }
          },
          "400": {
            "description": "Filter is malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/analysis/dynamic/natural-frequencies/metadata": {
      "get": {
        "tags": [
          "Dynamic Results"
        ],
        "summary": "Get Natural Frequencies Metadata",
        "description": "Returns the field schema for `GET natural-frequencies` — units resolved against current job units.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/errors": {
      "get": {
        "tags": [
          "Errors"
        ],
        "summary": "Get Errors",
        "description": "Returns all diagnostic error messages logged during the current session.\r\nThese are engine-level messages generated during operations such as analysis, import, or file operations.",
        "responses": {
          "200": {
            "description": "Returns the error list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorList"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Errors"
        ],
        "summary": "Clear Errors",
        "description": "Clears all logged error messages from the current session.",
        "responses": {
          "204": {
            "description": "Errors cleared successfully"
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/errors/last": {
      "get": {
        "tags": [
          "Errors"
        ],
        "summary": "Get Last Error",
        "description": "Returns the most recent error message, or null if no errors have been logged.\r\nUseful for quick checks after an operation without retrieving the full list.",
        "responses": {
          "200": {
            "description": "Returns the last error (hasError indicates if one exists)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LastError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/file/preview": {
      "get": {
        "tags": [
          "File"
        ],
        "summary": "Preview Job File",
        "description": "This endpoint extracts metadata appended to SPACE GASS job files:\r\n- Version: SPACE GASS version used to save the file\r\n- Licensee: Licensed user name when file was saved\r\n- Designer: Computer name where file was saved\r\n- Preview image: Screenshot of the model when saved (if available)\r\n            \r\nNote: Older files may not have this metadata. Check dataAvailable in response.\r\n            \r\nExample usage with curl:\r\n            \r\n    curl -X GET \"/api/v1/file/preview?filePath=C:\\path\\to\\job.sg&includeImage=true\"",
        "parameters": [
          {
            "name": "filePath",
            "in": "query",
            "description": "Full path to the SPACE GASS job file (.sg or .sgbase)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "includeImage",
            "in": "query",
            "description": "If true, includes the preview image (base64 encoded). Defaults to false.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns preview information",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobFilePreviewInfo"
                }
              }
            }
          },
          "400": {
            "description": "Invalid file path",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "File not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/file/samples": {
      "get": {
        "tags": [
          "File"
        ],
        "summary": "List Sample Files",
        "description": "Returns all available SPACE GASS sample project files.\r\nEach sample includes metadata and an optional preview image.\r\nThe file paths use virtual `samples://` scheme (e.g. \"samples://Portal Frame.SG\")\r\nwhich can be used with the preview and open endpoints.\r\n            \r\nSamples are opened as new unsaved jobs — use Save As to persist changes.\r\n            \r\nExample usage with curl:\r\n            \r\n    curl -X GET \"/api/v1/file/samples?includeImages=true\"",
        "parameters": [
          {
            "name": "includeImages",
            "in": "query",
            "description": "If true, includes preview images (base64 encoded). Defaults to false.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns list of sample files",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/JobFilePreviewInfo"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/file/status": {
      "get": {
        "tags": [
          "File"
        ],
        "summary": "Get File Opening Status",
        "description": "Status values from SPACE GASS library (SGJobStatus):\r\n- 0 (NoSGandNoATS): File does not exist\r\n- 1 (SGandNoATS): Ready to open safely\r\n- 3: File is locked (another user has it open)\r\n- 4 (NoSGbutATS): Only temporary files exist, .sg file missing\r\n- 5 (SGandATS): Abnormal shutdown detected, unsaved changes exist\r\n- 7: File is locked with unsaved changes\r\n- -1 (UnknownStatus): Cannot write to file or temporary files",
        "parameters": [
          {
            "name": "filePath",
            "in": "query",
            "description": "Full path to the SPACE GASS job file (.sg)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the file opening status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileOpeningStatus"
                }
              }
            }
          },
          "400": {
            "description": "Invalid file path",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/import/txt": {
      "post": {
        "tags": [
          "Import"
        ],
        "summary": "Import Text File",
        "description": "Creates a new job and imports the SpaceGass text file into it.\r\nThe new job will use the units defined in the imported text file — no conversion is performed.\r\n            \r\nNo job must be open when calling this endpoint. If a job is already open (even an empty one),\r\nthe request will return 409 Conflict — close the current job first using POST /job/close.\r\n            \r\nThe file should be uploaded as multipart/form-data with the field name \"file\".\r\n            \r\nExample usage with curl:\r\n            \r\n    curl -X POST \"/api/v1/job/import/txt\" \\\r\n      -F \"file=@/path/to/model.txt\"",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "description": "The SpaceGass text file (.txt) to import",
                    "format": "binary"
                  }
                }
              },
              "encoding": {
                "file": {
                  "style": "form"
                }
              }
            }
          },
          "required": false
        },
        "responses": {
          "200": {
            "description": "Text file imported successfully. Returns the new job status with model counts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobStatus"
                }
              }
            }
          },
          "400": {
            "description": "Invalid file or import failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "A job is already open — close the current job first with POST /job/close",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job": {
      "get": {
        "tags": [
          "Job"
        ],
        "summary": "Get Job",
        "description": "Gets the current job (there is only one).\r\n            \r\nSub-resources are managed via their own endpoints:\r\n- Headings: GET/PATCH /job/headings\r\n- Settings: GET /job/settings\r\n- Units: GET/PATCH /job/units\r\n- Errors: GET/DELETE /job/errors\r\n- Model summary: GET /job/status",
        "responses": {
          "200": {
            "description": "Returns the job",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "404": {
            "description": "No job found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/headings": {
      "get": {
        "tags": [
          "Job"
        ],
        "summary": "Get Job Headings",
        "description": "Gets the job headings (project heading, designer initials, notes).",
        "responses": {
          "200": {
            "description": "Returns the job headings",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobHeadings"
                }
              }
            }
          },
          "404": {
            "description": "No job found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Job"
        ],
        "summary": "Update Job Headings",
        "description": "Updates the job headings (project heading, designer initials, notes).",
        "requestBody": {
          "description": "The updated headings",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JobHeadingsUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/JobHeadingsUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/JobHeadingsUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the updated headings",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobHeadings"
                }
              }
            }
          },
          "400": {
            "description": "If the data is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "No job found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/status": {
      "get": {
        "tags": [
          "Job"
        ],
        "summary": "Get Job Status",
        "description": "Returns the current job and its file/session state.\r\nSame response shape as new, open, and save for consistency.\r\n            \r\nUse this to determine:\r\n- Whether a job is currently loaded (status.isOpen)\r\n- Whether it needs saving (status.isModified)\r\n- Whether to provide a filePath when saving (status.isNew)\r\n- What's in the model (job.modelSummary)",
        "responses": {
          "200": {
            "description": "Returns the job and status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobStatus"
                }
              }
            }
          },
          "404": {
            "description": "No job is currently open",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/close": {
      "post": {
        "tags": [
          "Job"
        ],
        "summary": "Close Job",
        "description": "Closes the current job session and unloads from memory.\r\n            \r\nIdempotent: if no job is currently open, returns 200 with the current state\r\n(isOpen=false) without error.\r\n            \r\nUnsaved changes are discarded. Call POST /job/save before closing to persist changes.\r\n            \r\nThe .sg file on disk is never deleted or modified.\r\nReturns the file resource state after close (isOpen will be false).",
        "responses": {
          "200": {
            "description": "Returns the state confirming the job is closed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobState"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/new": {
      "post": {
        "tags": [
          "Job"
        ],
        "summary": "New Job",
        "description": "Creates a new blank job with default configuration.\r\n            \r\nIf a job is currently open, returns 409 Conflict — close the current job first\r\nusing POST /job/close.",
        "responses": {
          "200": {
            "description": "New blank job created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobStatus"
                }
              }
            }
          },
          "409": {
            "description": "A job is already open — close it first with POST /job/close",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Bootstrap of the new job's @JB file failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/new-from-template": {
      "post": {
        "tags": [
          "Job"
        ],
        "summary": "New Job From Template",
        "description": "Creates a new job from an uploaded .sgbase template file.\r\n            \r\nThe template data is loaded but treated as a new job — no file path is set.\r\nUse POST /job/save with a filePath to save to a new location.\r\n            \r\nIf a job is currently open, returns 409 Conflict — close the current job first\r\nusing POST /job/close.\r\n            \r\nExample usage with curl:\r\n            \r\n    curl -X POST \"/api/v1/job/new-from-template\" \\\r\n      -F \"template=@/path/to/template.sgbase\"",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "required": [
                  "template"
                ],
                "type": "object",
                "properties": {
                  "template": {
                    "type": "string",
                    "description": ".sgbase template file uploaded as multipart/form-data",
                    "format": "binary"
                  }
                }
              },
              "encoding": {
                "template": {
                  "style": "form"
                }
              }
            }
          },
          "required": false
        },
        "responses": {
          "201": {
            "description": "New job created from template",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobStatus"
                }
              }
            }
          },
          "400": {
            "description": "Invalid or missing template file, or creation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Template file not found on disk after upload",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "A job is already open — close it first with POST /job/close",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Template load failed for an internal reason",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/open": {
      "post": {
        "tags": [
          "Job"
        ],
        "summary": "Open Job",
        "description": "Opens a job from a local .sg file.\r\n            \r\nIf a job is currently open, returns 409 Conflict — close the current job first\r\nusing POST /job/close.\r\n            \r\nFor normal open, omit forceOption (or set to null).\r\nIf the file has unsaved temporary files from a previous session, provide a forceOption:\r\n- OpenPreviousSaved: Discard unsaved changes, open last saved version\r\n- OpenUnsavedMostRecent: Preserve unsaved changes, recover from abnormal shutdown\r\n            \r\nExample request to recover unsaved work:\r\n            \r\n    POST /api/v1/job/open\r\n    {\r\n      \"filePath\": \"C:\\\\path\\\\to\\\\job.sg\",\r\n      \"forceOption\": \"OpenUnsavedMostRecent\"\r\n    }",
        "requestBody": {
          "description": "File path and optional force option",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OpenJobRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/OpenJobRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/OpenJobRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the opened job and status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobStatus"
                }
              }
            }
          },
          "400": {
            "description": "Invalid file path or the file is not a valid SPACE GASS job file",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "The job file does not exist at the supplied path",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "A job is already open, or the file is locked / has unsaved changes (supply forceOption)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Open failed for an internal reason",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/open-sample": {
      "post": {
        "tags": [
          "Job"
        ],
        "summary": "Open Sample Project",
        "description": "Opens a sample SPACE GASS project as a new unsaved job.\r\nThe sample data is loaded but treated as a new job — use Save As to persist changes.\r\n            \r\nIf a job is currently open, returns 409 Conflict — close the current job first\r\nusing POST /job/close.\r\n            \r\nUse GET /api/v1/file/samples to list available sample files and their virtual paths.\r\n            \r\nExample request:\r\n            \r\n    POST /api/v1/job/open-sample\r\n    {\r\n      \"fileName\": \"Portal Frame.SG\"\r\n    }",
        "requestBody": {
          "description": "Virtual sample path",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OpenSampleRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/OpenSampleRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/OpenSampleRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the opened job and status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobStatus"
                }
              }
            }
          },
          "400": {
            "description": "A sample file name was not provided",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Sample file not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "A job is already open — close it first with POST /job/close",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Sample open failed for an internal reason",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/save": {
      "post": {
        "tags": [
          "Job"
        ],
        "summary": "Save Job",
        "description": "Saves the current job. Provide a filePath to save to a new location (Save As),\r\nor omit it to save to the current location.\r\n            \r\nIf the job is new (never saved) and no filePath is provided, returns 409 Conflict.\r\n            \r\nReturns 201 Created on first save (new job), 200 OK on subsequent saves.",
        "requestBody": {
          "description": "Optional file path for Save As",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaveJobRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SaveJobRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SaveJobRequest"
              }
            }
          },
          "required": false
        },
        "responses": {
          "200": {
            "description": "Job saved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobStatus"
                }
              }
            }
          },
          "201": {
            "description": "New job saved for the first time",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobStatus"
                }
              }
            }
          },
          "400": {
            "description": "Save failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "No job is currently open",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Job is new and no filePath was provided",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/data": {
      "delete": {
        "tags": [
          "Job"
        ],
        "summary": "Clear Job Data",
        "description": "Clears all model data while keeping current configuration (units, settings).\r\nDeletes ATS data files but preserves the job configuration.\r\nReturns the job object with zeroed model summary counts.",
        "parameters": [
          {
            "name": "force",
            "in": "query",
            "description": "Must be true to confirm clearing. If false or omitted, operation is rejected for safety.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Job data cleared, returns updated job",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "400": {
            "description": "If force is not true or clearing failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "No job found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Clearing failed for an internal reason",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/license/status": {
      "get": {
        "tags": [
          "License"
        ],
        "summary": "Get License Status",
        "description": "Returns the current licensing status: backend type, organisation, and all held modules.\r\nThis endpoint is accessible even when the API is unlicensed so clients can diagnose\r\nwhy their other requests are being refused.",
        "responses": {
          "200": {
            "description": "Returns the license status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LicenseStatus"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/load-case-groups": {
      "get": {
        "tags": [
          "Load Case Groups"
        ],
        "summary": "Get All",
        "description": "Gets all items with optional filtering, pagination and sub-resource expansion.\r\nResults are always sorted by Id ascending.\r\nPagination metadata is returned in response headers (Total-Count, Offset, Limit).\r\n`Expand` defaults to `none` on list endpoints so payloads stay lean;\r\npass `Expand=all` to hydrate sub-resources. Sub-resource expansion is\r\nopt-in per resource type — resources that don't define sub-resources ignore the parameter.",
        "parameters": [
          {
            "name": "Groups",
            "in": "query",
            "description": "Group Ids to filter by, in SG list format (e.g. `\"1,3-7,10\"`).\r\nOmit to return all groups.",
            "schema": {
              "type": "string",
              "example": "1,3-7,10"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Expand",
            "in": "query",
            "description": "Sub-resource expansion. Defaults to `none`; pass `all` to hydrate sub-resources.",
            "schema": {
              "$ref": "#/components/schemas/ExpandOption"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/LoadCaseGroup"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Load Case Groups"
        ],
        "summary": "Create",
        "description": "Creates a new item. If a validator is registered, the item is validated before creation.",
        "requestBody": {
          "description": "The data for the new item",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoadCaseGroupCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/LoadCaseGroupCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/LoadCaseGroupCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoadCaseGroup"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/load-case-groups/{id}": {
      "get": {
        "tags": [
          "Load Case Groups"
        ],
        "summary": "Get by Id",
        "description": "`Expand` defaults to `all` on the single-item endpoint; pass `Expand=none`\r\n            to suppress sub-resource hydration. Sub-resource expansion is opt-in per resource type —\r\n            resources that don't define sub-resources ignore the parameter.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Expand",
            "in": "query",
            "description": "Sub-resource expansion. Defaults to `all`; pass `none` to suppress sub-resource hydration.",
            "schema": {
              "$ref": "#/components/schemas/ExpandOption"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoadCaseGroup"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Load Case Groups"
        ],
        "summary": "Update",
        "description": "Updates an existing item. If a validator is registered, the update is validated first.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The partial update data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoadCaseGroupUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/LoadCaseGroupUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/LoadCaseGroupUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoadCaseGroup"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Load Case Groups"
        ],
        "summary": "Delete",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/load-case-groups/{id}/cases": {
      "get": {
        "tags": [
          "Load Case Groups"
        ],
        "summary": "Get Group Cases",
        "description": "Gets the expanded list of load cases that belong to a group.\r\nResolves the group's load case list (e.g., \"1,3,5-10\") against the actual\r\nload cases that exist in the current job. Returns full load case data\r\nincluding Id, title, type, notes, and guid.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The group Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the list of load cases in the group",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/LoadCase"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Group not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/load-case-groups/metadata": {
      "get": {
        "tags": [
          "Load Case Groups"
        ],
        "summary": "Get Metadata",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/load-case-groups/next": {
      "get": {
        "tags": [
          "Load Case Groups"
        ],
        "summary": "Next Id",
        "description": "Gets the next available (unused) Id for this entity type.",
        "parameters": [
          {
            "name": "start",
            "in": "query",
            "description": "The Id value to start searching from (inclusive). Defaults to 1.",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/load-case-groups/bulk": {
      "post": {
        "tags": [
          "Load Case Groups"
        ],
        "summary": "Create Bulk",
        "description": "Creates multiple items in a bulk operation.\r\nIf a validator is registered, all items are validated upfront before any are created.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of items to create",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LoadCaseGroupCreate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LoadCaseGroupCreate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LoadCaseGroupCreate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoadCaseGroupBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Load Case Groups"
        ],
        "summary": "Update Bulk",
        "description": "Updates multiple items in a bulk operation.\r\nEach item must include its Id in the request body.\r\nIf a validator is registered, all items are validated upfront before any are updated.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of update objects (each must include Id)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LoadCaseGroupUpdate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LoadCaseGroupUpdate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LoadCaseGroupUpdate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoadCaseGroupBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Load Case Groups"
        ],
        "summary": "Delete Bulk",
        "description": "Deletes multiple entities by Id. The body is a JSON array of integer Ids\r\n(e.g. `[1, 5, 10]`) — consistent with every other bulk-delete endpoint\r\nin the API (see CLAUDE.md \"Query Parameter Conventions\").",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue on error",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "JSON array of entity Ids to delete",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/load-cases": {
      "get": {
        "tags": [
          "Load Cases"
        ],
        "summary": "List Load Cases",
        "description": "Returns all load cases in the open job. Type is read-only and computed by SPACE GASS\r\nbased on assigned loads (Primary, Combination, Step, Unused). Filter by type, by\r\ncase-Id list, or by title substring. Results are sorted by Id ascending.\r\nPagination metadata is returned in response headers (`Total-Count`, `Offset`, `Limit`).\r\nPass `Expand=all` to hydrate `combinationItems` on combination cases (otherwise the\r\n`hasCombinationItems` indicator is populated but the array is omitted from the wire).",
        "parameters": [
          {
            "name": "Cases",
            "in": "query",
            "description": "Load case Ids to filter by, in SG list format (e.g. `\"1,3-7,10\"`).\r\nOmit to return all load cases.",
            "schema": {
              "type": "string",
              "example": "1,3-7,10"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "TitleSearch",
            "in": "query",
            "description": "Search text to filter by title (case-insensitive contains).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Type",
            "in": "query",
            "description": "Filter by load case type (Primary, Combination, Step, Unused).",
            "schema": {
              "$ref": "#/components/schemas/LoadCaseType"
            }
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Expand",
            "in": "query",
            "description": "Sub-resource expansion. Defaults to `none`; pass `all` to hydrate combination items on combination cases.",
            "schema": {
              "$ref": "#/components/schemas/ExpandOption"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the list of load cases",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/LoadCase"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Load Cases"
        ],
        "summary": "Create Load Case",
        "description": "Creates a new load case. The case is initially type `Unused` until loads are\r\nassigned to it (or until combination items are added via `POST /combination-load-cases`,\r\nwhich creates the case as type `Combination`).",
        "requestBody": {
          "description": "The load case data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoadCaseCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/LoadCaseCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/LoadCaseCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Load case created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoadCase"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "A load case with the supplied Id already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/load-cases/{id}": {
      "get": {
        "tags": [
          "Load Cases"
        ],
        "summary": "Get Load Case",
        "description": "Gets a single load case by Id. `Expand` defaults to `all`, which hydrates\r\n`combinationItems` for combination cases; pass `Expand=none` to suppress.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The load case Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Expand",
            "in": "query",
            "description": "Sub-resource expansion. Defaults to `all`.",
            "schema": {
              "$ref": "#/components/schemas/ExpandOption"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the load case",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoadCase"
                }
              }
            }
          },
          "404": {
            "description": "Load case not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Load Cases"
        ],
        "summary": "Update Load Case",
        "description": "Partially updates a load case (title, notes). Only fields supplied in the body are\r\nchanged; omitted fields are left as-is.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The load case Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The partial update data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoadCaseUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/LoadCaseUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/LoadCaseUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the updated load case",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoadCase"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Load case not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Load Cases"
        ],
        "summary": "Delete Load Case",
        "description": "Removes the title, notes and metadata for the load case. Does not delete the actual\r\nloads assigned to the case or its combination items — the case may still appear in\r\nlistings if it has loads assigned to it.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The load case Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Load case deleted"
          },
          "404": {
            "description": "Load case not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/load-cases/metadata": {
      "get": {
        "tags": [
          "Load Cases"
        ],
        "summary": "Get Load Case Metadata",
        "description": "Returns the schema for a load case: field definitions, units resolved against current\r\njob units, and allowed values for enum fields (e.g. `type`).",
        "responses": {
          "200": {
            "description": "Returns load case schema metadata",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/load-cases/next": {
      "get": {
        "tags": [
          "Load Cases"
        ],
        "summary": "Get Next Load Case Id",
        "description": "Returns the next available (unused) load case Id, starting from start.",
        "parameters": [
          {
            "name": "start",
            "in": "query",
            "description": "The Id to start searching from (inclusive). Defaults to 1.",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the next available load case Id",
            "content": {
              "application/json": {
                "schema": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/load-cases/bulk": {
      "post": {
        "tags": [
          "Load Cases"
        ],
        "summary": "Create Load Cases (Bulk)",
        "description": "Creates multiple load cases in a single request. Validation runs upfront on the whole\r\nrequest; if any item fails and `continueOnError` is false (default), the entire\r\nrequest is rejected. With `continueOnError=true`, valid items are created and\r\nfailures are reported per-item in the response.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "If true, process valid items even when some fail. Default: false.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of load cases to create",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LoadCaseCreate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LoadCaseCreate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LoadCaseCreate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the bulk result (check the `errors` array for partial failures)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoadCaseBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Load Cases"
        ],
        "summary": "Update Load Cases (Bulk)",
        "description": "Partially updates multiple load cases. Each item must include its `id`.\r\nValidation runs upfront; with `continueOnError=false` (default) any failure\r\nrejects the whole request. With `continueOnError=true`, valid items are updated\r\nand failures are reported per-item.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "If true, process valid items even when some fail. Default: false.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of partial updates (each must include `id`)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LoadCaseUpdate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LoadCaseUpdate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LoadCaseUpdate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the bulk result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoadCaseBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Load Cases"
        ],
        "summary": "Delete Load Cases (Bulk)",
        "description": "Deletes multiple load cases by Id. The body is a JSON array of integer Ids\r\n(e.g. `[1, 5, 10]`). As with `DELETE /{id}`, this removes the\r\ntitle/notes/metadata only — assigned loads and combination items are preserved.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "If true, continue processing remaining Ids after a failure. Default: false.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "JSON array of load case Ids to delete",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the bulk result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Request body is missing or empty",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/load-categories": {
      "get": {
        "tags": [
          "Load Categories"
        ],
        "summary": "Get All",
        "description": "Gets all items with optional filtering, pagination and sub-resource expansion.\r\nResults are always sorted by Id ascending.\r\nPagination metadata is returned in response headers (Total-Count, Offset, Limit).\r\n`Expand` defaults to `none` on list endpoints so payloads stay lean;\r\npass `Expand=all` to hydrate sub-resources. Sub-resource expansion is\r\nopt-in per resource type — resources that don't define sub-resources ignore the parameter.",
        "parameters": [
          {
            "name": "Categories",
            "in": "query",
            "description": "Category Ids to filter by, in SG list format (e.g. `\"1,3-7,10\"`).\r\nOmit to return all categories.",
            "schema": {
              "type": "string",
              "example": "1,3-7,10"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "TitleSearch",
            "in": "query",
            "description": "Search text to filter by title (case-insensitive contains).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Expand",
            "in": "query",
            "description": "Sub-resource expansion. Defaults to `none`; pass `all` to hydrate sub-resources.",
            "schema": {
              "$ref": "#/components/schemas/ExpandOption"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/LoadCategory"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Load Categories"
        ],
        "summary": "Create",
        "description": "Creates a new item. If a validator is registered, the item is validated before creation.",
        "requestBody": {
          "description": "The data for the new item",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoadCategoryCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/LoadCategoryCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/LoadCategoryCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoadCategory"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/load-categories/{id}": {
      "get": {
        "tags": [
          "Load Categories"
        ],
        "summary": "Get by Id",
        "description": "`Expand` defaults to `all` on the single-item endpoint; pass `Expand=none`\r\n            to suppress sub-resource hydration. Sub-resource expansion is opt-in per resource type —\r\n            resources that don't define sub-resources ignore the parameter.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Expand",
            "in": "query",
            "description": "Sub-resource expansion. Defaults to `all`; pass `none` to suppress sub-resource hydration.",
            "schema": {
              "$ref": "#/components/schemas/ExpandOption"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoadCategory"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Load Categories"
        ],
        "summary": "Update",
        "description": "Updates an existing item. If a validator is registered, the update is validated first.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The partial update data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoadCategoryUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/LoadCategoryUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/LoadCategoryUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoadCategory"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Load Categories"
        ],
        "summary": "Delete",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/load-categories/metadata": {
      "get": {
        "tags": [
          "Load Categories"
        ],
        "summary": "Get Metadata",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/load-categories/next": {
      "get": {
        "tags": [
          "Load Categories"
        ],
        "summary": "Next Id",
        "description": "Gets the next available (unused) Id for this entity type.",
        "parameters": [
          {
            "name": "start",
            "in": "query",
            "description": "The Id value to start searching from (inclusive). Defaults to 1.",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/load-categories/bulk": {
      "post": {
        "tags": [
          "Load Categories"
        ],
        "summary": "Create Bulk",
        "description": "Creates multiple items in a bulk operation.\r\nIf a validator is registered, all items are validated upfront before any are created.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of items to create",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LoadCategoryCreate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LoadCategoryCreate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LoadCategoryCreate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoadCategoryBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Load Categories"
        ],
        "summary": "Update Bulk",
        "description": "Updates multiple items in a bulk operation.\r\nEach item must include its Id in the request body.\r\nIf a validator is registered, all items are validated upfront before any are updated.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of update objects (each must include Id)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LoadCategoryUpdate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LoadCategoryUpdate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LoadCategoryUpdate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoadCategoryBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Load Categories"
        ],
        "summary": "Delete Bulk",
        "description": "Deletes multiple entities by Id. The body is a JSON array of integer Ids\r\n(e.g. `[1, 5, 10]`) — consistent with every other bulk-delete endpoint\r\nin the API (see CLAUDE.md \"Query Parameter Conventions\").",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue on error",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "JSON array of entity Ids to delete",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/lumped-mass-loads": {
      "get": {
        "tags": [
          "Lumped Mass Loads"
        ],
        "summary": "Get All",
        "description": "Gets all loads with optional filtering and pagination.\r\nUse the `cases` query parameter to filter by load cases — accepts SG list format\r\n(e.g. `\"1,3-7,10\"`). Omit any list filter to match all.\r\nReturns an empty array when no loads match the filter — never 404.\r\nResults are sorted by Case ascending, then by entity Id ascending.\r\nPagination metadata is returned in response headers (Total-Count, Offset, Limit).",
        "parameters": [
          {
            "name": "Nodes",
            "in": "query",
            "description": "Node Ids to filter by, in SG list format (e.g. `\"1,5-10,12\"`).\r\nReturns only lumped masses applied to the specified nodes.\r\nOmit to return lumped masses for all nodes.",
            "schema": {
              "type": "string",
              "example": "1,5-10,12"
            },
            "example": "1,5-10,12"
          },
          {
            "name": "Cases",
            "in": "query",
            "description": "Load cases to filter by, in SG list format (e.g. `\"1,3-7,10\"`).\r\nReturns only loads belonging to the specified cases.\r\nOmit to return loads for all cases.",
            "schema": {
              "type": "string",
              "example": "1,3-7,10"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "LoadCategory",
            "in": "query",
            "description": "Filter by load category number.\r\nReturns only loads assigned to the specified category.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/LumpedMassLoad"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Lumped Mass Loads"
        ],
        "summary": "Create",
        "description": "Creates a new load. The load case must exist and be a Primary load case.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LumpedMassLoadCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/LumpedMassLoadCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/LumpedMassLoadCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/lumped-mass-loads/{caseId}/{nodeId}": {
      "get": {
        "tags": [
          "Lumped Mass Loads"
        ],
        "summary": "Get Lumped Mass Load",
        "description": "Gets a specific lumped mass load by its composite Id (case + node).",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "nodeId",
            "in": "path",
            "description": "The node number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the lumped mass load",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LumpedMassLoad"
                }
              }
            }
          },
          "404": {
            "description": "Lumped mass load not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Lumped Mass Loads"
        ],
        "summary": "Update Lumped Mass Load",
        "description": "Updates an existing lumped mass load. Only provided fields are updated.\r\nThe load case must be a Primary load case.",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "nodeId",
            "in": "path",
            "description": "The node number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The update data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LumpedMassLoadUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/LumpedMassLoadUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/LumpedMassLoadUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the updated lumped mass load",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LumpedMassLoad"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed or load case is not Primary",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Lumped mass load not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Lumped Mass Loads"
        ],
        "summary": "Delete Lumped Mass Load",
        "description": "Deletes a specific lumped mass load by its composite Id (case + node).",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "nodeId",
            "in": "path",
            "description": "The node number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Lumped mass load deleted successfully"
          },
          "404": {
            "description": "Lumped mass load not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/lumped-mass-loads/metadata": {
      "get": {
        "tags": [
          "Lumped Mass Loads"
        ],
        "summary": "Get Metadata",
        "description": "Returns schema metadata for this load entity type: field definitions, count, and key structure.\r\nField definitions include names, data types, units, and allowed value ranges.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/lumped-mass-loads/bulk": {
      "post": {
        "tags": [
          "Lumped Mass Loads"
        ],
        "summary": "Create Bulk",
        "description": "Creates multiple loads in a bulk operation.\r\nAll load cases referenced must exist and be Primary load cases.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of loads to create",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LumpedMassLoadCreate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LumpedMassLoadCreate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LumpedMassLoadCreate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Lumped Mass Loads"
        ],
        "summary": "Update Bulk",
        "description": "Updates multiple lumped mass loads. Each item must include case and node in the body.\r\nAll load cases referenced must be Primary.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of update objects (each must include case and node)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LumpedMassLoadUpdate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LumpedMassLoadUpdate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LumpedMassLoadUpdate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LumpedMassLoadBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Lumped Mass Loads"
        ],
        "summary": "Delete Bulk",
        "description": "Deletes multiple lumped mass loads. Both case and node are required for each entry —\r\nproviding only a case does not delete all lumped masses for that case.\r\nThe succeeded array echoes back the Ids of each successfully deleted load.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue on error",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of composite Id objects (case + node, both required)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LumpedMassLoadKey"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LumpedMassLoadKey"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LumpedMassLoadKey"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LumpedMassLoadKeyBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/materials": {
      "get": {
        "tags": [
          "Materials"
        ],
        "summary": "Get All",
        "description": "Gets all items with optional filtering, pagination and sub-resource expansion.\r\nResults are always sorted by Id ascending.\r\nPagination metadata is returned in response headers (Total-Count, Offset, Limit).\r\n`Expand` defaults to `none` on list endpoints so payloads stay lean;\r\npass `Expand=all` to hydrate sub-resources. Sub-resource expansion is\r\nopt-in per resource type — resources that don't define sub-resources ignore the parameter.",
        "parameters": [
          {
            "name": "Materials",
            "in": "query",
            "description": "Material Ids to filter by, in SG list format (e.g. `\"1,3-7,10\"`).\r\nOmit to return all materials.",
            "schema": {
              "type": "string",
              "example": "1,3-7,10"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Expand",
            "in": "query",
            "description": "Sub-resource expansion. Defaults to `none`; pass `all` to hydrate sub-resources.",
            "schema": {
              "$ref": "#/components/schemas/ExpandOption"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Material"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Materials"
        ],
        "summary": "Create",
        "description": "Creates a new item. If a validator is registered, the item is validated before creation.",
        "requestBody": {
          "description": "The data for the new item",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MaterialCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/MaterialCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/MaterialCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Material"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/materials/{id}": {
      "get": {
        "tags": [
          "Materials"
        ],
        "summary": "Get by Id",
        "description": "`Expand` defaults to `all` on the single-item endpoint; pass `Expand=none`\r\n            to suppress sub-resource hydration. Sub-resource expansion is opt-in per resource type —\r\n            resources that don't define sub-resources ignore the parameter.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Expand",
            "in": "query",
            "description": "Sub-resource expansion. Defaults to `all`; pass `none` to suppress sub-resource hydration.",
            "schema": {
              "$ref": "#/components/schemas/ExpandOption"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Material"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Materials"
        ],
        "summary": "Update",
        "description": "Updates an existing item. If a validator is registered, the update is validated first.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The partial update data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MaterialUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/MaterialUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/MaterialUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Material"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Materials"
        ],
        "summary": "Delete",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/materials/metadata": {
      "get": {
        "tags": [
          "Materials"
        ],
        "summary": "Get Metadata",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/materials/next": {
      "get": {
        "tags": [
          "Materials"
        ],
        "summary": "Next Id",
        "description": "Gets the next available (unused) Id for this entity type.",
        "parameters": [
          {
            "name": "start",
            "in": "query",
            "description": "The Id value to start searching from (inclusive). Defaults to 1.",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/materials/bulk": {
      "post": {
        "tags": [
          "Materials"
        ],
        "summary": "Create Bulk",
        "description": "Creates multiple items in a bulk operation.\r\nIf a validator is registered, all items are validated upfront before any are created.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of items to create",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MaterialCreate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MaterialCreate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MaterialCreate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MaterialBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Materials"
        ],
        "summary": "Update Bulk",
        "description": "Updates multiple items in a bulk operation.\r\nEach item must include its Id in the request body.\r\nIf a validator is registered, all items are validated upfront before any are updated.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of update objects (each must include Id)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MaterialUpdate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MaterialUpdate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MaterialUpdate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MaterialBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Materials"
        ],
        "summary": "Delete Bulk",
        "description": "Deletes multiple entities by Id. The body is a JSON array of integer Ids\r\n(e.g. `[1, 5, 10]`) — consistent with every other bulk-delete endpoint\r\nin the API (see CLAUDE.md \"Query Parameter Conventions\").",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue on error",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "JSON array of entity Ids to delete",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/materials/library": {
      "post": {
        "tags": [
          "Materials"
        ],
        "summary": "Create Library Material",
        "description": "Creates a material by looking it up in a SPACE GASS material library. All material\r\nproperties (Young's modulus, Poisson's ratio, mass density, thermal coefficient,\r\nconcrete strength) are populated from the library — the caller provides only the\r\nmaterial name and library.",
        "requestBody": {
          "description": "The library material to create",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MaterialLibraryCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/MaterialLibraryCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/MaterialLibraryCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Material created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Material"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request, or the specified material does not exist in the given library",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "A material with the specified Id already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/materials/library/bulk": {
      "post": {
        "tags": [
          "Materials"
        ],
        "summary": "Create Library Materials Bulk",
        "description": "Creates multiple library-sourced materials in a single request. Each material is\r\nresolved from the SPACE GASS material library by (name, library).",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of library materials to create",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MaterialLibraryCreate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MaterialLibraryCreate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MaterialLibraryCreate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Bulk operation completed (check succeeded/errors arrays)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MaterialBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or validation failure",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/materials/{id}/library": {
      "put": {
        "tags": [
          "Materials"
        ],
        "summary": "Replace With Library Material",
        "description": "Replaces the material at the given Id with a library-sourced material. The existing row\r\nis deleted and a new row is created at the same Id, resolved from the SPACE GASS\r\nmaterial library by (name, library). Use this to convert a User material to a Library\r\nmaterial, or to re-resolve an existing Library material against a different library\r\nentry. Any `id` in the request body is ignored — the route Id wins.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The Id of the material to replace",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The library material to put in its place",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MaterialLibraryCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/MaterialLibraryCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/MaterialLibraryCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Material replaced",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Material"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request, or the specified material does not exist in the given library",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "No material exists at the given Id",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/member-concentrated-loads": {
      "get": {
        "tags": [
          "Member Concentrated Loads"
        ],
        "summary": "Get All",
        "description": "Gets all loads with optional filtering and pagination.\r\nUse the `cases` query parameter to filter by load cases — accepts SG list format\r\n(e.g. `\"1,3-7,10\"`). Omit any list filter to match all.\r\nReturns an empty array when no loads match the filter — never 404.\r\nResults are sorted by Case ascending, then by entity Id ascending.\r\nPagination metadata is returned in response headers (Total-Count, Offset, Limit).",
        "parameters": [
          {
            "name": "Members",
            "in": "query",
            "description": "Member Ids to filter by, in SG list format (e.g. `\"1,3-7,10\"`).\r\nReturns only loads applied to the specified members.\r\nOmit to return loads for all members.",
            "schema": {
              "type": "string",
              "example": "1,3-7,10"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "Cases",
            "in": "query",
            "description": "Load cases to filter by, in SG list format (e.g. `\"1,3-7,10\"`).\r\nReturns only loads belonging to the specified cases.\r\nOmit to return loads for all cases.",
            "schema": {
              "type": "string",
              "example": "1,3-7,10"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "LoadCategory",
            "in": "query",
            "description": "Filter by load category number.\r\nReturns only loads assigned to the specified category.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/MemberConcentratedLoad"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Member Concentrated Loads"
        ],
        "summary": "Create",
        "description": "Creates a new load. The load case must exist and be a Primary load case.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberConcentratedLoadCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberConcentratedLoadCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/MemberConcentratedLoadCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/member-concentrated-loads/{caseId}/{memberId}/{subLoadId}": {
      "get": {
        "tags": [
          "Member Concentrated Loads"
        ],
        "summary": "Get Member Concentrated Load",
        "description": "Gets a specific member concentrated load by its composite Id (case + member + subLoad).",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "memberId",
            "in": "path",
            "description": "The member number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "subLoadId",
            "in": "path",
            "description": "The sub-load number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the member concentrated load",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberConcentratedLoad"
                }
              }
            }
          },
          "404": {
            "description": "Member concentrated load not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Member Concentrated Loads"
        ],
        "summary": "Update Member Concentrated Load",
        "description": "Updates an existing member concentrated load. Only provided fields are updated.\r\nThe load case must be a Primary load case.",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "memberId",
            "in": "path",
            "description": "The member number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "subLoadId",
            "in": "path",
            "description": "The sub-load number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The update data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberConcentratedLoadUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberConcentratedLoadUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/MemberConcentratedLoadUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the updated member concentrated load",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberConcentratedLoad"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed or load case is not Primary",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Member concentrated load not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Member Concentrated Loads"
        ],
        "summary": "Delete Member Concentrated Load",
        "description": "Deletes a specific member concentrated load by its composite Id (case + member + subLoad).",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "memberId",
            "in": "path",
            "description": "The member number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "subLoadId",
            "in": "path",
            "description": "The sub-load number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Member concentrated load deleted successfully"
          },
          "404": {
            "description": "Member concentrated load not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/member-concentrated-loads/metadata": {
      "get": {
        "tags": [
          "Member Concentrated Loads"
        ],
        "summary": "Get Metadata",
        "description": "Returns schema metadata for this load entity type: field definitions, count, and key structure.\r\nField definitions include names, data types, units, and allowed value ranges.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/member-concentrated-loads/bulk": {
      "post": {
        "tags": [
          "Member Concentrated Loads"
        ],
        "summary": "Create Bulk",
        "description": "Creates multiple loads in a bulk operation.\r\nAll load cases referenced must exist and be Primary load cases.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of loads to create",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberConcentratedLoadCreate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberConcentratedLoadCreate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberConcentratedLoadCreate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Member Concentrated Loads"
        ],
        "summary": "Update Bulk",
        "description": "Updates multiple member concentrated loads. Each item must include case, member, and subLoad in the body.\r\nAll load cases referenced must be Primary.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of update objects (each must include case, member, and subLoad)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberConcentratedLoadUpdate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberConcentratedLoadUpdate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberConcentratedLoadUpdate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberConcentratedLoadBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Member Concentrated Loads"
        ],
        "summary": "Delete Bulk",
        "description": "Deletes multiple member concentrated loads. Case, member, and subLoad are all required for each entry.\r\nThe succeeded array echoes back the Ids of each successfully deleted load.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue on error",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of composite Id objects (case + member + subLoad, all required)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberConcentratedLoadKey"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberConcentratedLoadKey"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberConcentratedLoadKey"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberConcentratedLoadKeyBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/member-distributed-loads": {
      "get": {
        "tags": [
          "Member Distributed Loads"
        ],
        "summary": "Get All",
        "description": "Gets all loads with optional filtering and pagination.\r\nUse the `cases` query parameter to filter by load cases — accepts SG list format\r\n(e.g. `\"1,3-7,10\"`). Omit any list filter to match all.\r\nReturns an empty array when no loads match the filter — never 404.\r\nResults are sorted by Case ascending, then by entity Id ascending.\r\nPagination metadata is returned in response headers (Total-Count, Offset, Limit).",
        "parameters": [
          {
            "name": "Members",
            "in": "query",
            "description": "Member Ids to filter by, in SG list format (e.g. `\"1,3-7,10\"`).\r\nReturns only loads applied to the specified members.\r\nOmit to return loads for all members.",
            "schema": {
              "type": "string",
              "example": "1,3-7,10"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "Cases",
            "in": "query",
            "description": "Load cases to filter by, in SG list format (e.g. `\"1,3-7,10\"`).\r\nReturns only loads belonging to the specified cases.\r\nOmit to return loads for all cases.",
            "schema": {
              "type": "string",
              "example": "1,3-7,10"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "LoadCategory",
            "in": "query",
            "description": "Filter by load category number.\r\nReturns only loads assigned to the specified category.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/MemberDistributedLoad"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Member Distributed Loads"
        ],
        "summary": "Create",
        "description": "Creates a new load. The load case must exist and be a Primary load case.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberDistributedLoadCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberDistributedLoadCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/MemberDistributedLoadCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/member-distributed-loads/{caseId}/{memberId}/{subLoadId}": {
      "get": {
        "tags": [
          "Member Distributed Loads"
        ],
        "summary": "Get Member Distributed Load",
        "description": "Gets a specific member distributed load by its composite Id (case + member + subLoad).",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "memberId",
            "in": "path",
            "description": "The member number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "subLoadId",
            "in": "path",
            "description": "The sub-load number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the member distributed load",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberDistributedLoad"
                }
              }
            }
          },
          "404": {
            "description": "Member distributed load not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Member Distributed Loads"
        ],
        "summary": "Update Member Distributed Load",
        "description": "Updates an existing member distributed load. Only provided fields are updated.\r\nThe load case must be a Primary load case.",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "memberId",
            "in": "path",
            "description": "The member number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "subLoadId",
            "in": "path",
            "description": "The sub-load number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The update data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberDistributedLoadUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberDistributedLoadUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/MemberDistributedLoadUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the updated member distributed load",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberDistributedLoad"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed or load case is not Primary",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Member distributed load not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Member Distributed Loads"
        ],
        "summary": "Delete Member Distributed Load",
        "description": "Deletes a specific member distributed load by its composite Id (case + member + subLoad).",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "memberId",
            "in": "path",
            "description": "The member number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "subLoadId",
            "in": "path",
            "description": "The sub-load number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Member distributed load deleted successfully"
          },
          "404": {
            "description": "Member distributed load not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/member-distributed-loads/metadata": {
      "get": {
        "tags": [
          "Member Distributed Loads"
        ],
        "summary": "Get Metadata",
        "description": "Returns schema metadata for this load entity type: field definitions, count, and key structure.\r\nField definitions include names, data types, units, and allowed value ranges.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/member-distributed-loads/bulk": {
      "post": {
        "tags": [
          "Member Distributed Loads"
        ],
        "summary": "Create Bulk",
        "description": "Creates multiple loads in a bulk operation.\r\nAll load cases referenced must exist and be Primary load cases.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of loads to create",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberDistributedLoadCreate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberDistributedLoadCreate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberDistributedLoadCreate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Member Distributed Loads"
        ],
        "summary": "Update Bulk",
        "description": "Updates multiple member distributed loads. Each item must include case, member, and subLoad in the body.\r\nAll load cases referenced must be Primary.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of update objects (each must include case, member, and subLoad)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberDistributedLoadUpdate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberDistributedLoadUpdate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberDistributedLoadUpdate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberDistributedLoadBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Member Distributed Loads"
        ],
        "summary": "Delete Bulk",
        "description": "Deletes multiple member distributed loads. Case, member, and subLoad are all required for each entry.\r\nThe succeeded array echoes back the Ids of each successfully deleted load.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue on error",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of composite Id objects (case + member + subLoad, all required)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberDistributedLoadKey"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberDistributedLoadKey"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberDistributedLoadKey"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberDistributedLoadKeyBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/member-distributed-moments": {
      "get": {
        "tags": [
          "Member Distributed Moments"
        ],
        "summary": "Get All",
        "description": "Gets all loads with optional filtering and pagination.\r\nUse the `cases` query parameter to filter by load cases — accepts SG list format\r\n(e.g. `\"1,3-7,10\"`). Omit any list filter to match all.\r\nReturns an empty array when no loads match the filter — never 404.\r\nResults are sorted by Case ascending, then by entity Id ascending.\r\nPagination metadata is returned in response headers (Total-Count, Offset, Limit).",
        "parameters": [
          {
            "name": "Members",
            "in": "query",
            "description": "Member Ids to filter by, in SG list format (e.g. `\"1,3-7,10\"`).\r\nReturns only loads applied to the specified members.\r\nOmit to return loads for all members.",
            "schema": {
              "type": "string",
              "example": "1,3-7,10"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "Cases",
            "in": "query",
            "description": "Load cases to filter by, in SG list format (e.g. `\"1,3-7,10\"`).\r\nReturns only loads belonging to the specified cases.\r\nOmit to return loads for all cases.",
            "schema": {
              "type": "string",
              "example": "1,3-7,10"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "LoadCategory",
            "in": "query",
            "description": "Filter by load category number.\r\nReturns only loads assigned to the specified category.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/MemberDistributedMoment"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Member Distributed Moments"
        ],
        "summary": "Create",
        "description": "Creates a new load. The load case must exist and be a Primary load case.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberDistributedMomentCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberDistributedMomentCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/MemberDistributedMomentCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/member-distributed-moments/{caseId}/{memberId}/{subLoadId}": {
      "get": {
        "tags": [
          "Member Distributed Moments"
        ],
        "summary": "Get Member Distributed Moment",
        "description": "Gets a specific member distributed moment by its composite Id (case + member + subLoad).",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "memberId",
            "in": "path",
            "description": "The member number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "subLoadId",
            "in": "path",
            "description": "The sub-load number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the member distributed moment",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberDistributedMoment"
                }
              }
            }
          },
          "404": {
            "description": "Member distributed moment not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Member Distributed Moments"
        ],
        "summary": "Update Member Distributed Moment",
        "description": "Updates an existing member distributed moment. Only provided fields are updated.\r\nThe load case must be a Primary load case.",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "memberId",
            "in": "path",
            "description": "The member number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "subLoadId",
            "in": "path",
            "description": "The sub-load number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The update data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberDistributedMomentUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberDistributedMomentUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/MemberDistributedMomentUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the updated member distributed moment",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberDistributedMoment"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed or load case is not Primary",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Member distributed moment not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Member Distributed Moments"
        ],
        "summary": "Delete Member Distributed Moment",
        "description": "Deletes a specific member distributed moment by its composite Id (case + member + subLoad).",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "memberId",
            "in": "path",
            "description": "The member number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "subLoadId",
            "in": "path",
            "description": "The sub-load number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Member distributed moment deleted successfully"
          },
          "404": {
            "description": "Member distributed moment not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/member-distributed-moments/metadata": {
      "get": {
        "tags": [
          "Member Distributed Moments"
        ],
        "summary": "Get Metadata",
        "description": "Returns schema metadata for this load entity type: field definitions, count, and key structure.\r\nField definitions include names, data types, units, and allowed value ranges.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/member-distributed-moments/bulk": {
      "post": {
        "tags": [
          "Member Distributed Moments"
        ],
        "summary": "Create Bulk",
        "description": "Creates multiple loads in a bulk operation.\r\nAll load cases referenced must exist and be Primary load cases.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of loads to create",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberDistributedMomentCreate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberDistributedMomentCreate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberDistributedMomentCreate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Member Distributed Moments"
        ],
        "summary": "Update Bulk",
        "description": "Updates multiple member distributed moments. Each item must include case, member, and subLoad in the body.\r\nAll load cases referenced must be Primary.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of update objects (each must include case, member, and subLoad)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberDistributedMomentUpdate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberDistributedMomentUpdate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberDistributedMomentUpdate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberDistributedMomentBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Member Distributed Moments"
        ],
        "summary": "Delete Bulk",
        "description": "Deletes multiple member distributed moments. Case, member, and subLoad are all required for each entry.\r\nThe succeeded array echoes back the Ids of each successfully deleted load.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue on error",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of composite Id objects (case + member + subLoad, all required)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberDistributedMomentKey"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberDistributedMomentKey"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberDistributedMomentKey"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberDistributedMomentKeyBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/member-offsets": {
      "get": {
        "tags": [
          "Member Offsets"
        ],
        "summary": "Get All",
        "description": "Returns all attribute rows for this resource type, with optional filtering.\r\nSorted by parent Id ascending. Pagination metadata is returned in response\r\nheaders (Total-Count, Offset, Limit).",
        "parameters": [
          {
            "name": "Members",
            "in": "query",
            "description": "Member Ids to filter offsets by, in SG list format (e.g. `\"1,5-10,15\"`).\r\nOmit to return all offsets.",
            "schema": {
              "type": "string",
              "example": "1,5-10,15"
            },
            "example": "1,5-10,15"
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/MemberOffset"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Member Offsets"
        ],
        "summary": "Create",
        "description": "Creates a new attribute row. The body must include the parent Id (e.g. `node`, `member`).\r\nReturns 409 if a row already exists for the supplied parent — PATCH instead, or DELETE first.\r\nReturns 404 if the parent does not exist.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberOffsetCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberOffsetCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/MemberOffsetCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberOffset"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/member-offsets/{memberId}": {
      "get": {
        "tags": [
          "Member Offsets"
        ],
        "summary": "Get Member Offsets",
        "description": "Gets the offsets row for a specific member — rigid end zones at each end.\r\nReturns 404 if no offsets row exists for the member.",
        "parameters": [
          {
            "name": "memberId",
            "in": "path",
            "description": "The member Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the member offsets",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberOffset"
                }
              }
            }
          },
          "404": {
            "description": "No offsets row exists for this member",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Member Offsets"
        ],
        "summary": "Update Member Offsets",
        "description": "Partially updates the offsets for a specific member.\r\nOnly fields included in the request are changed; omitted fields keep their current value.\r\nThe offsets row must already exist — use `POST /member-offsets` to create one.",
        "parameters": [
          {
            "name": "memberId",
            "in": "path",
            "description": "The member Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The partial update data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberOffsetUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberOffsetUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/MemberOffsetUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Offsets updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberOffset"
                }
              }
            }
          },
          "400": {
            "description": "Invalid update data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "No offsets row exists for this member",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Member Offsets"
        ],
        "summary": "Delete Member Offsets",
        "description": "Deletes the offsets row for a specific member. After deletion the member has no explicit\r\noffsets — both ends fall back to default behaviour (no rigid end zones).\r\nReturns 404 if no offsets row exists.",
        "parameters": [
          {
            "name": "memberId",
            "in": "path",
            "description": "The member Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Offsets deleted successfully"
          },
          "404": {
            "description": "No offsets row exists for this member",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/member-offsets/metadata": {
      "get": {
        "tags": [
          "Member Offsets"
        ],
        "summary": "Get Metadata",
        "description": "Returns the schema for the resource: field definitions, units resolved against current\r\njob units, and allowed values for enum fields.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/member-offsets/bulk": {
      "post": {
        "tags": [
          "Member Offsets"
        ],
        "summary": "Create Bulk",
        "description": "Creates multiple attribute rows in a single request. Each item must include its parent Id\r\nin the body. Returns 409 (per-item error) for any row whose parent already has an attribute.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberOffsetCreate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberOffsetCreate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberOffsetCreate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberOffsetBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Member Offsets"
        ],
        "summary": "Update Bulk",
        "description": "Updates multiple attribute rows in a single request. Each item must include its parent Id.\r\nPer-item 404 reported as a bulk error if no row exists for the supplied parent.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberOffsetUpdate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberOffsetUpdate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberOffsetUpdate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberOffsetBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Member Offsets"
        ],
        "summary": "Delete Bulk",
        "description": "Deletes multiple attribute rows by parent Id. The body is a JSON array of integer parent Ids.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/member-prestress-loads": {
      "get": {
        "tags": [
          "Member Prestress Loads"
        ],
        "summary": "Get All",
        "description": "Gets all loads with optional filtering and pagination.\r\nUse the `cases` query parameter to filter by load cases — accepts SG list format\r\n(e.g. `\"1,3-7,10\"`). Omit any list filter to match all.\r\nReturns an empty array when no loads match the filter — never 404.\r\nResults are sorted by Case ascending, then by entity Id ascending.\r\nPagination metadata is returned in response headers (Total-Count, Offset, Limit).",
        "parameters": [
          {
            "name": "Members",
            "in": "query",
            "description": "Member Ids to filter by, in SG list format (e.g. `\"1,3-7,10\"`).\r\nReturns only prestress loads applied to the specified members.\r\nOmit to return prestress loads for all members.",
            "schema": {
              "type": "string",
              "example": "1,3-7,10"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "Cases",
            "in": "query",
            "description": "Load cases to filter by, in SG list format (e.g. `\"1,3-7,10\"`).\r\nReturns only loads belonging to the specified cases.\r\nOmit to return loads for all cases.",
            "schema": {
              "type": "string",
              "example": "1,3-7,10"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "LoadCategory",
            "in": "query",
            "description": "Filter by load category number.\r\nReturns only loads assigned to the specified category.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/MemberPrestressLoad"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Member Prestress Loads"
        ],
        "summary": "Create",
        "description": "Creates a new load. The load case must exist and be a Primary load case.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberPrestressLoadCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberPrestressLoadCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/MemberPrestressLoadCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/member-prestress-loads/{caseId}/{memberId}": {
      "get": {
        "tags": [
          "Member Prestress Loads"
        ],
        "summary": "Get Member Prestress Load",
        "description": "Gets a specific member prestress load by its composite Id (case + member).",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "memberId",
            "in": "path",
            "description": "The member number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the member prestress load",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberPrestressLoad"
                }
              }
            }
          },
          "404": {
            "description": "Member prestress load not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Member Prestress Loads"
        ],
        "summary": "Update Member Prestress Load",
        "description": "Updates an existing member prestress load. Only provided fields are updated.\r\nThe load case must be a Primary load case.",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "memberId",
            "in": "path",
            "description": "The member number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The update data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberPrestressLoadUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberPrestressLoadUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/MemberPrestressLoadUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the updated member prestress load",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberPrestressLoad"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed or load case is not Primary",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Member prestress load not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Member Prestress Loads"
        ],
        "summary": "Delete Member Prestress Load",
        "description": "Deletes a specific member prestress load by its composite Id (case + member).",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "memberId",
            "in": "path",
            "description": "The member number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Member prestress load deleted successfully"
          },
          "404": {
            "description": "Member prestress load not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/member-prestress-loads/metadata": {
      "get": {
        "tags": [
          "Member Prestress Loads"
        ],
        "summary": "Get Metadata",
        "description": "Returns schema metadata for this load entity type: field definitions, count, and key structure.\r\nField definitions include names, data types, units, and allowed value ranges.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/member-prestress-loads/bulk": {
      "post": {
        "tags": [
          "Member Prestress Loads"
        ],
        "summary": "Create Bulk",
        "description": "Creates multiple loads in a bulk operation.\r\nAll load cases referenced must exist and be Primary load cases.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of loads to create",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberPrestressLoadCreate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberPrestressLoadCreate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberPrestressLoadCreate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Member Prestress Loads"
        ],
        "summary": "Update Bulk",
        "description": "Updates multiple member prestress loads. Each item must include case and member in the body.\r\nAll load cases referenced must be Primary.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of update objects (each must include case and member)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberPrestressLoadUpdate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberPrestressLoadUpdate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberPrestressLoadUpdate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberPrestressLoadBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Member Prestress Loads"
        ],
        "summary": "Delete Bulk",
        "description": "Deletes multiple member prestress loads. Both case and member are required for each entry —\r\nproviding only a case does not delete all prestress loads for that case.\r\nThe succeeded array echoes back the Ids of each successfully deleted load.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue on error",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of composite Id objects (case + member, both required)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberPrestressLoadKey"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberPrestressLoadKey"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberPrestressLoadKey"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberPrestressLoadKeyBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/members": {
      "get": {
        "tags": [
          "Members"
        ],
        "summary": "Get All",
        "description": "Gets all items with optional filtering, pagination and sub-resource expansion.\r\nResults are always sorted by Id ascending.\r\nPagination metadata is returned in response headers (Total-Count, Offset, Limit).\r\n`Expand` defaults to `none` on list endpoints so payloads stay lean;\r\npass `Expand=all` to hydrate sub-resources. Sub-resource expansion is\r\nopt-in per resource type — resources that don't define sub-resources ignore the parameter.",
        "parameters": [
          {
            "name": "Members",
            "in": "query",
            "description": "Member Ids to filter by, in SG list format (e.g. `\"1,3-7,10\"`).\r\nOmit to return all members.",
            "schema": {
              "type": "string",
              "example": "1,3-7,10"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "Type",
            "in": "query",
            "description": "Filter by member type (Normal, TensionOnly, CompressionOnly, Cable, Gap, BrittleFuse, PlasticFuse).",
            "schema": {
              "$ref": "#/components/schemas/MemberType"
            }
          },
          {
            "name": "Section",
            "in": "query",
            "description": "Filter by section number.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Material",
            "in": "query",
            "description": "Filter by material number.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Expand",
            "in": "query",
            "description": "Sub-resource expansion. Defaults to `none`; pass `all` to hydrate sub-resources.",
            "schema": {
              "$ref": "#/components/schemas/ExpandOption"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Member"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Members"
        ],
        "summary": "Create",
        "description": "Creates a new item. If a validator is registered, the item is validated before creation.",
        "requestBody": {
          "description": "The data for the new item",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/MemberCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Member"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/members/{id}": {
      "get": {
        "tags": [
          "Members"
        ],
        "summary": "Get by Id",
        "description": "`Expand` defaults to `all` on the single-item endpoint; pass `Expand=none`\r\n            to suppress sub-resource hydration. Sub-resource expansion is opt-in per resource type —\r\n            resources that don't define sub-resources ignore the parameter.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Expand",
            "in": "query",
            "description": "Sub-resource expansion. Defaults to `all`; pass `none` to suppress sub-resource hydration.",
            "schema": {
              "$ref": "#/components/schemas/ExpandOption"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Member"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Members"
        ],
        "summary": "Update",
        "description": "Updates an existing item. If a validator is registered, the update is validated first.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The partial update data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/MemberUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Member"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Members"
        ],
        "summary": "Delete",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/members/{id}/direction": {
      "get": {
        "tags": [
          "Members"
        ],
        "summary": "Get Direction",
        "description": "Gets the direction for a specific member.\r\nReturns the active source (Angle, Node, or Axis) and all three underlying field values.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The member Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the member direction",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberDirection"
                }
              }
            }
          },
          "401": {
            "description": "If the API key is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Member not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Members"
        ],
        "summary": "Set Direction",
        "description": "Sets the direction for a specific member. Exactly one of `dirAngle`,\r\n`dirNode`, or `dirAxis` must be supplied — the underlying datasheet row\r\nenforces mutual exclusion, so the supplied field is written and SG's per-field\r\nhelper zeros the other two for the row.\r\nA missing or empty body is rejected with 400 (PUT expects a meaningful payload).\r\n            \r\nUses PUT because today every write replaces the full direction state (the mutex\r\ninvariant zeros the other two fields). When SG stores a discriminator on the\r\nrow, a sibling PATCH endpoint will be added that supports true single-field\r\npartial updates without touching the others.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The member Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The direction to set — exactly one of `dirAngle`, `dirNode`, or `dirAxis` must be supplied",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DirectionUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/DirectionUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/DirectionUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Direction updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberDirection"
                }
              }
            }
          },
          "400": {
            "description": "Invalid direction data — missing or empty body, multiple value fields supplied, or a non-existent direction node",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "If the API key is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Member not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/members/{id}/releases": {
      "get": {
        "tags": [
          "Members"
        ],
        "summary": "Get Releases",
        "description": "Gets the releases for a specific member.\r\nReturns the member release conditions (fixed, pinned, etc.).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The member Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the member releases",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberRelease"
                }
              }
            }
          },
          "404": {
            "description": "Member not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Members"
        ],
        "summary": "Update Releases",
        "description": "Partially updates the releases for a specific member.\r\nOnly provided fields are updated; omitted fields remain unchanged.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The member Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The partial update data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberReleaseUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberReleaseUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/MemberReleaseUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Releases updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberRelease"
                }
              }
            }
          },
          "400": {
            "description": "Invalid update data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Member not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Members"
        ],
        "summary": "Reset Releases",
        "description": "Resets the releases for a specific member to defaults.\r\nRemoves any custom release configuration.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The member Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Releases reset successfully"
          },
          "404": {
            "description": "Member not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/members/direction/metadata": {
      "get": {
        "tags": [
          "Members"
        ],
        "summary": "Get Direction Metadata",
        "description": "Returns the schema for the member-direction sub-resource: field definitions,\r\nunits resolved against current job units, and allowed values for enum fields.\r\nFields mirror the shape of the `direction` object on member responses.",
        "responses": {
          "200": {
            "description": "Returns direction schema metadata",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "401": {
            "description": "If the API key is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/members/metadata": {
      "get": {
        "tags": [
          "Members"
        ],
        "summary": "Get Metadata",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/members/next": {
      "get": {
        "tags": [
          "Members"
        ],
        "summary": "Next Id",
        "description": "Gets the next available (unused) Id for this entity type.",
        "parameters": [
          {
            "name": "start",
            "in": "query",
            "description": "The Id value to start searching from (inclusive). Defaults to 1.",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/members/releases/metadata": {
      "get": {
        "tags": [
          "Members"
        ],
        "summary": "Get Releases Metadata",
        "description": "Returns the schema for the member-releases sub-resource: field definitions,\r\nunits resolved against current job units, and allowed values for enum fields.\r\nFields mirror the shape returned by `GET members/{key}/releases`.",
        "responses": {
          "200": {
            "description": "Returns release schema metadata",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/members/bulk": {
      "post": {
        "tags": [
          "Members"
        ],
        "summary": "Create Bulk",
        "description": "Creates multiple items in a bulk operation.\r\nIf a validator is registered, all items are validated upfront before any are created.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of items to create",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberCreate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberCreate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberCreate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Members"
        ],
        "summary": "Update Bulk",
        "description": "Updates multiple items in a bulk operation.\r\nEach item must include its Id in the request body.\r\nIf a validator is registered, all items are validated upfront before any are updated.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of update objects (each must include Id)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberUpdate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberUpdate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MemberUpdate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Members"
        ],
        "summary": "Delete Bulk",
        "description": "Deletes multiple entities by Id. The body is a JSON array of integer Ids\r\n(e.g. `[1, 5, 10]`) — consistent with every other bulk-delete endpoint\r\nin the API (see CLAUDE.md \"Query Parameter Conventions\").",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue on error",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "JSON array of entity Ids to delete",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/node-constraints": {
      "get": {
        "tags": [
          "Node Constraints"
        ],
        "summary": "Get All",
        "description": "Returns all attribute rows for this resource type, with optional filtering.\r\nSorted by parent Id ascending. Pagination metadata is returned in response\r\nheaders (Total-Count, Offset, Limit).",
        "parameters": [
          {
            "name": "Slaves",
            "in": "query",
            "description": "Slave node Ids to filter by, in SG list format (e.g. `\"1,5-10,15\"`).\r\nOmit to return all constraints.",
            "schema": {
              "type": "string",
              "example": "1,5-10,15"
            },
            "example": "1,5-10,15"
          },
          {
            "name": "MasterNode",
            "in": "query",
            "description": "Filter by master node number — returns only constraints whose master node matches.\r\nOmit to return constraints regardless of master.",
            "schema": {
              "type": "integer",
              "format": "int32",
              "example": 1
            },
            "example": 1
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/NodeConstraint"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Node Constraints"
        ],
        "summary": "Create",
        "description": "Creates a new attribute row. The body must include the parent Id (e.g. `node`, `member`).\r\nReturns 409 if a row already exists for the supplied parent — PATCH instead, or DELETE first.\r\nReturns 404 if the parent does not exist.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NodeConstraintCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/NodeConstraintCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/NodeConstraintCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NodeConstraint"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/node-constraints/{nodeId}": {
      "get": {
        "tags": [
          "Node Constraints"
        ],
        "summary": "Get Node Constraint",
        "description": "Gets the master-slave constraint for a specific slave node. Returns 404 if no\r\nconstraint is defined for the node. Each node can be a slave in at most one constraint.",
        "parameters": [
          {
            "name": "nodeId",
            "in": "path",
            "description": "The slave node Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the node constraint",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NodeConstraint"
                }
              }
            }
          },
          "404": {
            "description": "No constraint defined for this node",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Node Constraints"
        ],
        "summary": "Update Node Constraint",
        "description": "Partially updates the master-slave constraint for a specific slave node.\r\nOnly provided fields are updated; omitted fields remain unchanged.\r\nThe constraint must already exist — use `POST /node-constraints` to create one.\r\nIf `masterNode` is supplied it must reference an existing node and not equal the slave.",
        "parameters": [
          {
            "name": "nodeId",
            "in": "path",
            "description": "The slave node Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The partial update data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NodeConstraintUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/NodeConstraintUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/NodeConstraintUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Constraint updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NodeConstraint"
                }
              }
            }
          },
          "400": {
            "description": "Invalid update data (e.g. master == slave, or master node not found)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "No constraint defined for this node",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Node Constraints"
        ],
        "summary": "Delete Node Constraint",
        "description": "Deletes the master-slave constraint for a specific slave node.\r\nReturns 404 if no constraint is defined for the node.",
        "parameters": [
          {
            "name": "nodeId",
            "in": "path",
            "description": "The slave node Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Constraint deleted successfully"
          },
          "404": {
            "description": "No constraint defined for this node",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/node-constraints/metadata": {
      "get": {
        "tags": [
          "Node Constraints"
        ],
        "summary": "Get Metadata",
        "description": "Returns the schema for the resource: field definitions, units resolved against current\r\njob units, and allowed values for enum fields.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/node-constraints/bulk": {
      "post": {
        "tags": [
          "Node Constraints"
        ],
        "summary": "Create Bulk",
        "description": "Creates multiple attribute rows in a single request. Each item must include its parent Id\r\nin the body. Returns 409 (per-item error) for any row whose parent already has an attribute.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeConstraintCreate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeConstraintCreate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeConstraintCreate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NodeConstraintBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Node Constraints"
        ],
        "summary": "Update Bulk",
        "description": "Updates multiple attribute rows in a single request. Each item must include its parent Id.\r\nPer-item 404 reported as a bulk error if no row exists for the supplied parent.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeConstraintUpdate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeConstraintUpdate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeConstraintUpdate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NodeConstraintBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Node Constraints"
        ],
        "summary": "Delete Bulk",
        "description": "Deletes multiple attribute rows by parent Id. The body is a JSON array of integer parent Ids.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/node-displacements": {
      "get": {
        "tags": [
          "Node Displacements"
        ],
        "summary": "Get All",
        "description": "Gets all loads with optional filtering and pagination.\r\nUse the `cases` query parameter to filter by load cases — accepts SG list format\r\n(e.g. `\"1,3-7,10\"`). Omit any list filter to match all.\r\nReturns an empty array when no loads match the filter — never 404.\r\nResults are sorted by Case ascending, then by entity Id ascending.\r\nPagination metadata is returned in response headers (Total-Count, Offset, Limit).",
        "parameters": [
          {
            "name": "Nodes",
            "in": "query",
            "description": "Node Ids to filter by, in SG list format (e.g. `\"1,5-10,12\"`).\r\nReturns only displacements applied to the specified nodes.\r\nOmit to return displacements for all nodes.",
            "schema": {
              "type": "string",
              "example": "1,5-10,12"
            },
            "example": "1,5-10,12"
          },
          {
            "name": "Cases",
            "in": "query",
            "description": "Load cases to filter by, in SG list format (e.g. `\"1,3-7,10\"`).\r\nReturns only loads belonging to the specified cases.\r\nOmit to return loads for all cases.",
            "schema": {
              "type": "string",
              "example": "1,3-7,10"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "LoadCategory",
            "in": "query",
            "description": "Filter by load category number.\r\nReturns only loads assigned to the specified category.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PrescribedDisplacement"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Node Displacements"
        ],
        "summary": "Create",
        "description": "Creates a new load. The load case must exist and be a Primary load case.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PrescribedDisplacementCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PrescribedDisplacementCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PrescribedDisplacementCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/node-displacements/{caseId}/{nodeId}": {
      "get": {
        "tags": [
          "Node Displacements"
        ],
        "summary": "Get Prescribed Displacement",
        "description": "Gets a specific prescribed displacement by its composite Id (case + node).",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "nodeId",
            "in": "path",
            "description": "The node number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the prescribed displacement",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PrescribedDisplacement"
                }
              }
            }
          },
          "404": {
            "description": "Prescribed displacement not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Node Displacements"
        ],
        "summary": "Update Prescribed Displacement",
        "description": "Updates an existing prescribed displacement. Only provided fields are updated.\r\nThe load case must be a Primary load case.",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "nodeId",
            "in": "path",
            "description": "The node number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The update data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PrescribedDisplacementUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PrescribedDisplacementUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PrescribedDisplacementUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the updated prescribed displacement",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PrescribedDisplacement"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed or load case is not Primary",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Prescribed displacement not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Node Displacements"
        ],
        "summary": "Delete Prescribed Displacement",
        "description": "Deletes a specific prescribed displacement by its composite Id (case + node).",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "nodeId",
            "in": "path",
            "description": "The node number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Prescribed displacement deleted successfully"
          },
          "404": {
            "description": "Prescribed displacement not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/node-displacements/metadata": {
      "get": {
        "tags": [
          "Node Displacements"
        ],
        "summary": "Get Metadata",
        "description": "Returns schema metadata for this load entity type: field definitions, count, and key structure.\r\nField definitions include names, data types, units, and allowed value ranges.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/node-displacements/bulk": {
      "post": {
        "tags": [
          "Node Displacements"
        ],
        "summary": "Create Bulk",
        "description": "Creates multiple loads in a bulk operation.\r\nAll load cases referenced must exist and be Primary load cases.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of loads to create",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PrescribedDisplacementCreate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PrescribedDisplacementCreate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PrescribedDisplacementCreate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Node Displacements"
        ],
        "summary": "Update Bulk",
        "description": "Updates multiple prescribed displacements. Each item must include case and node in the body.\r\nAll load cases referenced must be Primary.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of update objects (each must include case and node)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PrescribedDisplacementUpdate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PrescribedDisplacementUpdate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PrescribedDisplacementUpdate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PrescribedDisplacementBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Node Displacements"
        ],
        "summary": "Delete Bulk",
        "description": "Deletes multiple prescribed displacements. Both case and node are required for each entry —\r\nproviding only a case does not delete all displacements for that case.\r\nThe succeeded array echoes back the Ids of each successfully deleted displacement.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue on error",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of composite Id objects (case + node, both required)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PrescribedDisplacementKey"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PrescribedDisplacementKey"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PrescribedDisplacementKey"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PrescribedDisplacementKeyBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/node-loads": {
      "get": {
        "tags": [
          "Node Loads"
        ],
        "summary": "Get All",
        "description": "Gets all loads with optional filtering and pagination.\r\nUse the `cases` query parameter to filter by load cases — accepts SG list format\r\n(e.g. `\"1,3-7,10\"`). Omit any list filter to match all.\r\nReturns an empty array when no loads match the filter — never 404.\r\nResults are sorted by Case ascending, then by entity Id ascending.\r\nPagination metadata is returned in response headers (Total-Count, Offset, Limit).",
        "parameters": [
          {
            "name": "Nodes",
            "in": "query",
            "description": "Node Ids to filter by, in SG list format (e.g. `\"1,5-10,12\"`).\r\nReturns only loads applied to the specified nodes.\r\nOmit to return loads for all nodes.",
            "schema": {
              "type": "string",
              "example": "1,5-10,12"
            },
            "example": "1,5-10,12"
          },
          {
            "name": "Cases",
            "in": "query",
            "description": "Load cases to filter by, in SG list format (e.g. `\"1,3-7,10\"`).\r\nReturns only loads belonging to the specified cases.\r\nOmit to return loads for all cases.",
            "schema": {
              "type": "string",
              "example": "1,3-7,10"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "LoadCategory",
            "in": "query",
            "description": "Filter by load category number.\r\nReturns only loads assigned to the specified category.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/NodeLoad"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Node Loads"
        ],
        "summary": "Create",
        "description": "Creates a new load. The load case must exist and be a Primary load case.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NodeLoadCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/NodeLoadCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/NodeLoadCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/node-loads/{caseId}/{nodeId}": {
      "get": {
        "tags": [
          "Node Loads"
        ],
        "summary": "Get Node Load",
        "description": "Gets a specific node load by its composite Id (case + node).",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "nodeId",
            "in": "path",
            "description": "The node number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the node load",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NodeLoad"
                }
              }
            }
          },
          "404": {
            "description": "Node load not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Node Loads"
        ],
        "summary": "Update Node Load",
        "description": "Updates an existing node load. Only provided fields are updated.\r\nThe load case must be a Primary load case.",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "nodeId",
            "in": "path",
            "description": "The node number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The update data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NodeLoadUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/NodeLoadUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/NodeLoadUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the updated node load",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NodeLoad"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed or load case is not Primary",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Node load not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Node Loads"
        ],
        "summary": "Delete Node Load",
        "description": "Deletes a specific node load by its composite Id (case + node).",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "nodeId",
            "in": "path",
            "description": "The node number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Node load deleted successfully"
          },
          "404": {
            "description": "Node load not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/node-loads/metadata": {
      "get": {
        "tags": [
          "Node Loads"
        ],
        "summary": "Get Metadata",
        "description": "Returns schema metadata for this load entity type: field definitions, count, and key structure.\r\nField definitions include names, data types, units, and allowed value ranges.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/node-loads/bulk": {
      "post": {
        "tags": [
          "Node Loads"
        ],
        "summary": "Create Bulk",
        "description": "Creates multiple loads in a bulk operation.\r\nAll load cases referenced must exist and be Primary load cases.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of loads to create",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeLoadCreate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeLoadCreate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeLoadCreate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Node Loads"
        ],
        "summary": "Update Bulk",
        "description": "Updates multiple node loads. Each item must include case and node in the body.\r\nAll load cases referenced must be Primary.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of update objects (each must include case and node)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeLoadUpdate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeLoadUpdate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeLoadUpdate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NodeLoadBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Node Loads"
        ],
        "summary": "Delete Bulk",
        "description": "Deletes multiple node loads. Both case and node are required for each entry —\r\nproviding only a case does not delete all loads for that case.\r\nThe succeeded array echoes back the Ids of each successfully deleted load.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue on error",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of composite Id objects (case + node, both required)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeLoadKey"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeLoadKey"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeLoadKey"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NodeLoadKeyBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/node-restraints": {
      "get": {
        "tags": [
          "Node Restraints"
        ],
        "summary": "Get All",
        "description": "Returns all attribute rows for this resource type, with optional filtering.\r\nSorted by parent Id ascending. Pagination metadata is returned in response\r\nheaders (Total-Count, Offset, Limit).",
        "parameters": [
          {
            "name": "Nodes",
            "in": "query",
            "description": "Node Ids to filter restraints by, in SG list format (e.g. `\"1,5-10,15\"`).\r\nOmit to return all restraints.",
            "schema": {
              "type": "string",
              "example": "1,5-10,15"
            },
            "example": "1,5-10,15"
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/NodeRestraint"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Node Restraints"
        ],
        "summary": "Create Node Restraint",
        "description": "Creates a new restraint row for the supplied node. Body must include the parent\r\n`node` Id. Returns 409 if a restraint already exists for that node — caller\r\nmust DELETE first or use PATCH to update. Returns 404 if the node does not exist.\r\nVariable-stiffness tables can be supplied inline; the corresponding restraintCode\r\nposition must be 'V'.",
        "requestBody": {
          "description": "The restraint data, including the parent node Id",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NodeRestraintCreate"
              },
              "example": {
                "node": 5,
                "restraintCode": "FFFRRR",
                "activeDirection": "BBBBBB",
                "txStiffness": 0,
                "tyStiffness": 0,
                "tzStiffness": 0,
                "rxStiffness": 0,
                "ryStiffness": 0,
                "rzStiffness": 0,
                "xFrictionNormalAxis": "None",
                "yFrictionNormalAxis": "None",
                "zFrictionNormalAxis": "None",
                "xFrictionNormalDirection": "Either",
                "yFrictionNormalDirection": "Either",
                "zFrictionNormalDirection": "Either",
                "xFrictionFactor": 0,
                "yFrictionFactor": 0,
                "zFrictionFactor": 0,
                "txPlasticLimit": 0,
                "tyPlasticLimit": 0,
                "tzPlasticLimit": 0,
                "rxPlasticLimit": 0,
                "ryPlasticLimit": 0,
                "rzPlasticLimit": 0
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/NodeRestraintCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/NodeRestraintCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Restraint created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NodeRestraint"
                }
              }
            }
          },
          "400": {
            "description": "Invalid restraint data (e.g. malformed restraintCode or table)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Node not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "A restraint already exists for this node",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/node-restraints/{nodeId}": {
      "get": {
        "tags": [
          "Node Restraints"
        ],
        "summary": "Get Node Restraint",
        "description": "Gets the restraint for a specific node — boundary conditions and spring stiffness.\r\nReturns 404 if no explicit restraint row exists for the node. Variable-stiffness\r\ntables for V-type DOFs are inlined on the response when present.",
        "parameters": [
          {
            "name": "nodeId",
            "in": "path",
            "description": "The node Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the node restraint",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NodeRestraint"
                }
              }
            }
          },
          "404": {
            "description": "No restraint row exists for this node",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Node Restraints"
        ],
        "summary": "Update Node Restraint",
        "description": "Partially updates the restraint for a specific node.\r\nOnly fields included in the request are changed; omitted fields keep their current value.\r\nThe restraint must already exist — use `POST /node-restraints` to create one.\r\nVariable-stiffness tables can be supplied inline; the corresponding restraintCode position\r\nmust be 'V' (after the update is applied).",
        "parameters": [
          {
            "name": "nodeId",
            "in": "path",
            "description": "The node Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The partial update data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NodeRestraintUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/NodeRestraintUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/NodeRestraintUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Restraint updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NodeRestraint"
                }
              }
            }
          },
          "400": {
            "description": "Invalid update data (e.g. malformed restraintCode or table)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "No restraint row exists for this node",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Node Restraints"
        ],
        "summary": "Delete Node Restraint",
        "description": "Deletes the restraint row for a specific node. After deletion the node has no explicit\r\nrestraint — it falls back to default behaviour (all DOFs free, no spring stiffness).\r\nReturns 404 if no restraint row exists.",
        "parameters": [
          {
            "name": "nodeId",
            "in": "path",
            "description": "The node Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Restraint deleted successfully"
          },
          "404": {
            "description": "No restraint row exists for this node",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/node-restraints/{nodeId}/table/{direction}": {
      "get": {
        "tags": [
          "Node Restraints"
        ],
        "summary": "Get Restraint Table Data",
        "description": "Returns the variable-stiffness table for one DOF on a node restraint.\r\n404 if the node has no restraint row, or if the table for that DOF is empty.\r\nSchema metadata (axis labels, units, bounds) is available at\r\n`GET /node-restraints/table/{direction}/metadata`.",
        "parameters": [
          {
            "name": "nodeId",
            "in": "path",
            "description": "The node Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "direction",
            "in": "path",
            "description": "The DOF (Tx, Ty, Tz, Rx, Ry, Rz)",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/StiffnessDirection"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the table",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "number",
                      "format": "double"
                    }
                  },
                  "description": "A generic 2D data table — row-major, where each row is an array of column values.\r\nReused across the API for any tabular (X, Y, …) data such as restraint\r\nvariable-stiffness curves, derived force-vs-deflection views, material curves, etc.\r\nSchema (column names, types, units, bounds) is returned by the resource's dedicated\r\ntable-metadata endpoint and is not embedded here."
                }
              }
            }
          },
          "404": {
            "description": "No table exists for this node and direction",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Node Restraints"
        ],
        "summary": "Set Restraint Table Data",
        "description": "Creates or replaces the variable-stiffness table for one DOF on a node restraint.\r\nThe node must already have a restraint row (POST `/node-restraints` to create one),\r\nand the corresponding character of `restraintCode` must be 'V'.\r\n            \r\nBody is a TableDto whose `rows` field is a list of 1–15 (x, y) pairs.\r\nX is deflection (translational) or rotation (rotational), Y is the spring stiffness.\r\nThe first point's X must be 0 (the base stiffness anchor); X values must be unique;\r\nX and Y must be ≥ 0.",
        "parameters": [
          {
            "name": "nodeId",
            "in": "path",
            "description": "The node Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "direction",
            "in": "path",
            "description": "The DOF (Tx, Ty, Tz, Rx, Ry, Rz)",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/StiffnessDirection"
            }
          }
        ],
        "requestBody": {
          "description": "The table to upsert",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "array",
                  "items": {
                    "type": "number",
                    "format": "double"
                  }
                },
                "description": "A generic 2D data table — row-major, where each row is an array of column values.\r\nReused across the API for any tabular (X, Y, …) data such as restraint\r\nvariable-stiffness curves, derived force-vs-deflection views, material curves, etc.\r\nSchema (column names, types, units, bounds) is returned by the resource's dedicated\r\ntable-metadata endpoint and is not embedded here."
              },
              "example": [
                [
                  0,
                  90000
                ],
                [
                  4.8,
                  62000
                ]
              ]
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "array",
                  "items": {
                    "type": "number",
                    "format": "double"
                  }
                },
                "description": "A generic 2D data table — row-major, where each row is an array of column values.\r\nReused across the API for any tabular (X, Y, …) data such as restraint\r\nvariable-stiffness curves, derived force-vs-deflection views, material curves, etc.\r\nSchema (column names, types, units, bounds) is returned by the resource's dedicated\r\ntable-metadata endpoint and is not embedded here."
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "array",
                  "items": {
                    "type": "number",
                    "format": "double"
                  }
                },
                "description": "A generic 2D data table — row-major, where each row is an array of column values.\r\nReused across the API for any tabular (X, Y, …) data such as restraint\r\nvariable-stiffness curves, derived force-vs-deflection views, material curves, etc.\r\nSchema (column names, types, units, bounds) is returned by the resource's dedicated\r\ntable-metadata endpoint and is not embedded here."
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Table created/replaced successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "number",
                      "format": "double"
                    }
                  },
                  "description": "A generic 2D data table — row-major, where each row is an array of column values.\r\nReused across the API for any tabular (X, Y, …) data such as restraint\r\nvariable-stiffness curves, derived force-vs-deflection views, material curves, etc.\r\nSchema (column names, types, units, bounds) is returned by the resource's dedicated\r\ntable-metadata endpoint and is not embedded here."
                }
              }
            }
          },
          "400": {
            "description": "Validation failure or restraintCode position is not 'V'",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "No restraint row exists for the node",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Node Restraints"
        ],
        "summary": "Clear Restraint Table Data",
        "description": "Clears the variable-stiffness table for one DOF on a node restraint\r\n(writes Count = 0 — the binary field stays allocated but holds no points).",
        "parameters": [
          {
            "name": "nodeId",
            "in": "path",
            "description": "The node Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "direction",
            "in": "path",
            "description": "The DOF (Tx, Ty, Tz, Rx, Ry, Rz)",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/StiffnessDirection"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Table cleared"
          },
          "404": {
            "description": "No restraint row exists for the node, or the table was already empty",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/node-restraints/metadata": {
      "get": {
        "tags": [
          "Node Restraints"
        ],
        "summary": "Get Metadata",
        "description": "Returns the schema for the resource: field definitions, units resolved against current\r\njob units, and allowed values for enum fields.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/node-restraints/table/{direction}/metadata": {
      "get": {
        "tags": [
          "Node Restraints"
        ],
        "summary": "Get Restraint Table Metadata",
        "description": "Returns the schema for a variable-stiffness table on the given DOF — title, axis labels\r\nand units (resolved against current job units), per-axis bounds, and the maximum number\r\nof points the table accepts.\r\n            \r\nMetadata is the same for any restraint of a given direction; it does not depend on a\r\nspecific node Id and is therefore not part of `{nodeId:int}/table/...`.",
        "parameters": [
          {
            "name": "direction",
            "in": "path",
            "description": "The DOF (Tx, Ty, Tz, Rx, Ry, Rz)",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/StiffnessDirection"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns table metadata",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TableMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/node-restraints/bulk": {
      "post": {
        "tags": [
          "Node Restraints"
        ],
        "summary": "Create Node Restraints (bulk)",
        "description": "Creates multiple restraint rows in a single request. Each item must include its\r\nparent `node` Id. Per-item 409 is reported as a bulk error if a restraint\r\nalready exists for the supplied node. Variable-stiffness tables can be supplied\r\ninline on each item.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "If true, continue processing remaining items after a failure. Default: false.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of restraint create DTOs",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeRestraintCreate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeRestraintCreate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeRestraintCreate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns bulk result (check errors array for partial failures)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NodeRestraintBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "If the request body is missing or malformed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Node Restraints"
        ],
        "summary": "Update Node Restraints (bulk)",
        "description": "Partially updates multiple restraints in a single request. Each item must include\r\nits parent `node` Id. Per-item 404 is reported as a bulk error if no row exists\r\nfor the supplied node. Only provided fields are changed; omitted fields keep their\r\ncurrent value.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "If true, continue processing remaining items after a failure. Default: false.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of partial update DTOs, each including its parent node Id",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeRestraintUpdate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeRestraintUpdate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeRestraintUpdate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns bulk result (check errors array for partial failures)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NodeRestraintBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "If the request body is missing or malformed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Node Restraints"
        ],
        "summary": "Delete Bulk",
        "description": "Deletes multiple attribute rows by parent Id. The body is a JSON array of integer parent Ids.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/node-restraints/set-general": {
      "post": {
        "tags": [
          "Node Restraints"
        ],
        "summary": "Set General Restraint",
        "description": "Promotes a single node as the general restraint and atomically demotes every other row.\r\nPass `node = N` to set node N as the general restraint;\r\npass `node = null` to clear the flag from every node so no general restraint is set.\r\n            \r\nAt most one node can be the general restraint at any time. The target node must already\r\nhave a restraint row — use `POST /node-restraints` to create one first.\r\n            \r\nTo observe which node (if any) is currently the general restraint, read\r\n`generalRestraint` on the node restraint DTO via `GET /node-restraints` or\r\n`GET /node-restraints/{nodeId}`.",
        "requestBody": {
          "description": "Request body. `node` is the node to promote, or null to clear.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetGeneralRestraintRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SetGeneralRestraintRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SetGeneralRestraintRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the promoted restraint, or null when clearing.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NodeRestraint"
                }
              }
            }
          },
          "400": {
            "description": "Request body missing or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Node not found, or node has no restraint row.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/nodes": {
      "get": {
        "tags": [
          "Nodes"
        ],
        "summary": "Get All",
        "description": "Gets all items with optional filtering, pagination and sub-resource expansion.\r\nResults are always sorted by Id ascending.\r\nPagination metadata is returned in response headers (Total-Count, Offset, Limit).\r\n`Expand` defaults to `none` on list endpoints so payloads stay lean;\r\npass `Expand=all` to hydrate sub-resources. Sub-resource expansion is\r\nopt-in per resource type — resources that don't define sub-resources ignore the parameter.",
        "parameters": [
          {
            "name": "NodeType",
            "in": "query",
            "description": "Filter by node type (e.g., Restrained). Default is All_Types.",
            "schema": {
              "$ref": "#/components/schemas/NodeTypeFilter"
            }
          },
          {
            "name": "MinX",
            "in": "query",
            "description": "Minimum X coordinate filter. Unit: Length (see GET /job/units).",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "MaxX",
            "in": "query",
            "description": "Maximum X coordinate filter. Unit: Length (see GET /job/units).",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "MinY",
            "in": "query",
            "description": "Minimum Y coordinate filter. Unit: Length (see GET /job/units).",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "MaxY",
            "in": "query",
            "description": "Maximum Y coordinate filter. Unit: Length (see GET /job/units).",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "MinZ",
            "in": "query",
            "description": "Minimum Z coordinate filter. Unit: Length (see GET /job/units).",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "MaxZ",
            "in": "query",
            "description": "Maximum Z coordinate filter. Unit: Length (see GET /job/units).",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "Nodes",
            "in": "query",
            "description": "Node Ids to filter by, in SG list format (e.g. `\"1,5-10,15\"`).\r\nOmit to return all nodes.",
            "schema": {
              "type": "string",
              "example": "1,5-10,15"
            },
            "example": "1,5-10,15"
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Expand",
            "in": "query",
            "description": "Sub-resource expansion. Defaults to `none`; pass `all` to hydrate sub-resources.",
            "schema": {
              "$ref": "#/components/schemas/ExpandOption"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Node"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Nodes"
        ],
        "summary": "Create",
        "description": "Creates a new item. If a validator is registered, the item is validated before creation.",
        "requestBody": {
          "description": "The data for the new item",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NodeCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/NodeCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/NodeCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Node"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/nodes/{id}": {
      "get": {
        "tags": [
          "Nodes"
        ],
        "summary": "Get by Id",
        "description": "`Expand` defaults to `all` on the single-item endpoint; pass `Expand=none`\r\n            to suppress sub-resource hydration. Sub-resource expansion is opt-in per resource type —\r\n            resources that don't define sub-resources ignore the parameter.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Expand",
            "in": "query",
            "description": "Sub-resource expansion. Defaults to `all`; pass `none` to suppress sub-resource hydration.",
            "schema": {
              "$ref": "#/components/schemas/ExpandOption"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Node"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Nodes"
        ],
        "summary": "Update",
        "description": "Updates an existing item. If a validator is registered, the update is validated first.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The partial update data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NodeUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/NodeUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/NodeUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Node"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Nodes"
        ],
        "summary": "Delete",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/nodes/exists": {
      "get": {
        "tags": [
          "Nodes"
        ],
        "summary": "Get by Location",
        "description": "Checks if a node exists within a given tolerance of the specified coordinates.\r\nReturns the first matching node found within the Euclidean distance tolerance.",
        "parameters": [
          {
            "name": "x",
            "in": "query",
            "description": "X coordinate to search near",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "y",
            "in": "query",
            "description": "Y coordinate to search near",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "z",
            "in": "query",
            "description": "Z coordinate to search near",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "tolerance",
            "in": "query",
            "description": "Maximum Euclidean distance to consider a match",
            "schema": {
              "type": "number",
              "format": "double"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the matching node",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Node"
                }
              }
            }
          },
          "400": {
            "description": "If tolerance is negative",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "No node exists within the specified tolerance",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/nodes/metadata": {
      "get": {
        "tags": [
          "Nodes"
        ],
        "summary": "Get Metadata",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/nodes/next": {
      "get": {
        "tags": [
          "Nodes"
        ],
        "summary": "Next Id",
        "description": "Gets the next available (unused) Id for this entity type.",
        "parameters": [
          {
            "name": "start",
            "in": "query",
            "description": "The Id value to start searching from (inclusive). Defaults to 1.",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/nodes/bulk": {
      "post": {
        "tags": [
          "Nodes"
        ],
        "summary": "Create Bulk",
        "description": "Creates multiple items in a bulk operation.\r\nIf a validator is registered, all items are validated upfront before any are created.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of items to create",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeCreate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeCreate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeCreate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NodeBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Nodes"
        ],
        "summary": "Update Bulk",
        "description": "Updates multiple items in a bulk operation.\r\nEach item must include its Id in the request body.\r\nIf a validator is registered, all items are validated upfront before any are updated.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of update objects (each must include Id)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeUpdate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeUpdate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NodeUpdate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NodeBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Nodes"
        ],
        "summary": "Delete Bulk",
        "description": "Deletes multiple entities by Id. The body is a JSON array of integer Ids\r\n(e.g. `[1, 5, 10]`) — consistent with every other bulk-delete endpoint\r\nin the API (see CLAUDE.md \"Query Parameter Conventions\").",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue on error",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "JSON array of entity Ids to delete",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/plate-cuts": {
      "get": {
        "tags": [
          "Plate Cuts"
        ],
        "summary": "Get All",
        "description": "Gets all items with optional filtering, pagination and sub-resource expansion.\r\nResults are always sorted by Id ascending.\r\nPagination metadata is returned in response headers (Total-Count, Offset, Limit).\r\n`Expand` defaults to `none` on list endpoints so payloads stay lean;\r\npass `Expand=all` to hydrate sub-resources. Sub-resource expansion is\r\nopt-in per resource type — resources that don't define sub-resources ignore the parameter.",
        "parameters": [
          {
            "name": "Cuts",
            "in": "query",
            "description": "Cut Ids to filter by, in SG list format (e.g. `\"1,3-7,10\"`).\r\nOmit to return all cuts.",
            "schema": {
              "type": "string",
              "example": "1,3-7,10"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Expand",
            "in": "query",
            "description": "Sub-resource expansion. Defaults to `none`; pass `all` to hydrate sub-resources.",
            "schema": {
              "$ref": "#/components/schemas/ExpandOption"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PlateCut"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Plate Cuts"
        ],
        "summary": "Create",
        "description": "Creates a new item. If a validator is registered, the item is validated before creation.",
        "requestBody": {
          "description": "The data for the new item",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PlateCutCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PlateCutCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PlateCutCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlateCut"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/plate-cuts/{id}": {
      "get": {
        "tags": [
          "Plate Cuts"
        ],
        "summary": "Get by Id",
        "description": "`Expand` defaults to `all` on the single-item endpoint; pass `Expand=none`\r\n            to suppress sub-resource hydration. Sub-resource expansion is opt-in per resource type —\r\n            resources that don't define sub-resources ignore the parameter.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Expand",
            "in": "query",
            "description": "Sub-resource expansion. Defaults to `all`; pass `none` to suppress sub-resource hydration.",
            "schema": {
              "$ref": "#/components/schemas/ExpandOption"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlateCut"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Plate Cuts"
        ],
        "summary": "Update",
        "description": "Updates an existing item. If a validator is registered, the update is validated first.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The partial update data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PlateCutUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PlateCutUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PlateCutUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlateCut"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Plate Cuts"
        ],
        "summary": "Delete",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/plate-cuts/metadata": {
      "get": {
        "tags": [
          "Plate Cuts"
        ],
        "summary": "Get Metadata",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/plate-cuts/next": {
      "get": {
        "tags": [
          "Plate Cuts"
        ],
        "summary": "Next Id",
        "description": "Gets the next available (unused) Id for this entity type.",
        "parameters": [
          {
            "name": "start",
            "in": "query",
            "description": "The Id value to start searching from (inclusive). Defaults to 1.",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/plate-cuts/bulk": {
      "post": {
        "tags": [
          "Plate Cuts"
        ],
        "summary": "Create Bulk",
        "description": "Creates multiple items in a bulk operation.\r\nIf a validator is registered, all items are validated upfront before any are created.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of items to create",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlateCutCreate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlateCutCreate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlateCutCreate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlateCutBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Plate Cuts"
        ],
        "summary": "Update Bulk",
        "description": "Updates multiple items in a bulk operation.\r\nEach item must include its Id in the request body.\r\nIf a validator is registered, all items are validated upfront before any are updated.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of update objects (each must include Id)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlateCutUpdate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlateCutUpdate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlateCutUpdate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlateCutBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Plate Cuts"
        ],
        "summary": "Delete Bulk",
        "description": "Deletes multiple entities by Id. The body is a JSON array of integer Ids\r\n(e.g. `[1, 5, 10]`) — consistent with every other bulk-delete endpoint\r\nin the API (see CLAUDE.md \"Query Parameter Conventions\").",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue on error",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "JSON array of entity Ids to delete",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/plate-pressure-loads": {
      "get": {
        "tags": [
          "Plate Pressure Loads"
        ],
        "summary": "Get All",
        "description": "Gets all loads with optional filtering and pagination.\r\nUse the `cases` query parameter to filter by load cases — accepts SG list format\r\n(e.g. `\"1,3-7,10\"`). Omit any list filter to match all.\r\nReturns an empty array when no loads match the filter — never 404.\r\nResults are sorted by Case ascending, then by entity Id ascending.\r\nPagination metadata is returned in response headers (Total-Count, Offset, Limit).",
        "parameters": [
          {
            "name": "Plates",
            "in": "query",
            "description": "Plate Ids to filter by, in SG list format (e.g. `\"1,3-7,10\"`).\r\nReturns only pressure loads applied to the specified plates.\r\nOmit to return pressure loads for all plates.",
            "schema": {
              "type": "string",
              "example": "1,3-7,10"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "Cases",
            "in": "query",
            "description": "Load cases to filter by, in SG list format (e.g. `\"1,3-7,10\"`).\r\nReturns only loads belonging to the specified cases.\r\nOmit to return loads for all cases.",
            "schema": {
              "type": "string",
              "example": "1,3-7,10"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "LoadCategory",
            "in": "query",
            "description": "Filter by load category number.\r\nReturns only loads assigned to the specified category.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PlatePressureLoad"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Plate Pressure Loads"
        ],
        "summary": "Create",
        "description": "Creates a new load. The load case must exist and be a Primary load case.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PlatePressureLoadCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PlatePressureLoadCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PlatePressureLoadCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/plate-pressure-loads/{caseId}/{plateId}": {
      "get": {
        "tags": [
          "Plate Pressure Loads"
        ],
        "summary": "Get Plate Pressure Load",
        "description": "Gets a specific plate pressure load by its composite Id (case + plate).",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "plateId",
            "in": "path",
            "description": "The plate number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the plate pressure load",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlatePressureLoad"
                }
              }
            }
          },
          "404": {
            "description": "Plate pressure load not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Plate Pressure Loads"
        ],
        "summary": "Update Plate Pressure Load",
        "description": "Updates an existing plate pressure load. Only provided fields are updated.\r\nThe load case must be a Primary load case.",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "plateId",
            "in": "path",
            "description": "The plate number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The update data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PlatePressureLoadUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PlatePressureLoadUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PlatePressureLoadUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the updated plate pressure load",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlatePressureLoad"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed or load case is not Primary",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Plate pressure load not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Plate Pressure Loads"
        ],
        "summary": "Delete Plate Pressure Load",
        "description": "Deletes a specific plate pressure load by its composite Id (case + plate).",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "plateId",
            "in": "path",
            "description": "The plate number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Plate pressure load deleted successfully"
          },
          "404": {
            "description": "Plate pressure load not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/plate-pressure-loads/metadata": {
      "get": {
        "tags": [
          "Plate Pressure Loads"
        ],
        "summary": "Get Metadata",
        "description": "Returns schema metadata for this load entity type: field definitions, count, and key structure.\r\nField definitions include names, data types, units, and allowed value ranges.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/plate-pressure-loads/bulk": {
      "post": {
        "tags": [
          "Plate Pressure Loads"
        ],
        "summary": "Create Bulk",
        "description": "Creates multiple loads in a bulk operation.\r\nAll load cases referenced must exist and be Primary load cases.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of loads to create",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlatePressureLoadCreate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlatePressureLoadCreate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlatePressureLoadCreate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Plate Pressure Loads"
        ],
        "summary": "Update Bulk",
        "description": "Updates multiple plate pressure loads. Each item must include case and plate in the body.\r\nAll load cases referenced must be Primary.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of update objects (each must include case and plate)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlatePressureLoadUpdate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlatePressureLoadUpdate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlatePressureLoadUpdate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlatePressureLoadBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Plate Pressure Loads"
        ],
        "summary": "Delete Bulk",
        "description": "Deletes multiple plate pressure loads. Both case and plate are required for each entry —\r\nproviding only a case does not delete all pressure loads for that case.\r\nThe succeeded array echoes back the Ids of each successfully deleted load.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue on error",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of composite Id objects (case + plate, both required)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlatePressureLoadKey"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlatePressureLoadKey"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlatePressureLoadKey"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlatePressureLoadKeyBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/plate-strips": {
      "get": {
        "tags": [
          "Plate Strips"
        ],
        "summary": "Get All",
        "description": "Gets all items with optional filtering, pagination and sub-resource expansion.\r\nResults are always sorted by Id ascending.\r\nPagination metadata is returned in response headers (Total-Count, Offset, Limit).\r\n`Expand` defaults to `none` on list endpoints so payloads stay lean;\r\npass `Expand=all` to hydrate sub-resources. Sub-resource expansion is\r\nopt-in per resource type — resources that don't define sub-resources ignore the parameter.",
        "parameters": [
          {
            "name": "Strips",
            "in": "query",
            "description": "Strip Ids to filter by, in SG list format (e.g. `\"1,3-7,10\"`).\r\nOmit to return all strips.",
            "schema": {
              "type": "string",
              "example": "1,3-7,10"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Expand",
            "in": "query",
            "description": "Sub-resource expansion. Defaults to `none`; pass `all` to hydrate sub-resources.",
            "schema": {
              "$ref": "#/components/schemas/ExpandOption"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PlateStrip"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Plate Strips"
        ],
        "summary": "Create",
        "description": "Creates a new item. If a validator is registered, the item is validated before creation.",
        "requestBody": {
          "description": "The data for the new item",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PlateStripCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PlateStripCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PlateStripCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlateStrip"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/plate-strips/{id}": {
      "get": {
        "tags": [
          "Plate Strips"
        ],
        "summary": "Get by Id",
        "description": "`Expand` defaults to `all` on the single-item endpoint; pass `Expand=none`\r\n            to suppress sub-resource hydration. Sub-resource expansion is opt-in per resource type —\r\n            resources that don't define sub-resources ignore the parameter.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Expand",
            "in": "query",
            "description": "Sub-resource expansion. Defaults to `all`; pass `none` to suppress sub-resource hydration.",
            "schema": {
              "$ref": "#/components/schemas/ExpandOption"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlateStrip"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Plate Strips"
        ],
        "summary": "Update",
        "description": "Updates an existing item. If a validator is registered, the update is validated first.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The partial update data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PlateStripUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PlateStripUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PlateStripUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlateStrip"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Plate Strips"
        ],
        "summary": "Delete",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/plate-strips/metadata": {
      "get": {
        "tags": [
          "Plate Strips"
        ],
        "summary": "Get Metadata",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/plate-strips/next": {
      "get": {
        "tags": [
          "Plate Strips"
        ],
        "summary": "Next Id",
        "description": "Gets the next available (unused) Id for this entity type.",
        "parameters": [
          {
            "name": "start",
            "in": "query",
            "description": "The Id value to start searching from (inclusive). Defaults to 1.",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/plate-strips/bulk": {
      "post": {
        "tags": [
          "Plate Strips"
        ],
        "summary": "Create Bulk",
        "description": "Creates multiple items in a bulk operation.\r\nIf a validator is registered, all items are validated upfront before any are created.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of items to create",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlateStripCreate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlateStripCreate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlateStripCreate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlateStripBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Plate Strips"
        ],
        "summary": "Update Bulk",
        "description": "Updates multiple items in a bulk operation.\r\nEach item must include its Id in the request body.\r\nIf a validator is registered, all items are validated upfront before any are updated.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of update objects (each must include Id)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlateStripUpdate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlateStripUpdate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlateStripUpdate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlateStripBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Plate Strips"
        ],
        "summary": "Delete Bulk",
        "description": "Deletes multiple entities by Id. The body is a JSON array of integer Ids\r\n(e.g. `[1, 5, 10]`) — consistent with every other bulk-delete endpoint\r\nin the API (see CLAUDE.md \"Query Parameter Conventions\").",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue on error",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "JSON array of entity Ids to delete",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/plates": {
      "get": {
        "tags": [
          "Plates"
        ],
        "summary": "Get All",
        "description": "Gets all items with optional filtering, pagination and sub-resource expansion.\r\nResults are always sorted by Id ascending.\r\nPagination metadata is returned in response headers (Total-Count, Offset, Limit).\r\n`Expand` defaults to `none` on list endpoints so payloads stay lean;\r\npass `Expand=all` to hydrate sub-resources. Sub-resource expansion is\r\nopt-in per resource type — resources that don't define sub-resources ignore the parameter.",
        "parameters": [
          {
            "name": "Plates",
            "in": "query",
            "description": "Plate Ids to filter by, in SG list format (e.g. `\"1,3-7,10\"`).\r\nOmit to return all plates.",
            "schema": {
              "type": "string",
              "example": "1,3-7,10"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "Theory",
            "in": "query",
            "description": "Filter by plate theory (Kirchoff or Mindlin).",
            "schema": {
              "$ref": "#/components/schemas/PlateTheory"
            }
          },
          {
            "name": "Material",
            "in": "query",
            "description": "Filter by material number.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Expand",
            "in": "query",
            "description": "Sub-resource expansion. Defaults to `none`; pass `all` to hydrate sub-resources.",
            "schema": {
              "$ref": "#/components/schemas/ExpandOption"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Plate"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Plates"
        ],
        "summary": "Create",
        "description": "Creates a new item. If a validator is registered, the item is validated before creation.",
        "requestBody": {
          "description": "The data for the new item",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PlateCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PlateCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PlateCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Plate"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/plates/{id}": {
      "get": {
        "tags": [
          "Plates"
        ],
        "summary": "Get by Id",
        "description": "`Expand` defaults to `all` on the single-item endpoint; pass `Expand=none`\r\n            to suppress sub-resource hydration. Sub-resource expansion is opt-in per resource type —\r\n            resources that don't define sub-resources ignore the parameter.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Expand",
            "in": "query",
            "description": "Sub-resource expansion. Defaults to `all`; pass `none` to suppress sub-resource hydration.",
            "schema": {
              "$ref": "#/components/schemas/ExpandOption"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Plate"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Plates"
        ],
        "summary": "Update",
        "description": "Updates an existing item. If a validator is registered, the update is validated first.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The partial update data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PlateUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PlateUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PlateUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Plate"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Plates"
        ],
        "summary": "Delete",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/plates/{id}/direction": {
      "get": {
        "tags": [
          "Plates"
        ],
        "summary": "Get Direction",
        "description": "Gets the direction for a specific plate.\r\nReturns the active source (Angle, Node, or Axis) and all three underlying field values.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The plate Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the plate direction",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlateDirection"
                }
              }
            }
          },
          "401": {
            "description": "If the API key is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Plate not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Plates"
        ],
        "summary": "Set Direction",
        "description": "Sets the direction for a specific plate. Exactly one of `dirAngle`,\r\n`dirNode`, or `dirAxis` must be supplied — the underlying datasheet row\r\nenforces mutual exclusion, so the supplied field is written and SG's per-field\r\nhelper zeros the other two for the row.\r\nA missing or empty body is rejected with 400 (PUT expects a meaningful payload).\r\n            \r\nUses PUT because today every write replaces the full direction state (the mutex\r\ninvariant zeros the other two fields). When SG stores a discriminator on the\r\nrow, a sibling PATCH endpoint will be added that supports true single-field\r\npartial updates without touching the others.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The plate Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The direction to set — exactly one of `dirAngle`, `dirNode`, or `dirAxis` must be supplied",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DirectionUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/DirectionUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/DirectionUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Direction updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlateDirection"
                }
              }
            }
          },
          "400": {
            "description": "Invalid direction data — missing or empty body, multiple value fields supplied, or a non-existent direction node",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "If the API key is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Plate not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/plates/direction/metadata": {
      "get": {
        "tags": [
          "Plates"
        ],
        "summary": "Get Direction Metadata",
        "description": "Returns the schema for the plate-direction sub-resource: field definitions,\r\nunits resolved against current job units, and allowed values for enum fields.\r\nFields mirror the shape of the `direction` object on plate responses.",
        "responses": {
          "200": {
            "description": "Returns direction schema metadata",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "401": {
            "description": "If the API key is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/plates/metadata": {
      "get": {
        "tags": [
          "Plates"
        ],
        "summary": "Get Metadata",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/plates/next": {
      "get": {
        "tags": [
          "Plates"
        ],
        "summary": "Next Id",
        "description": "Gets the next available (unused) Id for this entity type.",
        "parameters": [
          {
            "name": "start",
            "in": "query",
            "description": "The Id value to start searching from (inclusive). Defaults to 1.",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/plates/bulk": {
      "post": {
        "tags": [
          "Plates"
        ],
        "summary": "Create Bulk",
        "description": "Creates multiple items in a bulk operation.\r\nIf a validator is registered, all items are validated upfront before any are created.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of items to create",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlateCreate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlateCreate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlateCreate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlateBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Plates"
        ],
        "summary": "Update Bulk",
        "description": "Updates multiple items in a bulk operation.\r\nEach item must include its Id in the request body.\r\nIf a validator is registered, all items are validated upfront before any are updated.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of update objects (each must include Id)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlateUpdate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlateUpdate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PlateUpdate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlateBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Plates"
        ],
        "summary": "Delete Bulk",
        "description": "Deletes multiple entities by Id. The body is a JSON array of integer Ids\r\n(e.g. `[1, 5, 10]`) — consistent with every other bulk-delete endpoint\r\nin the API (see CLAUDE.md \"Query Parameter Conventions\").",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue on error",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "JSON array of entity Ids to delete",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/sections": {
      "get": {
        "tags": [
          "Sections"
        ],
        "summary": "Get All",
        "description": "Gets all items with optional filtering, pagination and sub-resource expansion.\r\nResults are always sorted by Id ascending.\r\nPagination metadata is returned in response headers (Total-Count, Offset, Limit).\r\n`Expand` defaults to `none` on list endpoints so payloads stay lean;\r\npass `Expand=all` to hydrate sub-resources. Sub-resource expansion is\r\nopt-in per resource type — resources that don't define sub-resources ignore the parameter.",
        "parameters": [
          {
            "name": "Sections",
            "in": "query",
            "description": "Section Ids to filter by, in SG list format (e.g. `\"1,3-7,10\"`).\r\nOmit to return all sections.",
            "schema": {
              "type": "string",
              "example": "1,3-7,10"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Expand",
            "in": "query",
            "description": "Sub-resource expansion. Defaults to `none`; pass `all` to hydrate sub-resources.",
            "schema": {
              "$ref": "#/components/schemas/ExpandOption"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Section"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Sections"
        ],
        "summary": "Create",
        "description": "Creates a new item. If a validator is registered, the item is validated before creation.",
        "requestBody": {
          "description": "The data for the new item",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SectionUserCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SectionUserCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SectionUserCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Section"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/sections/{id}": {
      "get": {
        "tags": [
          "Sections"
        ],
        "summary": "Get by Id",
        "description": "`Expand` defaults to `all` on the single-item endpoint; pass `Expand=none`\r\n            to suppress sub-resource hydration. Sub-resource expansion is opt-in per resource type —\r\n            resources that don't define sub-resources ignore the parameter.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Expand",
            "in": "query",
            "description": "Sub-resource expansion. Defaults to `all`; pass `none` to suppress sub-resource hydration.",
            "schema": {
              "$ref": "#/components/schemas/ExpandOption"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Section"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Sections"
        ],
        "summary": "Update",
        "description": "Updates an existing item. If a validator is registered, the update is validated first.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The partial update data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SectionUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SectionUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SectionUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Section"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Sections"
        ],
        "summary": "Delete",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The entity Id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/sections/metadata": {
      "get": {
        "tags": [
          "Sections"
        ],
        "summary": "Get Metadata",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/sections/next": {
      "get": {
        "tags": [
          "Sections"
        ],
        "summary": "Next Id",
        "description": "Gets the next available (unused) Id for this entity type.",
        "parameters": [
          {
            "name": "start",
            "in": "query",
            "description": "The Id value to start searching from (inclusive). Defaults to 1.",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/sections/bulk": {
      "post": {
        "tags": [
          "Sections"
        ],
        "summary": "Create Bulk",
        "description": "Creates multiple items in a bulk operation.\r\nIf a validator is registered, all items are validated upfront before any are created.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of items to create",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/SectionUserCreate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/SectionUserCreate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/SectionUserCreate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SectionBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Sections"
        ],
        "summary": "Update Bulk",
        "description": "Updates multiple items in a bulk operation.\r\nEach item must include its Id in the request body.\r\nIf a validator is registered, all items are validated upfront before any are updated.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of update objects (each must include Id)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/SectionUpdate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/SectionUpdate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/SectionUpdate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SectionBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Sections"
        ],
        "summary": "Delete Bulk",
        "description": "Deletes multiple entities by Id. The body is a JSON array of integer Ids\r\n(e.g. `[1, 5, 10]`) — consistent with every other bulk-delete endpoint\r\nin the API (see CLAUDE.md \"Query Parameter Conventions\").",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue on error",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "JSON array of entity Ids to delete",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/sections/library": {
      "post": {
        "tags": [
          "Sections"
        ],
        "summary": "Create Library Section",
        "description": "Creates a section by looking it up in a SPACE GASS section library. All structural\r\nproperties (A, J, Iy, Iz, etc.) and cross-section shape data are populated from the\r\nlibrary — the caller provides only the section name and library.",
        "requestBody": {
          "description": "The library section to create",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SectionLibraryCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SectionLibraryCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SectionLibraryCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Section created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Section"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request, or the specified section does not exist in the given library",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "A section with the specified Id already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/sections/library/bulk": {
      "post": {
        "tags": [
          "Sections"
        ],
        "summary": "Create Library Sections Bulk",
        "description": "Creates multiple library-sourced sections in a single request. Each section is\r\nresolved from the SPACE GASS section library by (name, library).",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of library sections to create",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/SectionLibraryCreate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/SectionLibraryCreate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/SectionLibraryCreate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Bulk operation completed (check succeeded/errors arrays)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SectionBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or validation failure",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/structure/sections/{id}/library": {
      "put": {
        "tags": [
          "Sections"
        ],
        "summary": "Replace With Library Section",
        "description": "Replaces the section at the given Id with a library-sourced section. The existing row\r\nis deleted and a new row is created at the same Id, resolved from the SPACE GASS\r\nsection library by (name, library). Use this to convert a User section to a Library\r\nsection, or to re-resolve an existing Library section against a different library\r\nentry. Any `id` in the request body is ignored — the route Id wins.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The Id of the section to replace",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The library section to put in its place",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SectionLibraryCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SectionLibraryCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SectionLibraryCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Section replaced",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Section"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request, or the specified section does not exist in the given library",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "No section exists at the given Id",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/self-weight-loads": {
      "get": {
        "tags": [
          "Self Weight Loads"
        ],
        "summary": "Get All",
        "description": "Gets all loads with optional filtering and pagination.\r\nUse the `cases` query parameter to filter by load cases — accepts SG list format\r\n(e.g. `\"1,3-7,10\"`). Omit any list filter to match all.\r\nReturns an empty array when no loads match the filter — never 404.\r\nResults are sorted by Case ascending, then by entity Id ascending.\r\nPagination metadata is returned in response headers (Total-Count, Offset, Limit).",
        "parameters": [
          {
            "name": "Cases",
            "in": "query",
            "description": "Load cases to filter by, in SG list format (e.g. `\"1,3-7,10\"`).\r\nReturns only loads belonging to the specified cases.\r\nOmit to return loads for all cases.",
            "schema": {
              "type": "string",
              "example": "1,3-7,10"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "LoadCategory",
            "in": "query",
            "description": "Filter by load category number.\r\nReturns only loads assigned to the specified category.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SelfWeightLoad"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Self Weight Loads"
        ],
        "summary": "Create",
        "description": "Creates a new load. The load case must exist and be a Primary load case.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SelfWeightLoadCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SelfWeightLoadCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SelfWeightLoadCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/self-weight-loads/{caseId}": {
      "get": {
        "tags": [
          "Self Weight Loads"
        ],
        "summary": "Get Self Weight Load",
        "description": "Gets the self-weight load for a specific load case.\r\nReturns 404 if no self-weight load exists for that case.",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the self-weight load",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SelfWeightLoad"
                }
              }
            }
          },
          "404": {
            "description": "Self-weight load not found for this case",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Self Weight Loads"
        ],
        "summary": "Update Self Weight Load",
        "description": "Updates an existing self-weight load. Only provided fields are updated.",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The update data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SelfWeightLoadUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SelfWeightLoadUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SelfWeightLoadUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the updated self-weight load",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SelfWeightLoad"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Self-weight load not found for this case",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Self Weight Loads"
        ],
        "summary": "Delete Self Weight Load",
        "description": "Deletes the self-weight load for a specific load case.",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Self-weight load deleted successfully"
          },
          "404": {
            "description": "Self-weight load not found for this case",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/self-weight-loads/metadata": {
      "get": {
        "tags": [
          "Self Weight Loads"
        ],
        "summary": "Get Metadata",
        "description": "Returns schema metadata for this load entity type: field definitions, count, and key structure.\r\nField definitions include names, data types, units, and allowed value ranges.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/self-weight-loads/bulk": {
      "post": {
        "tags": [
          "Self Weight Loads"
        ],
        "summary": "Create Bulk",
        "description": "Creates multiple loads in a bulk operation.\r\nAll load cases referenced must exist and be Primary load cases.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of loads to create",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/SelfWeightLoadCreate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/SelfWeightLoadCreate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/SelfWeightLoadCreate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/service/info": {
      "get": {
        "tags": [
          "Service"
        ],
        "summary": "Get Service Info",
        "description": "Returns the API base URL and the SPACE GASS version number.",
        "responses": {
          "200": {
            "description": "Returns service information",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServiceInfo"
                }
              }
            }
          }
        }
      }
    },
    "/job/settings": {
      "get": {
        "tags": [
          "Settings"
        ],
        "summary": "Get Settings",
        "description": "Gets job-level settings (vertical axis, etc.) for the current job.\r\nThese properties apply to the job as a whole.",
        "responses": {
          "200": {
            "description": "Returns the settings",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobSettings"
                }
              }
            }
          },
          "404": {
            "description": "No job found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/settings/metadata": {
      "get": {
        "tags": [
          "Settings"
        ],
        "summary": "Get Settings Metadata",
        "description": "Returns the schema for `GET /job/settings` — field definitions with\r\n`allowedValues` for enum-backed fields (e.g. `verticalAxis`).",
        "responses": {
          "200": {
            "description": "Returns the settings schema",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/": {
      "get": {
        "tags": [
          "Space Gass API"
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/analysis/static/member-end-forces": {
      "get": {
        "tags": [
          "Static Results"
        ],
        "summary": "List Member End Forces",
        "description": "Gets end force results for members, grouped by load case and member.\r\nEach result contains force values at the start and end nodes.",
        "parameters": [
          {
            "name": "cases",
            "in": "query",
            "description": "Load case Ids in SG list format (e.g. `\"1,3-7,10\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "members",
            "in": "query",
            "description": "Member Ids in SG list format (e.g. `\"1,3-7,10\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the member end force results.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberEndForceQueryResult"
                }
              }
            }
          },
          "400": {
            "description": "Filter is malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/analysis/static/member-end-forces/metadata": {
      "get": {
        "tags": [
          "Static Results"
        ],
        "summary": "Get Member End Forces Metadata",
        "description": "Returns the field schema for `GET member-end-forces` — units resolved against current job units.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/analysis/static/member-intermediate-displacements": {
      "get": {
        "tags": [
          "Static Results"
        ],
        "summary": "List Member Intermediate Displacements",
        "description": "Gets intermediate displacement results for members, grouped by load case and member.\r\nEach result contains global and local displacement values at stations along the member.",
        "parameters": [
          {
            "name": "cases",
            "in": "query",
            "description": "Load case Ids in SG list format (e.g. `\"1,3-7,10\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "members",
            "in": "query",
            "description": "Member Ids in SG list format (e.g. `\"1,3-7,10\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the member intermediate displacement results.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberIntermediateDisplacementQueryResult"
                }
              }
            }
          },
          "400": {
            "description": "Filter is malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/analysis/static/member-intermediate-displacements/metadata": {
      "get": {
        "tags": [
          "Static Results"
        ],
        "summary": "Get Member Intermediate Displacements Metadata",
        "description": "Returns the field schema for `GET member-intermediate-displacements` — units resolved against current job units.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/analysis/static/member-intermediate-forces": {
      "get": {
        "tags": [
          "Static Results"
        ],
        "summary": "List Member Intermediate Forces",
        "description": "Gets intermediate force results for members, grouped by load case and member.\r\nEach result contains force values at stations along the member.",
        "parameters": [
          {
            "name": "cases",
            "in": "query",
            "description": "Load case Ids in SG list format (e.g. `\"1,3-7,10\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "members",
            "in": "query",
            "description": "Member Ids in SG list format (e.g. `\"1,3-7,10\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the member intermediate force results.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberIntermediateForceQueryResult"
                }
              }
            }
          },
          "400": {
            "description": "Filter is malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/analysis/static/member-intermediate-forces/metadata": {
      "get": {
        "tags": [
          "Static Results"
        ],
        "summary": "Get Member Intermediate Forces Metadata",
        "description": "Returns the field schema for `GET member-intermediate-forces` — units resolved against current job units.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/analysis/static/member-stresses": {
      "get": {
        "tags": [
          "Static Results"
        ],
        "summary": "List Member Stresses",
        "description": "Gets stress results for members, grouped by load case and member.\r\nEach result contains stress values at stations along the member.",
        "parameters": [
          {
            "name": "cases",
            "in": "query",
            "description": "Load case Ids in SG list format (e.g. `\"1,3-7,10\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "members",
            "in": "query",
            "description": "Member Ids in SG list format (e.g. `\"1,3-7,10\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the member stress results.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberStressQueryResult"
                }
              }
            }
          },
          "400": {
            "description": "Filter is malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/analysis/static/member-stresses/metadata": {
      "get": {
        "tags": [
          "Static Results"
        ],
        "summary": "Get Member Stresses Metadata",
        "description": "Returns the field schema for `GET member-stresses` — units resolved against current job units.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/analysis/static/node-displacements": {
      "get": {
        "tags": [
          "Static Results"
        ],
        "summary": "List Node Displacements",
        "description": "Gets displacement results for nodes, optionally filtered by load cases and node Ids.",
        "parameters": [
          {
            "name": "cases",
            "in": "query",
            "description": "Load case Ids in SG list format (e.g. `\"1,3-7,10\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "nodes",
            "in": "query",
            "description": "Node Ids in SG list format (e.g. `\"1,5-10\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1,5-10"
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the node displacement results.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NodeDisplacementQueryResult"
                }
              }
            }
          },
          "400": {
            "description": "Filter is malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/analysis/static/node-displacements/metadata": {
      "get": {
        "tags": [
          "Static Results"
        ],
        "summary": "Get Node Displacements Metadata",
        "description": "Returns the field schema for `GET node-displacements` — units resolved against current job units.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/analysis/static/node-reactions": {
      "get": {
        "tags": [
          "Static Results"
        ],
        "summary": "List Node Reactions",
        "description": "Gets reaction results for nodes, optionally filtered by load cases and node Ids.",
        "parameters": [
          {
            "name": "cases",
            "in": "query",
            "description": "Load case Ids in SG list format (e.g. `\"1,3-7,10\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "nodes",
            "in": "query",
            "description": "Node Ids in SG list format (e.g. `\"1,5-10\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1,5-10"
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the node reaction results.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NodeReactionQueryResult"
                }
              }
            }
          },
          "400": {
            "description": "Filter is malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/analysis/static/node-reactions/metadata": {
      "get": {
        "tags": [
          "Static Results"
        ],
        "summary": "Get Node Reactions Metadata",
        "description": "Returns the field schema for `GET node-reactions` — units resolved against current job units.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/analysis/static/plate-element-forces": {
      "get": {
        "tags": [
          "Static Results"
        ],
        "summary": "List Plate Element Forces",
        "description": "Gets element force results for plates, optionally filtered by load cases and plate Ids.",
        "parameters": [
          {
            "name": "cases",
            "in": "query",
            "description": "Load case Ids in SG list format (e.g. `\"1,3-7,10\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "plates",
            "in": "query",
            "description": "Plate Ids in SG list format (e.g. `\"1,3-7,10\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the plate element force results.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlateElementForceQueryResult"
                }
              }
            }
          },
          "400": {
            "description": "Filter is malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/analysis/static/plate-element-forces/metadata": {
      "get": {
        "tags": [
          "Static Results"
        ],
        "summary": "Get Plate Element Forces Metadata",
        "description": "Returns the field schema for `GET plate-element-forces` — units resolved against current job units.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/analysis/static/plate-element-stresses": {
      "get": {
        "tags": [
          "Static Results"
        ],
        "summary": "List Plate Element Stresses",
        "description": "Gets element stress results for plates, optionally filtered by load cases and plate Ids.",
        "parameters": [
          {
            "name": "cases",
            "in": "query",
            "description": "Load case Ids in SG list format (e.g. `\"1,3-7,10\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "plates",
            "in": "query",
            "description": "Plate Ids in SG list format (e.g. `\"1,3-7,10\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the plate element stress results.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlateStressQueryResult"
                }
              }
            }
          },
          "400": {
            "description": "Filter is malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/analysis/static/plate-element-stresses/metadata": {
      "get": {
        "tags": [
          "Static Results"
        ],
        "summary": "Get Plate Element Stresses Metadata",
        "description": "Returns the field schema for `GET plate-element-stresses` — units resolved against current job units.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/analysis/static/plate-nodal-forces": {
      "get": {
        "tags": [
          "Static Results"
        ],
        "summary": "List Plate Nodal Forces",
        "description": "Gets nodal force results for plates, grouped by load case and plate.\r\nEach result contains force values at each node of the plate element.",
        "parameters": [
          {
            "name": "cases",
            "in": "query",
            "description": "Load case Ids in SG list format (e.g. `\"1,3-7,10\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "plates",
            "in": "query",
            "description": "Plate Ids in SG list format (e.g. `\"1,3-7,10\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the plate nodal force results.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlateNodalForceQueryResult"
                }
              }
            }
          },
          "400": {
            "description": "Filter is malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/analysis/static/plate-nodal-forces/metadata": {
      "get": {
        "tags": [
          "Static Results"
        ],
        "summary": "Get Plate Nodal Forces Metadata",
        "description": "Returns the field schema for `GET plate-nodal-forces` — units resolved against current job units.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/design/steel-member/check-summary": {
      "get": {
        "tags": [
          "Steel Design Results"
        ],
        "summary": "List Steel Member Check Summary",
        "description": "Gets steel member design check summary results, optionally filtered by member Ids.",
        "parameters": [
          {
            "name": "members",
            "in": "query",
            "description": "Member Ids in SG list format (e.g. `\"1,3-7,10\"`). Omit to return all.",
            "schema": {
              "type": "string"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the steel member design check summary results.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SteelCheckSummaryQueryResult"
                }
              }
            }
          },
          "400": {
            "description": "Filter is malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/query/design/steel-member/check-summary/metadata": {
      "get": {
        "tags": [
          "Steel Design Results"
        ],
        "summary": "Get Steel Check Summary Metadata",
        "description": "Returns the field schema for `GET steel-member/check-summary` — units resolved against current job units.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/thermal-loads": {
      "get": {
        "tags": [
          "Thermal Loads"
        ],
        "summary": "Get All",
        "description": "Gets all loads with optional filtering and pagination.\r\nUse the `cases` query parameter to filter by load cases — accepts SG list format\r\n(e.g. `\"1,3-7,10\"`). Omit any list filter to match all.\r\nReturns an empty array when no loads match the filter — never 404.\r\nResults are sorted by Case ascending, then by entity Id ascending.\r\nPagination metadata is returned in response headers (Total-Count, Offset, Limit).",
        "parameters": [
          {
            "name": "ElementType",
            "in": "query",
            "description": "Filter by element type (member or plate).\r\nReturns only thermal loads for the specified element type.\r\nOmit to return both member and plate thermal loads.",
            "schema": {
              "$ref": "#/components/schemas/ThermalElementType"
            }
          },
          {
            "name": "Elements",
            "in": "query",
            "description": "Element Ids to filter by, in SG list format (e.g. `\"1,3-7,10\"`).\r\nThe meaning depends on ElementType — member Id for members, plate Id for plates.\r\nOmit to return thermal loads for all elements.",
            "schema": {
              "type": "string",
              "example": "1,3-7,10"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "Cases",
            "in": "query",
            "description": "Load cases to filter by, in SG list format (e.g. `\"1,3-7,10\"`).\r\nReturns only loads belonging to the specified cases.\r\nOmit to return loads for all cases.",
            "schema": {
              "type": "string",
              "example": "1,3-7,10"
            },
            "example": "1,3-7,10"
          },
          {
            "name": "LoadCategory",
            "in": "query",
            "description": "Filter by load category number.\r\nReturns only loads assigned to the specified category.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Offset",
            "in": "query",
            "description": "Number of items to skip from the start of the result set. Default is 0.",
            "schema": {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Maximum number of items to return. Default is null (return all).",
            "schema": {
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ThermalLoad"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Thermal Loads"
        ],
        "summary": "Create",
        "description": "Creates a new load. The load case must exist and be a Primary load case.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ThermalLoadCreate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ThermalLoadCreate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ThermalLoadCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/thermal-loads/member/{caseId}/{memberId}": {
      "get": {
        "tags": [
          "Thermal Loads"
        ],
        "summary": "Get Member Thermal Load",
        "description": "Gets the thermal load for a specific member in a load case.",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "memberId",
            "in": "path",
            "description": "The member number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the member thermal load",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ThermalLoad"
                }
              }
            }
          },
          "404": {
            "description": "Member thermal load not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Thermal Loads"
        ],
        "summary": "Update Member Thermal Load",
        "description": "Updates an existing member thermal load. Only provided fields are updated.\r\nThe load case must be a Primary load case.",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "memberId",
            "in": "path",
            "description": "The member number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The update data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ThermalLoadUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ThermalLoadUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ThermalLoadUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the updated member thermal load",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ThermalLoad"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed or load case is not Primary",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Member thermal load not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Thermal Loads"
        ],
        "summary": "Delete Member Thermal Load",
        "description": "Deletes the thermal load for a specific member in a load case.",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "memberId",
            "in": "path",
            "description": "The member number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Member thermal load deleted successfully"
          },
          "404": {
            "description": "Member thermal load not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/thermal-loads/metadata": {
      "get": {
        "tags": [
          "Thermal Loads"
        ],
        "summary": "Get Metadata",
        "description": "Returns schema metadata for this load entity type: field definitions, count, and key structure.\r\nField definitions include names, data types, units, and allowed value ranges.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/thermal-loads/plate/{caseId}/{plateId}": {
      "get": {
        "tags": [
          "Thermal Loads"
        ],
        "summary": "Get Plate Thermal Load",
        "description": "Gets the thermal load for a specific plate in a load case.",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "plateId",
            "in": "path",
            "description": "The plate number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the plate thermal load",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ThermalLoad"
                }
              }
            }
          },
          "404": {
            "description": "Plate thermal load not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Thermal Loads"
        ],
        "summary": "Update Plate Thermal Load",
        "description": "Updates an existing plate thermal load. Only provided fields are updated.\r\nThe load case must be a Primary load case.",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "plateId",
            "in": "path",
            "description": "The plate number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The update data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ThermalLoadUpdate"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ThermalLoadUpdate"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ThermalLoadUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the updated plate thermal load",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ThermalLoad"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed or load case is not Primary",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Plate thermal load not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Thermal Loads"
        ],
        "summary": "Delete Plate Thermal Load",
        "description": "Deletes the thermal load for a specific plate in a load case.",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "description": "The load case number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "plateId",
            "in": "path",
            "description": "The plate number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Plate thermal load deleted successfully"
          },
          "404": {
            "description": "Plate thermal load not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/loads/thermal-loads/bulk": {
      "post": {
        "tags": [
          "Thermal Loads"
        ],
        "summary": "Create Bulk",
        "description": "Creates multiple loads in a bulk operation.\r\nAll load cases referenced must exist and be Primary load cases.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of loads to create",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ThermalLoadCreate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ThermalLoadCreate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ThermalLoadCreate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Thermal Loads"
        ],
        "summary": "Update Bulk",
        "description": "Updates multiple thermal loads. Each item must include case, element, and elementType in the body.\r\nAll load cases referenced must be Primary.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue processing after individual failures",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of update objects (each must include case, element, and elementType)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ThermalLoadUpdate"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ThermalLoadUpdate"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ThermalLoadUpdate"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ThermalLoadBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Thermal Loads"
        ],
        "summary": "Delete Bulk",
        "description": "Deletes multiple thermal loads. Case, element, and elementType are all required for each entry.\r\nThe succeeded array echoes back the Ids of each successfully deleted load.",
        "parameters": [
          {
            "name": "continueOnError",
            "in": "query",
            "description": "Whether to continue on error",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Array of composite Id objects (case + element + elementType, all required)",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ThermalLoadElementId"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ThermalLoadElementId"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ThermalLoadElementId"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ThermalLoadElementIdBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/units": {
      "get": {
        "tags": [
          "Units"
        ],
        "summary": "Get Units",
        "description": "Gets the current unit settings for the job.",
        "responses": {
          "200": {
            "description": "Returns the current units",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Units"
                }
              }
            }
          },
          "404": {
            "description": "No job found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/job/units/metadata": {
      "get": {
        "tags": [
          "Units"
        ],
        "summary": "Get Units Metadata",
        "description": "Returns the schema for `GET /job/units` — one entry per unit property\r\nwith the full list of `allowedValues` (SPACE GASS unit tokens + display\r\nlabels). Use this to drive a units-picker UI without round-tripping to Swagger.",
        "responses": {
          "200": {
            "description": "Returns the units schema",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceMetadata"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "AccelerationUnit": {
        "enum": [
          "gs",
          "ftpersec2",
          "inpersec2",
          "mpersec2",
          "cmpersec2",
          "mmpersec2",
          "kNperkg"
        ],
        "type": "string",
        "description": "Acceleration unit. Members mirror SPACE GASS `SgAcceleration`."
      },
      "AllowedValue": {
        "type": "object",
        "properties": {
          "value": {
            "type": "string",
            "description": "The exact string token the wire accepts and returns for this enum value\r\n(the C# enum identifier, e.g. `\"CompressionOnly\"`). Use this directly in\r\nrequest bodies — it matches what comes back on reads.",
            "nullable": true
          },
          "label": {
            "type": "string",
            "description": "Human-readable label for display (e.g. `\"Compression only\"`). Pulled from\r\n`[Description]` or `[Display(Name=…)]` on the enum member when present,\r\notherwise falls back to the enum identifier.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A permitted value for an enum-backed field.\r\nUse `value` in request bodies; `label` is for display only."
      },
      "AnalysisLoadCaseProgress": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer",
            "description": "Total number of load cases",
            "format": "int32"
          },
          "index": {
            "type": "integer",
            "description": "Current load case index (0-based)",
            "format": "int32"
          },
          "id": {
            "type": "integer",
            "description": "Current load case identifier",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Load case progress information"
      },
      "AnalysisLogLevel": {
        "enum": [
          "Info",
          "Warning",
          "Error"
        ],
        "type": "string",
        "description": "Log level for analysis messages"
      },
      "AnalysisLogMessage": {
        "type": "object",
        "properties": {
          "level": {
            "$ref": "#/components/schemas/AnalysisLogLevel"
          },
          "text": {
            "type": "string",
            "description": "The message text",
            "nullable": true
          },
          "timestamp": {
            "type": "string",
            "description": "When the message was received",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "A log message from the analysis solver"
      },
      "AnalysisProgress": {
        "type": "object",
        "properties": {
          "totalSteps": {
            "type": "integer",
            "description": "Total number of analysis steps/phases discovered so far.\r\nInferred dynamically from solver messages (the solver does not declare total steps upfront).",
            "format": "int32"
          },
          "currentStep": {
            "type": "integer",
            "description": "Current step being processed (0-based index)",
            "format": "int32"
          },
          "iterationPercentage": {
            "type": "integer",
            "description": "Iteration progress percentage (0-100) for the current solver iteration",
            "format": "int32"
          },
          "stepPercentages": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int32"
            },
            "description": "Per-step percentage completion. Array index corresponds to step index.",
            "nullable": true
          },
          "stepLabels": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Per-step labels/names (e.g., \"Assembling geometric data\", \"Solving stiffness matrix\").\r\nArray index corresponds to step index. Null entries mean no label received yet.",
            "nullable": true
          },
          "loadCaseStatus": {
            "type": "string",
            "description": "Live load case status string, updated as load cases are processed.\r\ne.g., starts as \"55\" then becomes \"40 (29/55)\" during analysis.\r\nNull if no load case information is available.",
            "nullable": true
          },
          "loadCaseCount": {
            "$ref": "#/components/schemas/AnalysisLoadCaseProgress"
          },
          "statusText": {
            "type": "string",
            "description": "Current status text from the solver (e.g., \"Analysing..\", \"Saving results..\")",
            "nullable": true
          },
          "messages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AnalysisLogMessage"
            },
            "description": "Log messages from the solver (info, warnings, errors).\r\nIncludes error/warning messages (from negative textIndex) and completion info.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Live progress data from the analysis solver.\r\nCaptured via Windows messages from SGSolver.EXE to the display proxy window."
      },
      "AnalysisRun": {
        "type": "object",
        "properties": {
          "runId": {
            "type": "string",
            "description": "Unique identifier for this run",
            "format": "uuid"
          },
          "analysisType": {
            "$ref": "#/components/schemas/AnalysisType"
          },
          "status": {
            "$ref": "#/components/schemas/AnalysisRunStatus"
          },
          "startedAt": {
            "type": "string",
            "description": "When the run was initiated",
            "format": "date-time"
          },
          "completedAt": {
            "type": "string",
            "description": "When the run finished. Null if still running.",
            "format": "date-time",
            "nullable": true
          },
          "elapsedTime": {
            "type": "string",
            "description": "Total elapsed time as a formatted string (e.g., \"00:01:23.456\").\r\nLive-computed while Running or Cancelling, stored after completion. Null while Queued.",
            "nullable": true
          },
          "errorMessage": {
            "type": "string",
            "description": "Error message if the run failed",
            "nullable": true
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Warning messages generated during the analysis",
            "nullable": true
          },
          "header": {
            "type": "string",
            "description": "Header describing the analysis type (e.g., \"Non-Linear Static Analysis (64-bit)\").\r\nAvailable while running (from live progress) and after completion (persisted on run).",
            "nullable": true
          },
          "parameters": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Static analysis parameters as label→value pairs.\r\nSet during analysis initialisation and do not change during execution.\r\ne.g., { \"Input data:\": \"4.6 Mb (Mem)\", \"Degrees of freedom:\": \"26244\", \"Load cases:\": \"55\" }\r\nAvailable while running (from live progress) and after completion (persisted on run).",
            "nullable": true
          },
          "convergenceHistory": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ConvergenceEntry"
            },
            "description": "Convergence history from non-linear analysis iterations.\r\nAvailable while running (from live progress) and after completion (persisted on run).\r\nNull for linear analyses or before any convergence is reached.",
            "nullable": true
          },
          "progress": {
            "$ref": "#/components/schemas/AnalysisProgress"
          }
        },
        "additionalProperties": false,
        "description": "Response DTO representing an analysis run and its current state.\r\nUsed for both the initial 202 response and subsequent status polling."
      },
      "AnalysisRunResult": {
        "type": "object",
        "properties": {
          "runId": {
            "type": "string",
            "description": "Unique identifier for this run",
            "format": "uuid"
          },
          "analysisType": {
            "$ref": "#/components/schemas/AnalysisType"
          },
          "status": {
            "$ref": "#/components/schemas/AnalysisRunStatus"
          },
          "elapsedTime": {
            "type": "string",
            "description": "Total elapsed time as a formatted string",
            "nullable": true
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Warning messages generated during the analysis",
            "nullable": true
          },
          "errorMessage": {
            "type": "string",
            "description": "Error message if the run failed",
            "nullable": true
          },
          "convergenceHistory": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ConvergenceEntry"
            },
            "description": "Convergence history from non-linear analysis iterations.\r\nNull for linear analyses or if no convergence was recorded.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Result summary DTO returned once an analysis run completes.\r\nFor actual analysis result data, use the query endpoints\r\n(e.g., /api/v1/job/query/analysis/static/node-reactions)."
      },
      "AnalysisRunStatus": {
        "enum": [
          "Queued",
          "Running",
          "Cancelling",
          "Completed",
          "Failed",
          "Cancelled"
        ],
        "type": "string",
        "description": "Status of an analysis run through its lifecycle."
      },
      "AnalysisType": {
        "enum": [
          "LinearStaticAnalysis",
          "NonLinearStaticAnalysis",
          "DynamicFrequencyAnalysis",
          "SpectralResponseAnalysis",
          "BucklingAnalysis",
          "HarmonicAnalysis",
          "LinearTransientAnalysis",
          "NonLinearTransientAnalysis",
          "None"
        ],
        "type": "string",
        "description": "SPACEGASS analysis types. Values map to the SPACEGASS internal SGAnalysisType IDs."
      },
      "AngleType": {
        "enum": [
          "NotApplicable",
          "SingleType",
          "ShortShort",
          "LongLong",
          "Starred"
        ],
        "type": "string",
        "description": "Angle section type for structural sections.\r\nMaps to SPACE GASS lookup table \"Angle Type\"."
      },
      "AxesType": {
        "enum": [
          "Local",
          "Global"
        ],
        "type": "string",
        "description": "Coordinate axes type (Local or Global).\r\nMaps to SPACE GASS lookup table \"L/G Axes\"."
      },
      "AxialForceDistribution": {
        "enum": [
          "Linear",
          "NonLinear"
        ],
        "type": "string",
        "description": "Axial force distribution method for buckling analysis."
      },
      "BucklingEffectiveLength": {
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "Load case ID.",
            "format": "int32"
          },
          "mode": {
            "type": "integer",
            "description": "Buckling mode number.",
            "format": "int32"
          },
          "member": {
            "type": "integer",
            "description": "Member key.",
            "format": "int32"
          },
          "pcr": {
            "type": "number",
            "description": "Critical buckling load. Unit: Force (see GET /job/units).",
            "format": "float"
          },
          "length": {
            "type": "number",
            "description": "Member length. Unit: Length (see GET /job/units).",
            "format": "float"
          },
          "ly": {
            "type": "number",
            "description": "Effective length about Y axis. Unit: Length (see GET /job/units).",
            "format": "float"
          },
          "lz": {
            "type": "number",
            "description": "Effective length about Z axis. Unit: Length (see GET /job/units).",
            "format": "float"
          }
        },
        "additionalProperties": false,
        "description": "Buckling effective length result (FileId 217)."
      },
      "BucklingEffectiveLengthQueryResult": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BucklingEffectiveLength"
            },
            "description": "The query result rows.",
            "nullable": true
          },
          "warnings": {
            "$ref": "#/components/schemas/QueryWarnings"
          }
        },
        "additionalProperties": false,
        "description": "Wrapper for analysis query results.\r\nContains the result data plus optional warnings about requested cases or modes\r\nthat produced no results (i.e. were not analysed)."
      },
      "BucklingLoadFactor": {
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "Load case ID.",
            "format": "int32"
          },
          "mode": {
            "type": "integer",
            "description": "Buckling mode number.",
            "format": "int32"
          },
          "warning": {
            "type": "string",
            "description": "Analysis engine warning message (empty if none).",
            "nullable": true
          },
          "loadFactor": {
            "type": "number",
            "description": "Buckling load factor.",
            "format": "float"
          },
          "tolerance": {
            "type": "number",
            "description": "Convergence tolerance.",
            "format": "float"
          },
          "iterations": {
            "type": "integer",
            "description": "Number of iterations to converge.",
            "format": "int32"
          },
          "nodeAtMaxTrans": {
            "type": "number",
            "description": "Node key at maximum translation.",
            "format": "float"
          },
          "transAxis": {
            "type": "string",
            "description": "Axis of maximum translation.",
            "nullable": true
          },
          "nodeAtMaxRotn": {
            "type": "number",
            "description": "Node key at maximum rotation.",
            "format": "float"
          },
          "rotnAxis": {
            "type": "string",
            "description": "Axis of maximum rotation.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Buckling load factor result (FileId 216)."
      },
      "BucklingLoadFactorQueryResult": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BucklingLoadFactor"
            },
            "description": "The query result rows.",
            "nullable": true
          },
          "warnings": {
            "$ref": "#/components/schemas/QueryWarnings"
          }
        },
        "additionalProperties": false,
        "description": "Wrapper for analysis query results.\r\nContains the result data plus optional warnings about requested cases or modes\r\nthat produced no results (i.e. were not analysed)."
      },
      "BucklingSettings": {
        "type": "object",
        "properties": {
          "loadCases": {
            "type": "string",
            "description": "Load cases to include in the analysis, in SG list format (e.g. `\"1,3,5-10\"`).\r\nOmit or pass an empty string to include all load cases (default).\r\nMaximum 50 entries (individual numbers and ranges each count as entries).",
            "nullable": true,
            "example": "1,3,5-10"
          },
          "retainCases": {
            "type": "boolean",
            "description": "Whether to retain results of other load cases during analysis.\r\nWhen true, results from previously analysed load cases are preserved."
          },
          "checkNonExistentCases": {
            "type": "boolean",
            "description": "Whether to check for non-existent load cases referenced in the analysis.\r\nWhen true, warnings are generated for missing load cases."
          },
          "stabilizeUnrestrainedNodes": {
            "type": "boolean",
            "description": "Whether to stabilize unrestrained nodes during analysis.\r\nWhen true, temporary restraints are added to prevent instability."
          },
          "tensionCompressionOnly": {
            "$ref": "#/components/schemas/TensionCompressionOnlyMode"
          },
          "reversalIterations": {
            "type": "integer",
            "description": "Number of iterations before disabling reversal of tension/compression-only members.\r\nOnly relevant when TensionCompressionOnly is Activated.",
            "format": "int32"
          },
          "tolerance": {
            "type": "number",
            "description": "Convergence tolerance for the buckling analysis.",
            "format": "float"
          },
          "upperLimit": {
            "type": "number",
            "description": "Upper limit for the load factor in buckling analysis.",
            "format": "float"
          },
          "lowerLimit": {
            "type": "number",
            "description": "Lower limit for the load factor in buckling analysis.",
            "format": "float"
          },
          "modes": {
            "type": "integer",
            "description": "Number of buckling modes to compute.",
            "format": "int32"
          },
          "extraIterations": {
            "type": "boolean",
            "description": "Whether to perform extra iterations for improved mode shape accuracy."
          },
          "axialForceDistribution": {
            "$ref": "#/components/schemas/AxialForceDistribution"
          },
          "optimizationMethod": {
            "$ref": "#/components/schemas/OptimizationMethod"
          },
          "optimizationAxis": {
            "$ref": "#/components/schemas/OptimizationAxis"
          },
          "optimizationX": {
            "type": "number",
            "description": "X coordinate or X component of the optimization vector.",
            "format": "float"
          },
          "optimizationY": {
            "type": "number",
            "description": "Y coordinate or Y component of the optimization vector.",
            "format": "float"
          },
          "optimizationZ": {
            "type": "number",
            "description": "Z coordinate or Z component of the optimization vector.",
            "format": "float"
          },
          "solverType": {
            "$ref": "#/components/schemas/SolverType"
          },
          "drillingStiffness": {
            "type": "number",
            "description": "Drilling stiffness multiplier for plate elements.",
            "format": "float"
          },
          "plateType": {
            "$ref": "#/components/schemas/PlateType"
          },
          "theory": {
            "$ref": "#/components/schemas/BucklingTheory"
          }
        },
        "additionalProperties": false,
        "description": "Settings for Buckling Analysis."
      },
      "BucklingSettingsUpdate": {
        "type": "object",
        "properties": {
          "loadCases": {
            "type": "string",
            "nullable": true
          },
          "retainCases": {
            "type": "boolean",
            "nullable": true
          },
          "checkNonExistentCases": {
            "type": "boolean",
            "nullable": true
          },
          "stabilizeUnrestrainedNodes": {
            "type": "boolean",
            "nullable": true
          },
          "tensionCompressionOnly": {
            "$ref": "#/components/schemas/TensionCompressionOnlyMode"
          },
          "reversalIterations": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "tolerance": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "upperLimit": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "lowerLimit": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "modes": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "extraIterations": {
            "type": "boolean",
            "nullable": true
          },
          "axialForceDistribution": {
            "$ref": "#/components/schemas/AxialForceDistribution"
          },
          "optimizationMethod": {
            "$ref": "#/components/schemas/OptimizationMethod"
          },
          "optimizationAxis": {
            "$ref": "#/components/schemas/OptimizationAxis"
          },
          "optimizationX": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "optimizationY": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "optimizationZ": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "solverType": {
            "$ref": "#/components/schemas/SolverType"
          },
          "drillingStiffness": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "plateType": {
            "$ref": "#/components/schemas/PlateType"
          },
          "theory": {
            "$ref": "#/components/schemas/BucklingTheory"
          }
        },
        "additionalProperties": false,
        "description": "Update request for Buckling Analysis settings.\r\nOnly fields included in the request are updated; omit a field to keep its current value."
      },
      "BucklingTheory": {
        "enum": [
          "SigncountEigensolver",
          "ClassicEigensolver"
        ],
        "type": "string",
        "description": "Eigensolver theory used for buckling analysis."
      },
      "BulkError": {
        "type": "object",
        "properties": {
          "index": {
            "type": "integer",
            "description": "Index of the item in the original request (0-based).",
            "format": "int32"
          },
          "id": {
            "type": "integer",
            "description": "Entity Id of the failed item (for single-Id entities).",
            "format": "int32",
            "nullable": true
          },
          "ids": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int32"
            },
            "description": "Id values of the failed item (for multi-Id entities).",
            "nullable": true
          },
          "error": {
            "type": "string",
            "description": "Error message describing what went wrong.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Detailed SPACE GASS validation messages for this item, when available.\r\nPopulated from `SpaceGassException.SpaceGassErrors` so callers see\r\nthe exact field-level diagnostic (\"Restraint Code: Valid characters are FRSVPN\")\r\nwithout needing a follow-up call to `GET /job/errors/last`.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Error details for a failed bulk item."
      },
      "CaseModesWarning": {
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "Load case Id this entry applies to.",
            "format": "int32",
            "example": 2
          },
          "modes": {
            "type": "string",
            "description": "Mode numbers the caller requested but the analysis did not produce for this case.\r\nSG list-format string.",
            "nullable": true,
            "example": "4-5"
          }
        },
        "additionalProperties": false,
        "description": "One case's missing-mode entry inside SpaceGassApi.Models.Dtos.Query.Analysis.QueryWarningsDto.ModesNotAnalyzed."
      },
      "CombinationLoadCaseCreate": {
        "required": [
          "combinationItems",
          "title"
        ],
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier - must be unique, no duplicates allowed.\r\nOptional - will be auto-assigned to next available number if not provided.\r\nIf provided, must not already exist in the model.",
            "format": "int32",
            "nullable": true,
            "example": 1
          },
          "title": {
            "maxLength": 100,
            "minLength": 0,
            "type": "string",
            "description": "Load case title.",
            "example": "Dead Load"
          },
          "notes": {
            "maxLength": 2048,
            "minLength": 0,
            "type": "string",
            "description": "Load case notes (supports multi-line text).",
            "nullable": true,
            "example": "Self-weight of structural steel members"
          },
          "combinationItems": {
            "minItems": 1,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CombinationLoadCaseItem"
            },
            "description": "The component cases and their multiplying factors that make up this combination case."
          }
        },
        "additionalProperties": false,
        "description": "Request payload for creating a combination load case in a single call.\r\nInherits Id, Guid, Title and Notes from SpaceGassApi.Models.Dtos.Entity.Loads.LoadCaseCreateDto and adds\r\na required, non-empty list of combination items."
      },
      "CombinationLoadCaseItem": {
        "required": [
          "case",
          "multiplyingFactor"
        ],
        "type": "object",
        "properties": {
          "case": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Component load case number.",
            "format": "int32",
            "example": 1
          },
          "multiplyingFactor": {
            "type": "number",
            "description": "Multiplying factor applied to the component load case (default: 1.0).",
            "format": "double",
            "example": 1.2
          }
        },
        "additionalProperties": false,
        "description": "Represents a single component within a load combination — a component case Id and\r\nthe multiplying factor applied to it."
      },
      "CombinationLoadCaseUpdate": {
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier of the entity to update.\r\nOptional for single updates (Id comes from route), required for bulk updates.",
            "format": "int32",
            "nullable": true,
            "example": 1
          },
          "title": {
            "maxLength": 100,
            "minLength": 0,
            "type": "string",
            "description": "Load case title.",
            "nullable": true,
            "example": "Dead Load (revised)"
          },
          "notes": {
            "maxLength": 2048,
            "minLength": 0,
            "type": "string",
            "description": "Load case notes (supports multi-line text).",
            "nullable": true,
            "example": "Updated to include cladding self-weight"
          },
          "combinationItems": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CombinationLoadCaseItem"
            },
            "description": "Replacement combination items for this case. Omit to leave items unchanged.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Request payload for updating a combination load case.\r\nInherits Id, Title and Notes from SpaceGassApi.Models.Dtos.Entity.Loads.LoadCaseUpdateDto (each optional for\r\npartial update) and adds an optional `combinationItems` list."
      },
      "ConstraintAxes": {
        "enum": [
          "Global",
          "Inclined"
        ],
        "type": "string",
        "description": "Coordinate axis system used for master-slave constraint equations.\r\nMaps to SPACE GASS lookup table \"Constraint Axes\"."
      },
      "ConvergenceEntry": {
        "type": "object",
        "properties": {
          "iteration": {
            "type": "integer",
            "description": "Sequential iteration number (1-based)",
            "format": "int32"
          },
          "percentage": {
            "type": "number",
            "description": "Convergence percentage achieved at this iteration (e.g., 98.177)",
            "format": "double"
          }
        },
        "additionalProperties": false,
        "description": "A convergence result from a non-linear analysis iteration."
      },
      "DirectionAxis": {
        "enum": [
          "NotApplicable",
          "XAxis",
          "YAxis",
          "ZAxis",
          "NegativeXAxis",
          "NegativeYAxis",
          "NegativeZAxis"
        ],
        "type": "string",
        "description": "Direction axis for member orientation.\r\nMaps to SPACE GASS lookup table \"Direction Axis\"."
      },
      "DirectionSource": {
        "enum": [
          "Angle",
          "Node",
          "Axis"
        ],
        "type": "string",
        "description": "Indicates which field defines a member or plate's direction.\r\nSetting one source zeros the other two direction fields.\r\nValues align with SG's `SGLookupAxisDirection` enum in CommonEnums.vb."
      },
      "DirectionUpdate": {
        "type": "object",
        "properties": {
          "dirAngle": {
            "type": "number",
            "description": "Direction angle for orientation. Mutually exclusive with `dirNode` and `dirAxis`.",
            "format": "double",
            "nullable": true
          },
          "dirNode": {
            "type": "integer",
            "description": "Direction node Id for orientation. Mutually exclusive with `dirAngle` and `dirAxis`.",
            "format": "int32",
            "nullable": true
          },
          "dirAxis": {
            "$ref": "#/components/schemas/DirectionAxis"
          }
        },
        "additionalProperties": false,
        "description": "DTO for updating the direction on a member or plate (partial-update semantics)."
      },
      "DynamicFrequencySettings": {
        "type": "object",
        "properties": {
          "loadCases": {
            "type": "string",
            "description": "Load cases to include in the analysis, in SG list format (e.g. `\"1,3,5-10\"`).\r\nOmit or pass an empty string to include all load cases (default).\r\nMaximum 50 entries (individual numbers and ranges each count as entries).",
            "nullable": true,
            "example": "1,3,5-10"
          },
          "retainCases": {
            "type": "boolean",
            "description": "Whether to retain results of other load cases during analysis.\r\nWhen true, results from previously analysed load cases are preserved."
          },
          "checkNonExistentCases": {
            "type": "boolean",
            "description": "Whether to check for non-existent load cases referenced in the analysis.\r\nWhen true, warnings are generated for missing load cases."
          },
          "stabilizeUnrestrainedNodes": {
            "type": "boolean",
            "description": "Whether to stabilize unrestrained nodes during analysis.\r\nWhen true, temporary restraints are added to prevent instability."
          },
          "tolerance": {
            "type": "number",
            "description": "Convergence tolerance for the frequency analysis.",
            "format": "float"
          },
          "upperLimit": {
            "type": "number",
            "description": "Upper limit for the frequency range.",
            "format": "float"
          },
          "lowerLimit": {
            "type": "number",
            "description": "Lower limit for the frequency range.",
            "format": "float"
          },
          "frequencyShift": {
            "type": "number",
            "description": "Frequency shift value for the eigensolver.",
            "format": "float"
          },
          "modes": {
            "type": "integer",
            "description": "Number of dynamic modes to compute.",
            "format": "int32"
          },
          "extraIterations": {
            "type": "boolean",
            "description": "Whether to perform extra iterations for improved mode shape accuracy."
          },
          "optimizationMethod": {
            "$ref": "#/components/schemas/FrequencyOptimizationMethod"
          },
          "optimizationAxis": {
            "$ref": "#/components/schemas/OptimizationAxis"
          },
          "optimizationX": {
            "type": "number",
            "description": "X coordinate for optimization.",
            "format": "float"
          },
          "optimizationY": {
            "type": "number",
            "description": "Y coordinate for optimization.",
            "format": "float"
          },
          "optimizationZ": {
            "type": "number",
            "description": "Z coordinate for optimization.",
            "format": "float"
          },
          "solverType": {
            "$ref": "#/components/schemas/SolverType"
          },
          "drillingStiffness": {
            "type": "number",
            "description": "Drilling stiffness multiplier for plate elements.",
            "format": "float"
          },
          "plateType": {
            "$ref": "#/components/schemas/PlateType"
          }
        },
        "additionalProperties": false,
        "description": "Settings for Dynamic Frequency Analysis."
      },
      "DynamicFrequencySettingsUpdate": {
        "type": "object",
        "properties": {
          "loadCases": {
            "type": "string",
            "nullable": true
          },
          "retainCases": {
            "type": "boolean",
            "nullable": true
          },
          "checkNonExistentCases": {
            "type": "boolean",
            "nullable": true
          },
          "stabilizeUnrestrainedNodes": {
            "type": "boolean",
            "nullable": true
          },
          "tolerance": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "upperLimit": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "lowerLimit": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "frequencyShift": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "modes": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "extraIterations": {
            "type": "boolean",
            "nullable": true
          },
          "optimizationMethod": {
            "$ref": "#/components/schemas/FrequencyOptimizationMethod"
          },
          "optimizationAxis": {
            "$ref": "#/components/schemas/OptimizationAxis"
          },
          "optimizationX": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "optimizationY": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "optimizationZ": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "solverType": {
            "$ref": "#/components/schemas/SolverType"
          },
          "drillingStiffness": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "plateType": {
            "$ref": "#/components/schemas/PlateType"
          }
        },
        "additionalProperties": false,
        "description": "Update request for Dynamic Frequency Analysis settings.\r\nOnly fields included in the request are updated; omit a field to keep its current value."
      },
      "EntityId": {
        "enum": [
          "Nodes",
          "Members",
          "Plates",
          "PlateCuts",
          "PlateStrips",
          "Solids",
          "NodeLoads",
          "MemberConcentratedLoads",
          "MemberDistributedLoads",
          "MemberTorsionLoads",
          "MemberPrestressLoads",
          "PlateLoads",
          "AreaLoads",
          "PrescribedDisplacements",
          "SelfWeightLoads",
          "ThermalLoads",
          "LumpedMassLoads",
          "Sections",
          "Materials",
          "NodeRestraints",
          "NodeConstraints",
          "MemberOffsets",
          "MemberReleases",
          "MemberDirection",
          "PlateDirection",
          "Units",
          "JobSettings",
          "LoadCases",
          "LoadCaseGroups",
          "LoadCategories",
          "CombinationLoadCases",
          "LoadCombinations",
          "AnalysisSettings",
          "NodeDisplacements",
          "NodeReactions",
          "MemberEndForces",
          "MemberIntermediateForces",
          "MemberIntermediateDisplacements",
          "MemberStresses",
          "PlateNodalForces",
          "PlateElementForces",
          "PlateElementStresses",
          "BucklingLoadFactors",
          "BucklingEffectiveLengths",
          "NaturalFrequencies",
          "ModeShapes",
          "SteelCheckSummary"
        ],
        "type": "string",
        "description": "Identifies entity types managed by the API.\r\nKept separate from SGFileID to allow for future API-only entities\r\nthat may not have a formal SPACE GASS FileID."
      },
      "ErrorList": {
        "type": "object",
        "properties": {
          "errors": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "List of error messages",
            "nullable": true
          },
          "count": {
            "type": "integer",
            "description": "Number of errors",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Response containing error list."
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "description": "A short, human-readable summary of the problem type",
            "nullable": true
          },
          "status": {
            "type": "integer",
            "description": "HTTP status code",
            "format": "int32"
          },
          "detail": {
            "type": "string",
            "description": "A human-readable explanation specific to this occurrence",
            "nullable": true
          },
          "instance": {
            "type": "string",
            "description": "A URI reference that identifies the specific occurrence",
            "nullable": true
          },
          "errorCode": {
            "type": "string",
            "description": "Machine-readable error code for programmatic handling",
            "nullable": true
          },
          "source": {
            "$ref": "#/components/schemas/ErrorSource"
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "description": "List of errors describing what went wrong. Always populated on the wire — falls back\r\nto a single entry derived from SpaceGassApi.Models.Dtos.Common.ErrorResponseDto.Detail / SpaceGassApi.Models.Dtos.Common.ErrorResponseDto.ErrorCode when no\r\ncaller-supplied list is present, so clients can iterate uniformly.\r\nMultiple entries appear for validation failures (one entry per failed rule).",
            "nullable": true
          },
          "extensions": {
            "type": "object",
            "additionalProperties": {},
            "description": "Additional context-specific data",
            "nullable": true
          },
          "timestamp": {
            "type": "string",
            "description": "Timestamp when the error occurred",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "Standard error response format for all API errors\r\nFollows RFC 7807 Problem Details pattern"
      },
      "ErrorSource": {
        "enum": [
          "SpaceGass",
          "Validation",
          "Api",
          "Infrastructure",
          "Unknown"
        ],
        "type": "string",
        "description": "Source of the error. Serialised as its string identifier (e.g. \"Infrastructure\") on the wire\r\nregardless of which JSON pipeline emits the response — the MVC `AddJsonOptions` string-enum\r\nconverter doesn't apply to direct `HttpResponse.WriteAsJsonAsync` writes (used by\r\n`GlobalExceptionHandler`), so the converter is declared on the enum itself."
      },
      "ExpandOption": {
        "enum": [
          "None",
          "All"
        ],
        "type": "string",
        "description": "Controls sub-resource hydration on entity GET endpoints.\r\nShared across every resource that supports expansion — a given resource's\r\nmetadata (`expandable`) lists which sub-resources `All` hydrates."
      },
      "FieldMetadata": {
        "type": "object",
        "properties": {
          "jsonName": {
            "type": "string",
            "description": "Wire-format property key — the JSON object key a client sees in a GET\r\nresponse body. This is the authoritative public identifier for the field.",
            "nullable": true
          },
          "dataType": {
            "type": "string",
            "description": "Data type: \"Integer\" | \"Double\" | \"String\" | \"Enum\" | \"Boolean\" | \"Guid\".\r\nFor enums, see SpaceGassApi.Models.Dtos.Common.FieldMetadataDto.AllowedValues for the permitted values.",
            "nullable": true
          },
          "units": {
            "type": "string",
            "description": "Resolved unit label based on the current job units — e.g. \"mm\", \"kN\",\r\n\"kN/mm^2\". Null when the field has no units.",
            "nullable": true
          },
          "min": {
            "type": "string",
            "description": "Minimum allowed value for this field (as a string; use `dataType` to determine how to parse it).\r\nNull if no minimum constraint applies.",
            "nullable": true
          },
          "max": {
            "type": "string",
            "description": "Maximum allowed value for this field (as a string; use `dataType` to determine how to parse it).\r\nNull if no maximum constraint applies.",
            "nullable": true
          },
          "default": {
            "type": "string",
            "description": "Default value when the field is omitted on create.",
            "nullable": true
          },
          "maxLength": {
            "type": "integer",
            "description": "Maximum length for string fields (characters). Null for non-string fields.",
            "format": "int32",
            "nullable": true
          },
          "description": {
            "type": "string",
            "description": "Optional hint text for this field, useful for UI labels and tooltips. Null when not available.",
            "nullable": true
          },
          "allowedValues": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AllowedValue"
            },
            "description": "For enum-backed fields, the permitted values with their wire tokens and display labels.\r\nUse `value` in request bodies; `label` is for display only. Null for non-enum fields.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Metadata for a single field in a resource. The shape mirrors what clients see on\r\nthe wire — SpaceGassApi.Models.Dtos.Common.FieldMetadataDto.JsonName is the exact property key a JSON consumer will\r\nread, so a client can correlate metadata to payload without any translation."
      },
      "FileOpeningStatus": {
        "type": "object",
        "properties": {
          "filePath": {
            "type": "string",
            "description": "The file path that was checked",
            "nullable": true
          },
          "status": {
            "$ref": "#/components/schemas/JobFileOpeningStatus"
          },
          "description": {
            "type": "string",
            "description": "Human-readable description of the status",
            "nullable": true
          },
          "recommendedAction": {
            "type": "string",
            "description": "Recommended action to take based on the status",
            "nullable": true
          },
          "canOpenSafely": {
            "type": "boolean",
            "description": "Whether the file can be opened safely without force options"
          }
        },
        "additionalProperties": false,
        "description": "Status information about a SPACE GASS file's readiness for opening."
      },
      "ForceUnit": {
        "enum": [
          "K",
          "lb",
          "kN",
          "N",
          "kg"
        ],
        "type": "string",
        "description": "Force unit. Members mirror SPACE GASS `SgForce`."
      },
      "FrequencyOptimizationMethod": {
        "enum": [
          "None",
          "General",
          "Linear",
          "Angular"
        ],
        "type": "string",
        "description": "Optimization method for Dynamic Frequency analysis.\r\nNote: These have different integer mappings than the static/buckling OptimizationMethod enum."
      },
      "FrictionNormalAxis": {
        "enum": [
          "None",
          "XAxis",
          "YAxis",
          "ZAxis"
        ],
        "type": "string",
        "description": "Friction normal axis for restraint friction definitions.\r\nMaps to SPACE GASS lookup table \"N/X/Y/Z Axes\"."
      },
      "FrictionNormalDirection": {
        "enum": [
          "Either",
          "PositiveOnly",
          "NegativeOnly"
        ],
        "type": "string",
        "description": "Friction normal direction for restraint friction definitions.\r\nMaps to SPACE GASS lookup table \"Normal Direction\"."
      },
      "Job": {
        "type": "object",
        "properties": {
          "headings": {
            "$ref": "#/components/schemas/JobHeadings"
          },
          "settings": {
            "$ref": "#/components/schemas/JobSettings"
          },
          "units": {
            "$ref": "#/components/schemas/Units"
          }
        },
        "additionalProperties": false,
        "description": "Read DTO for job responses.\r\nModel counts and file state are available via GET /job/status (JobStatusDto)."
      },
      "JobFile": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "File name only (e.g. \"Bridge_Design_v2.sg\").",
            "nullable": true
          },
          "path": {
            "type": "string",
            "description": "Full file path (e.g. \"C:/Projects/Bridge_Design_v2.sg\").",
            "nullable": true
          },
          "source": {
            "$ref": "#/components/schemas/JobFileSource"
          }
        },
        "additionalProperties": false,
        "description": "File information for the current job."
      },
      "JobFileOpeningStatus": {
        "enum": [
          "NoSGandNoATS",
          "SGNotOpenAndNoAts",
          "SGOpenAndNoAts",
          "NoSGButAts",
          "SGNotOpenButAts",
          "SGOpenAndAts",
          "UnknownStatus"
        ],
        "type": "string",
        "description": "Status of a job file for opening, based on .sg file and ATS file states"
      },
      "JobFilePreviewInfo": {
        "type": "object",
        "properties": {
          "dataAvailable": {
            "type": "boolean",
            "description": "Whether metadata was available in the file.\r\nOlder files may not have this data appended."
          },
          "filePath": {
            "type": "string",
            "description": "The file path that was queried",
            "nullable": true
          },
          "fileName": {
            "type": "string",
            "description": "The file name without path",
            "nullable": true
          },
          "fileSizeBytes": {
            "type": "integer",
            "description": "File size in bytes",
            "format": "int64"
          },
          "lastModified": {
            "type": "string",
            "description": "Last modified date of the file",
            "format": "date-time",
            "nullable": true
          },
          "version": {
            "type": "string",
            "description": "The SPACE GASS version that was used to save the file",
            "nullable": true
          },
          "licenseeName": {
            "type": "string",
            "description": "The licensee name that was used when saving the file",
            "nullable": true
          },
          "designer": {
            "type": "string",
            "description": "The designer name when the file was saved",
            "nullable": true
          },
          "projectHeading": {
            "type": "string",
            "description": "The project heading/title",
            "nullable": true
          },
          "jobHeading": {
            "type": "string",
            "description": "The job heading/title",
            "nullable": true
          },
          "notes": {
            "type": "string",
            "description": "Job notes",
            "nullable": true
          },
          "dateSaved": {
            "type": "string",
            "description": "Date and time the file was saved",
            "nullable": true
          },
          "computerName": {
            "type": "string",
            "description": "Computer name where the file was saved",
            "nullable": true
          },
          "userName": {
            "type": "string",
            "description": "User name who saved the file",
            "nullable": true
          },
          "compression": {
            "type": "string",
            "description": "Compression type used when saving the file",
            "nullable": true
          },
          "hasPreviewImage": {
            "type": "boolean",
            "description": "Whether a preview image is available"
          },
          "previewImageBase64": {
            "type": "string",
            "description": "The preview image as a base64-encoded PNG string.\r\nOnly populated if includeImage parameter is true.",
            "nullable": true
          },
          "previewImageDataUrl": {
            "type": "string",
            "description": "The preview image as a Data URL (data:image/png;base64,...).\r\nCan be used directly in HTML img src attribute.\r\nOnly available if includeImage parameter is true and image exists.",
            "nullable": true,
            "readOnly": true
          }
        },
        "additionalProperties": false,
        "description": "Information extracted from a SPACE GASS job file (.sg or .sgbase).\r\nContains metadata appended to the file when saved."
      },
      "JobFileSource": {
        "enum": [
          "None",
          "LocalFile",
          "NewJob"
        ],
        "type": "string",
        "description": "Enum representing the source of a job file"
      },
      "JobForceAccessOption": {
        "enum": [
          "None",
          "OpenPreviousSaved",
          "OpenUnsavedMostRecent"
        ],
        "type": "string",
        "description": "Options for forcing access to a job file that is in a locked or unsaved state.\r\nUsed when temporary files exist from a previous session that was not properly closed."
      },
      "JobHeadings": {
        "type": "object",
        "properties": {
          "projectHeading": {
            "type": "string",
            "description": "Project heading",
            "nullable": true
          },
          "heading": {
            "type": "string",
            "description": "Job heading",
            "nullable": true
          },
          "designerInitials": {
            "type": "string",
            "description": "Designer initials",
            "nullable": true
          },
          "notes": {
            "type": "string",
            "description": "Job notes",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Read DTO for job headings (text properties)."
      },
      "JobHeadingsUpdate": {
        "type": "object",
        "properties": {
          "projectHeading": {
            "maxLength": 50,
            "minLength": 0,
            "type": "string",
            "description": "Project heading. Omit to leave unchanged.",
            "nullable": true
          },
          "heading": {
            "maxLength": 50,
            "minLength": 0,
            "type": "string",
            "description": "Job heading. Omit to leave unchanged.",
            "nullable": true
          },
          "designerInitials": {
            "maxLength": 3,
            "minLength": 0,
            "type": "string",
            "description": "Designer initials. Omit to leave unchanged.",
            "nullable": true
          },
          "notes": {
            "maxLength": 1024,
            "minLength": 0,
            "type": "string",
            "description": "Job notes. Omit to leave unchanged.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Write DTO for updating job headings via PATCH /job/headings.\r\nOmit a field to leave it unchanged."
      },
      "JobSettings": {
        "type": "object",
        "properties": {
          "verticalAxis": {
            "$ref": "#/components/schemas/VerticalAxis"
          }
        },
        "additionalProperties": false,
        "description": "Read DTO for job-level settings.\r\nGroups configuration properties that apply to the job as a whole."
      },
      "JobState": {
        "type": "object",
        "properties": {
          "isOpen": {
            "type": "boolean",
            "description": "Whether a job is currently loaded in memory."
          },
          "isNew": {
            "type": "boolean",
            "description": "Whether this is a new job that has never been saved.\r\nIf true, provide a filePath when calling POST /save."
          },
          "isModified": {
            "type": "boolean",
            "description": "Whether the job has unsaved modifications."
          },
          "openedAt": {
            "type": "string",
            "description": "When the job was opened (null if not open).",
            "format": "date-time",
            "nullable": true
          },
          "file": {
            "$ref": "#/components/schemas/JobFile"
          }
        },
        "additionalProperties": false,
        "description": "Current session/file state of the job."
      },
      "JobStatus": {
        "type": "object",
        "properties": {
          "job": {
            "$ref": "#/components/schemas/Job"
          },
          "state": {
            "$ref": "#/components/schemas/JobState"
          },
          "model": {
            "$ref": "#/components/schemas/ModelSummary"
          }
        },
        "additionalProperties": false,
        "description": "Full job status response including the current job, session state, and model summary.\r\nReturned by lifecycle operations (new, open, save, status) and GET /job/status."
      },
      "LastError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "The last error message (null if no errors)",
            "nullable": true
          },
          "hasError": {
            "type": "boolean",
            "description": "Whether there is an error"
          }
        },
        "additionalProperties": false,
        "description": "Response containing last error."
      },
      "LengthUnit": {
        "enum": [
          "ft",
          "in",
          "m",
          "cm",
          "mm"
        ],
        "type": "string",
        "description": "Length unit. Members mirror SPACE GASS `SGLength`\r\n(`NetCommon/CommonEnums.vb`); integer values and identifiers must stay in\r\nlock-step with it. The System.ComponentModel.DescriptionAttribute carries the display\r\nlabel (mirrors `gcUNITS_LABEL_*`)."
      },
      "LicenseStatus": {
        "type": "object",
        "properties": {
          "isRegistered": {
            "type": "boolean",
            "description": "True when this machine has a SPACE GASS registration the API supports\r\n(TitanCloud or Titan LM). False indicates either an unsupported lock\r\ntype (e.g. legacy SGREG.DAT registration) or no registration at all.\r\nAlways check this before SpaceGassApi.Models.Dtos.License.LicenseStatusDto.IsLicensed: an unregistered\r\nAPI is blocked at the registration step, before any license acquire\r\nis attempted."
          },
          "registrationType": {
            "$ref": "#/components/schemas/RegistrationStatus"
          },
          "registrationDetail": {
            "type": "string",
            "description": "Human-readable explanation of the registration state. Always\r\npopulated. For TitanCloud / TitanLM it confirms the registration\r\nis active; for Unsupported / Unregistered it explains what the\r\noperator should do to fix it.",
            "nullable": true,
            "example": "TitanCloud registration is active. No action required."
          },
          "isLicensed": {
            "type": "boolean",
            "description": "True when the API is currently licensed (Tier 1 API module is held)."
          },
          "isRoaming": {
            "type": "boolean",
            "description": "True when the active Titan LM session is backed by an offline\r\nroaming licence file (no live LM server connection). Always false\r\nfor TitanCloud and for non-roaming Titan LM. Operator-facing\r\nsignal so dashboards can tell which path is in use."
          },
          "organization": {
            "type": "string",
            "description": "Company or organisation name from the license server.",
            "nullable": true,
            "example": "SPACE GASS PTY LTD"
          },
          "licenseId": {
            "type": "integer",
            "description": "License ID from the license server (the company registration number).",
            "format": "int32",
            "example": 9991111
          },
          "errorMessage": {
            "type": "string",
            "description": "Last error message when the license is not active; null otherwise.",
            "nullable": true
          },
          "isJobOpen": {
            "type": "boolean",
            "description": "Whether a job is currently open (Tier 2 SPACE GASS core held)."
          },
          "jobOpenedAt": {
            "type": "string",
            "description": "UTC timestamp when the current job was opened (and the SPACE GASS\r\nlicence seat became active), or `null` when no job is open.",
            "format": "date-time",
            "nullable": true
          },
          "activeModules": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Names of module licenses currently active for this API instance.",
            "nullable": true,
            "example": [
              "API",
              "Buckling analysis"
            ]
          },
          "entitlements": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Names of modules this company / user is entitled to (has purchased),\r\nwhether or not they are currently acquired. Analogous to the SPACE\r\nGASS desktop \"Help > About\" dialog's licensed-module list. Empty\r\nif the backend query failed (see SpaceGassApi.Models.Dtos.License.LicenseStatusDto.ErrorMessage).",
            "nullable": true,
            "example": [
              "API",
              "Plate element",
              "Buckling analysis"
            ]
          }
        },
        "additionalProperties": false,
        "description": "Full licensing status for the API instance.\r\nAccessible even when the API is unlicensed (whitelisted in middleware)\r\nso clients can diagnose why requests are being refused."
      },
      "LoadAxes": {
        "enum": [
          "Local",
          "GlobalInclined",
          "GlobalProjected"
        ],
        "type": "string",
        "description": "Coordinate axes type for distributed loads and plate pressure loads.\r\nMaps to SPACE GASS lookup table \"L/GI/GP Axes\"."
      },
      "LoadCase": {
        "required": [
          "id",
          "title"
        ],
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier - must be unique, no duplicates allowed.\r\nRange: 1 to int.MaxValue",
            "format": "int32",
            "example": 1
          },
          "title": {
            "minLength": 1,
            "type": "string",
            "description": "Load case title.",
            "example": "Dead Load"
          },
          "notes": {
            "type": "string",
            "description": "Load case notes (supports multi-line text).",
            "nullable": true,
            "example": "Self-weight of structural steel members"
          },
          "type": {
            "$ref": "#/components/schemas/LoadCaseType"
          },
          "hasCombinationItems": {
            "type": "boolean",
            "description": "True when this case has at least one combination item defined.\r\nOnly meaningful for cases where `Type` is `Combination`.\r\nUse `?expand=all` to include the full `combinationItems` array."
          },
          "combinationItems": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CombinationLoadCaseItem"
            },
            "description": "The combination items (component case + multiplying factor rows) that make up this case.\r\nPopulated only when `?expand=all` is passed AND `hasCombinationItems` is true;\r\nomitted from the wire otherwise.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for a load case (from Loads - Titles table, FileID=28).\r\nReturns all load cases including primary, combination, and step types.\r\nWhen `Type` is `Combination`, the case owns a list of combination items\r\n(hydrated inline via `?expand=all`)."
      },
      "LoadCaseBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LoadCase"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "LoadCaseCreate": {
        "required": [
          "title"
        ],
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier - must be unique, no duplicates allowed.\r\nOptional - will be auto-assigned to next available number if not provided.\r\nIf provided, must not already exist in the model.",
            "format": "int32",
            "nullable": true,
            "example": 1
          },
          "title": {
            "maxLength": 100,
            "minLength": 0,
            "type": "string",
            "description": "Load case title.",
            "example": "Dead Load"
          },
          "notes": {
            "maxLength": 2048,
            "minLength": 0,
            "type": "string",
            "description": "Load case notes (supports multi-line text).",
            "nullable": true,
            "example": "Self-weight of structural steel members"
          }
        },
        "additionalProperties": false,
        "description": "DTO for creating a new load case."
      },
      "LoadCaseGroup": {
        "required": [
          "id",
          "loadCaseList",
          "title"
        ],
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier - must be unique, no duplicates allowed.\r\nRange: 1 to int.MaxValue",
            "format": "int32",
            "example": 1
          },
          "title": {
            "minLength": 1,
            "type": "string",
            "description": "Group title."
          },
          "loadCaseList": {
            "minLength": 1,
            "type": "string",
            "description": "Comma-separated list of load case numbers and ranges (e.g., \"1,3,5-10\")."
          }
        },
        "additionalProperties": false,
        "description": "DTO for a load case group (from Loads - Load Case Groups table, FileID=39)."
      },
      "LoadCaseGroupBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LoadCaseGroup"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "LoadCaseGroupCreate": {
        "required": [
          "loadCaseList",
          "title"
        ],
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier - must be unique, no duplicates allowed.\r\nOptional - will be auto-assigned to next available number if not provided.\r\nIf provided, must not already exist in the model.",
            "format": "int32",
            "nullable": true,
            "example": 1
          },
          "title": {
            "maxLength": 100,
            "minLength": 0,
            "type": "string",
            "description": "Group title."
          },
          "loadCaseList": {
            "maxLength": 600,
            "minLength": 0,
            "pattern": "^[\\d,\\- ]+$",
            "type": "string",
            "description": "Comma-separated list of load case numbers and ranges (e.g., \"1,3,5-10\").\r\nValid characters: digits, commas, hyphens, spaces."
          }
        },
        "additionalProperties": false,
        "description": "DTO for creating a new load case group."
      },
      "LoadCaseGroupUpdate": {
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier of the entity to update.\r\nOptional for single updates (Id comes from route), required for bulk updates.",
            "format": "int32",
            "nullable": true,
            "example": 1
          },
          "title": {
            "maxLength": 100,
            "minLength": 0,
            "type": "string",
            "description": "Group title.",
            "nullable": true
          },
          "loadCaseList": {
            "maxLength": 600,
            "minLength": 0,
            "pattern": "^[\\d,\\- ]+$",
            "type": "string",
            "description": "Comma-separated list of load case numbers and ranges (e.g., \"1,3,5-10\").",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for updating an existing load case group.\r\nAll fields optional for partial updates."
      },
      "LoadCaseType": {
        "enum": [
          "Primary",
          "Combination",
          "Step",
          "Unused"
        ],
        "type": "string",
        "description": "Type of load case in the structural model.\r\nRead-only — computed internally by SPACE GASS based on assigned loads."
      },
      "LoadCaseUpdate": {
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier of the entity to update.\r\nOptional for single updates (Id comes from route), required for bulk updates.",
            "format": "int32",
            "nullable": true,
            "example": 1
          },
          "title": {
            "maxLength": 100,
            "minLength": 0,
            "type": "string",
            "description": "Load case title.",
            "nullable": true,
            "example": "Dead Load (revised)"
          },
          "notes": {
            "maxLength": 2048,
            "minLength": 0,
            "type": "string",
            "description": "Load case notes (supports multi-line text).",
            "nullable": true,
            "example": "Updated to include cladding self-weight"
          }
        },
        "additionalProperties": false,
        "description": "DTO for updating an existing load case.\r\nAll fields are optional to support partial updates."
      },
      "LoadCategory": {
        "required": [
          "id",
          "title"
        ],
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier - must be unique, no duplicates allowed.\r\nRange: 1 to int.MaxValue",
            "format": "int32",
            "example": 1
          },
          "title": {
            "minLength": 1,
            "type": "string",
            "description": "Category title."
          },
          "source": {
            "type": "string",
            "description": "Source (read-only, set automatically by the application).",
            "nullable": true
          },
          "version": {
            "type": "string",
            "description": "Version (read-only, set automatically by the application).",
            "nullable": true
          },
          "username": {
            "type": "string",
            "description": "Username (read-only, set automatically by the application).",
            "nullable": true
          },
          "notes": {
            "type": "string",
            "description": "Notes (supports multi-line text).",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A load category used to group load cases (e.g. dead, live, wind).\r\nIncludes read-only audit fields (Source, Version, Username) set automatically by the application."
      },
      "LoadCategoryBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LoadCategory"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "LoadCategoryCreate": {
        "required": [
          "title"
        ],
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier - must be unique, no duplicates allowed.\r\nOptional - will be auto-assigned to next available number if not provided.\r\nIf provided, must not already exist in the model.",
            "format": "int32",
            "nullable": true,
            "example": 1
          },
          "title": {
            "maxLength": 100,
            "minLength": 0,
            "type": "string",
            "description": "Category title."
          },
          "notes": {
            "maxLength": 2048,
            "minLength": 0,
            "type": "string",
            "description": "Notes (supports multi-line text).",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for creating a new load category.\r\nRead-only fields (Source, Version, Username) are excluded."
      },
      "LoadCategoryUpdate": {
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier of the entity to update.\r\nOptional for single updates (Id comes from route), required for bulk updates.",
            "format": "int32",
            "nullable": true,
            "example": 1
          },
          "title": {
            "maxLength": 100,
            "minLength": 0,
            "type": "string",
            "description": "Category title.",
            "nullable": true
          },
          "notes": {
            "maxLength": 2048,
            "minLength": 0,
            "type": "string",
            "description": "Notes (supports multi-line text).",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for updating an existing load category.\r\nAll fields optional for partial updates. Read-only fields excluded."
      },
      "LoadPositionUnits": {
        "enum": [
          "Actual",
          "Percent"
        ],
        "type": "string",
        "description": "Position units for member load placement along a member.\r\nMaps to SPACE GASS lookup table \"Load Units\"."
      },
      "LoadingType": {
        "enum": [
          "Full",
          "Residual"
        ],
        "type": "string",
        "description": "Loading type for non-linear static analysis.\r\nOnly used for non-linear static analysis."
      },
      "LumpedMassLoad": {
        "required": [
          "node"
        ],
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "The load case number this load belongs to.",
            "format": "int32"
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "node": {
            "type": "integer",
            "description": "The node number this lumped mass is applied to.",
            "format": "int32"
          },
          "tmx": {
            "type": "number",
            "description": "Translational mass in the global X direction.",
            "format": "double"
          },
          "tmy": {
            "type": "number",
            "description": "Translational mass in the global Y direction.",
            "format": "double"
          },
          "tmz": {
            "type": "number",
            "description": "Translational mass in the global Z direction.",
            "format": "double"
          },
          "rmx": {
            "type": "number",
            "description": "Rotational mass inertia about the global X axis.",
            "format": "double"
          },
          "rmy": {
            "type": "number",
            "description": "Rotational mass inertia about the global Y axis.",
            "format": "double"
          },
          "rmz": {
            "type": "number",
            "description": "Rotational mass inertia about the global Z axis.",
            "format": "double"
          }
        },
        "additionalProperties": false,
        "description": "DTO for reading a lumped mass load entity.\r\nRepresents a lumped mass and rotational inertia applied at a node."
      },
      "LumpedMassLoadBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LumpedMassLoad"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "LumpedMassLoadCreate": {
        "required": [
          "case",
          "node"
        ],
        "type": "object",
        "properties": {
          "case": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The load case number to create this load in.",
            "format": "int32"
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "node": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The node number to apply this lumped mass to.",
            "format": "int32"
          },
          "tmx": {
            "type": "number",
            "description": "Translational mass in the global X direction.",
            "format": "double",
            "nullable": true
          },
          "tmy": {
            "type": "number",
            "description": "Translational mass in the global Y direction.",
            "format": "double",
            "nullable": true
          },
          "tmz": {
            "type": "number",
            "description": "Translational mass in the global Z direction.",
            "format": "double",
            "nullable": true
          },
          "rmx": {
            "type": "number",
            "description": "Rotational mass inertia about the global X axis.",
            "format": "double",
            "nullable": true
          },
          "rmy": {
            "type": "number",
            "description": "Rotational mass inertia about the global Y axis.",
            "format": "double",
            "nullable": true
          },
          "rmz": {
            "type": "number",
            "description": "Rotational mass inertia about the global Z axis.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for creating a new lumped mass load."
      },
      "LumpedMassLoadKey": {
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "The load case number.",
            "format": "int32"
          },
          "node": {
            "type": "integer",
            "description": "The node number.",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Composite Id object for bulk delete operations."
      },
      "LumpedMassLoadKeyBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LumpedMassLoadKey"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "LumpedMassLoadUpdate": {
        "type": "object",
        "properties": {
          "case": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The load case number.",
            "format": "int32",
            "nullable": true
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "node": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The node number.",
            "format": "int32",
            "nullable": true
          },
          "tmx": {
            "type": "number",
            "description": "Translational mass in the global X direction.",
            "format": "double",
            "nullable": true
          },
          "tmy": {
            "type": "number",
            "description": "Translational mass in the global Y direction.",
            "format": "double",
            "nullable": true
          },
          "tmz": {
            "type": "number",
            "description": "Translational mass in the global Z direction.",
            "format": "double",
            "nullable": true
          },
          "rmx": {
            "type": "number",
            "description": "Rotational mass inertia about the global X axis.",
            "format": "double",
            "nullable": true
          },
          "rmy": {
            "type": "number",
            "description": "Rotational mass inertia about the global Y axis.",
            "format": "double",
            "nullable": true
          },
          "rmz": {
            "type": "number",
            "description": "Rotational mass inertia about the global Z axis.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for updating an existing lumped mass load.\r\nOnly fields included in the request are updated; omit a field to keep its current value."
      },
      "MassDensityUnit": {
        "enum": [
          "Kperft3",
          "Kperin3",
          "lbperft3",
          "lbperin3",
          "Tperm3",
          "Tpercm3",
          "Tpermm3",
          "kgperm3",
          "kgpercm3",
          "kgpermm3"
        ],
        "type": "string",
        "description": "Mass density unit. Members mirror SPACE GASS `SgMassDensity`."
      },
      "MassUnit": {
        "enum": [
          "K",
          "lb",
          "T",
          "kg"
        ],
        "type": "string",
        "description": "Mass unit. Members mirror SPACE GASS `SgMass`."
      },
      "Material": {
        "required": [
          "id"
        ],
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier - must be unique, no duplicates allowed.\r\nRange: 1 to int.MaxValue",
            "format": "int32",
            "example": 1
          },
          "name": {
            "type": "string",
            "description": "Material name.",
            "nullable": true
          },
          "youngsModulus": {
            "type": "number",
            "description": "Young's modulus.",
            "format": "double"
          },
          "poissonsRatio": {
            "type": "number",
            "description": "Poisson's ratio (unitless).",
            "format": "double"
          },
          "massDensity": {
            "type": "number",
            "description": "Mass density.",
            "format": "double"
          },
          "thermalCoeff": {
            "type": "number",
            "description": "Thermal expansion coefficient.",
            "format": "double"
          },
          "concreteStrength": {
            "type": "number",
            "description": "Concrete compressive strength.",
            "format": "double"
          },
          "source": {
            "$ref": "#/components/schemas/PropertySource"
          },
          "library": {
            "type": "string",
            "description": "Library name. Empty for user-defined materials.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for reading a material entity."
      },
      "MaterialBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Material"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "MaterialCreate": {
        "required": [
          "name"
        ],
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier - must be unique, no duplicates allowed.\r\nOptional - will be auto-assigned to next available number if not provided.\r\nIf provided, must not already exist in the model.",
            "format": "int32",
            "nullable": true,
            "example": 1
          },
          "name": {
            "minLength": 1,
            "type": "string",
            "description": "Material name."
          },
          "youngsModulus": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Young's modulus. Must be greater than zero.",
            "format": "double"
          },
          "poissonsRatio": {
            "type": "number",
            "description": "Poisson's ratio (unitless).",
            "format": "double"
          },
          "massDensity": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Mass density. Must be greater than zero.",
            "format": "double"
          },
          "thermalCoeff": {
            "type": "number",
            "description": "Thermal expansion coefficient.",
            "format": "double"
          },
          "concreteStrength": {
            "type": "number",
            "description": "Concrete compressive strength.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for creating a new user-defined material."
      },
      "MaterialLibraryCreate": {
        "required": [
          "library",
          "name"
        ],
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier - must be unique, no duplicates allowed.\r\nOptional - will be auto-assigned to next available number if not provided.\r\nIf provided, must not already exist in the model.",
            "format": "int32",
            "nullable": true,
            "example": 1
          },
          "name": {
            "minLength": 1,
            "type": "string",
            "description": "Material item name within the library.",
            "example": "Steel(AS)"
          },
          "library": {
            "minLength": 1,
            "type": "string",
            "description": "Library name.",
            "example": "AustralianMaterials"
          }
        },
        "additionalProperties": false,
        "description": "DTO for creating a new library-sourced material.\r\nAll material properties (Young's modulus, Poisson's ratio, etc.) are resolved from the\r\nlibrary — the caller provides only the material name and library."
      },
      "MaterialStrengthUnit": {
        "enum": [
          "Ksf",
          "Psf",
          "Ksi",
          "Psi",
          "MPa",
          "kPa",
          "Pa",
          "kgperm2",
          "kgpercm2",
          "kgpermm2"
        ],
        "type": "string",
        "description": "Material strength unit (yield stress, ultimate stress, etc.). Members mirror\r\nSPACE GASS `SgMaterialStrength`."
      },
      "MaterialUpdate": {
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier of the entity to update.\r\nOptional for single updates (Id comes from route), required for bulk updates.",
            "format": "int32",
            "nullable": true,
            "example": 1
          },
          "name": {
            "type": "string",
            "description": "Material name.",
            "nullable": true
          },
          "youngsModulus": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Young's modulus. Must be greater than zero if provided.",
            "format": "double",
            "nullable": true
          },
          "poissonsRatio": {
            "type": "number",
            "description": "Poisson's ratio (unitless).",
            "format": "double",
            "nullable": true
          },
          "massDensity": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Mass density. Must be greater than zero if provided.",
            "format": "double",
            "nullable": true
          },
          "thermalCoeff": {
            "type": "number",
            "description": "Thermal expansion coefficient.",
            "format": "double",
            "nullable": true
          },
          "concreteStrength": {
            "type": "number",
            "description": "Concrete compressive strength.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for updating an existing material.\r\nAll fields are optional to support partial updates."
      },
      "MatrixType": {
        "enum": [
          "Secant",
          "Tangent"
        ],
        "type": "string",
        "description": "Stiffness matrix type for non-linear static analysis.\r\nOnly used for non-linear static analysis."
      },
      "Member": {
        "required": [
          "id",
          "nodeA",
          "nodeB"
        ],
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier - must be unique, no duplicates allowed.\r\nRange: 1 to int.MaxValue",
            "format": "int32",
            "example": 1
          },
          "nodeA": {
            "type": "integer",
            "description": "Node at end A of the member.",
            "format": "int32"
          },
          "nodeB": {
            "type": "integer",
            "description": "Node at end B of the member.",
            "format": "int32"
          },
          "type": {
            "$ref": "#/components/schemas/MemberType"
          },
          "section": {
            "type": "integer",
            "description": "Section number assigned to this member.",
            "format": "int32"
          },
          "material": {
            "type": "integer",
            "description": "Material number assigned to this member.",
            "format": "int32"
          },
          "cableLength": {
            "type": "number",
            "description": "Cable length (for Cable type members). Unit: Length (see GET /job/units).",
            "format": "double"
          },
          "gapTensionLimit": {
            "type": "number",
            "description": "Gap tension limit (for Gap type members). Unit: Force (see GET /job/units).",
            "format": "double"
          },
          "gapCompressionLimit": {
            "type": "number",
            "description": "Gap compression limit (for Gap type members). Unit: Force (see GET /job/units).",
            "format": "double"
          },
          "fuseTensionLimit": {
            "type": "number",
            "description": "Fuse tension limit (for Fuse type members). Unit: Force (see GET /job/units).",
            "format": "double"
          },
          "fuseCompressionLimit": {
            "type": "number",
            "description": "Fuse compression limit (for Fuse type members). Unit: Force (see GET /job/units).",
            "format": "double"
          },
          "direction": {
            "$ref": "#/components/schemas/MemberDirection"
          },
          "releases": {
            "$ref": "#/components/schemas/MemberRelease"
          },
          "hasOffsets": {
            "type": "boolean",
            "description": "True when this member has an explicit offsets row defined (rigid end zones at A/B).\r\nFalse means the member has no offsets (end rigid zones zero).\r\nUse `?expand=all` to include the full `offsets` object."
          },
          "offsets": {
            "$ref": "#/components/schemas/MemberOffset"
          }
        },
        "additionalProperties": false,
        "description": "DTO for reading a member entity.\r\nReleases (fixity/stiffness at each end) are intrinsic member data and are always populated.\r\nOffsets (rigid end zones) are a linked sub-resource and are hydrated only when `?expand=all`."
      },
      "MemberBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Member"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "MemberConcentratedLoad": {
        "required": [
          "member",
          "subLoad"
        ],
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "The load case number this load belongs to.",
            "format": "int32"
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "member": {
            "type": "integer",
            "description": "The member number this load is applied to.",
            "format": "int32"
          },
          "subLoad": {
            "type": "integer",
            "description": "The auto-assigned sub-load number within the member+case combination.",
            "format": "int32"
          },
          "axes": {
            "$ref": "#/components/schemas/LoadAxes"
          },
          "positionUnits": {
            "$ref": "#/components/schemas/LoadPositionUnits"
          },
          "position": {
            "type": "number",
            "description": "Position of the load along the member.",
            "format": "double"
          },
          "fx": {
            "type": "number",
            "description": "Force in the local/global X direction.",
            "format": "double"
          },
          "fy": {
            "type": "number",
            "description": "Force in the local/global Y direction.",
            "format": "double"
          },
          "fz": {
            "type": "number",
            "description": "Force in the local/global Z direction.",
            "format": "double"
          },
          "mx": {
            "type": "number",
            "description": "Moment about the local/global X axis.",
            "format": "double"
          },
          "my": {
            "type": "number",
            "description": "Moment about the local/global Y axis.",
            "format": "double"
          },
          "mz": {
            "type": "number",
            "description": "Moment about the local/global Z axis.",
            "format": "double"
          }
        },
        "additionalProperties": false,
        "description": "DTO for reading a member concentrated load entity.\r\nRepresents a concentrated force or moment applied at a point along a member.\r\nComposite Id: (Case, Member, SubLoad)."
      },
      "MemberConcentratedLoadBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MemberConcentratedLoad"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "MemberConcentratedLoadCreate": {
        "required": [
          "case",
          "member"
        ],
        "type": "object",
        "properties": {
          "case": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The load case number to create this load in.",
            "format": "int32"
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "member": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The member number to apply this load to.",
            "format": "int32"
          },
          "axes": {
            "$ref": "#/components/schemas/LoadAxes"
          },
          "positionUnits": {
            "$ref": "#/components/schemas/LoadPositionUnits"
          },
          "position": {
            "type": "number",
            "description": "Position of the load along the member.",
            "format": "double",
            "nullable": true
          },
          "fx": {
            "type": "number",
            "description": "Force in the local/global X direction.",
            "format": "double",
            "nullable": true
          },
          "fy": {
            "type": "number",
            "description": "Force in the local/global Y direction.",
            "format": "double",
            "nullable": true
          },
          "fz": {
            "type": "number",
            "description": "Force in the local/global Z direction.",
            "format": "double",
            "nullable": true
          },
          "mx": {
            "type": "number",
            "description": "Moment about the local/global X axis.",
            "format": "double",
            "nullable": true
          },
          "my": {
            "type": "number",
            "description": "Moment about the local/global Y axis.",
            "format": "double",
            "nullable": true
          },
          "mz": {
            "type": "number",
            "description": "Moment about the local/global Z axis.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for creating a new member concentrated load.\r\nThe sub-load number is auto-assigned — do not include it in the request."
      },
      "MemberConcentratedLoadKey": {
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "The load case number.",
            "format": "int32"
          },
          "member": {
            "type": "integer",
            "description": "The member number.",
            "format": "int32"
          },
          "subLoad": {
            "type": "integer",
            "description": "The sub-load number.",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Composite Id object for bulk delete operations on member concentrated loads."
      },
      "MemberConcentratedLoadKeyBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MemberConcentratedLoadKey"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "MemberConcentratedLoadUpdate": {
        "type": "object",
        "properties": {
          "case": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The load case number.",
            "format": "int32",
            "nullable": true
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "member": {
            "type": "integer",
            "description": "The member number.",
            "format": "int32",
            "nullable": true
          },
          "subLoad": {
            "type": "integer",
            "description": "The sub-load number.",
            "format": "int32",
            "nullable": true
          },
          "axes": {
            "$ref": "#/components/schemas/LoadAxes"
          },
          "positionUnits": {
            "$ref": "#/components/schemas/LoadPositionUnits"
          },
          "position": {
            "type": "number",
            "description": "Position of the load along the member.",
            "format": "double",
            "nullable": true
          },
          "fx": {
            "type": "number",
            "description": "Force in the local/global X direction.",
            "format": "double",
            "nullable": true
          },
          "fy": {
            "type": "number",
            "description": "Force in the local/global Y direction.",
            "format": "double",
            "nullable": true
          },
          "fz": {
            "type": "number",
            "description": "Force in the local/global Z direction.",
            "format": "double",
            "nullable": true
          },
          "mx": {
            "type": "number",
            "description": "Moment about the local/global X axis.",
            "format": "double",
            "nullable": true
          },
          "my": {
            "type": "number",
            "description": "Moment about the local/global Y axis.",
            "format": "double",
            "nullable": true
          },
          "mz": {
            "type": "number",
            "description": "Moment about the local/global Z axis.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for updating an existing member concentrated load.\r\nOnly fields included in the request are updated; omit a field to keep its current value."
      },
      "MemberCreate": {
        "required": [
          "nodeA",
          "nodeB"
        ],
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier - must be unique, no duplicates allowed.\r\nOptional - will be auto-assigned to next available number if not provided.\r\nIf provided, must not already exist in the model.",
            "format": "int32",
            "nullable": true,
            "example": 1
          },
          "nodeA": {
            "type": "integer",
            "description": "Node at end A of the member.",
            "format": "int32"
          },
          "nodeB": {
            "type": "integer",
            "description": "Node at end B of the member.",
            "format": "int32"
          },
          "type": {
            "$ref": "#/components/schemas/MemberType"
          },
          "section": {
            "type": "integer",
            "description": "Section number assigned to this member.",
            "format": "int32",
            "nullable": true
          },
          "material": {
            "type": "integer",
            "description": "Material number assigned to this member.",
            "format": "int32",
            "nullable": true
          },
          "direction": {
            "$ref": "#/components/schemas/DirectionUpdate"
          },
          "cableLength": {
            "type": "number",
            "description": "Cable length (for Cable type members). Unit: Length (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "gapTensionLimit": {
            "type": "number",
            "description": "Gap tension limit (for Gap type members). Unit: Force (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "gapCompressionLimit": {
            "type": "number",
            "description": "Gap compression limit (for Gap type members). Unit: Force (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "fuseTensionLimit": {
            "type": "number",
            "description": "Fuse tension limit (for Fuse type members). Unit: Force (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "fuseCompressionLimit": {
            "type": "number",
            "description": "Fuse compression limit (for Fuse type members). Unit: Force (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "releases": {
            "$ref": "#/components/schemas/MemberReleaseUpdate"
          }
        },
        "additionalProperties": false,
        "description": "DTO for creating a new member.\r\nNodeA and NodeB are required; all other fields are optional."
      },
      "MemberDirection": {
        "type": "object",
        "properties": {
          "source": {
            "$ref": "#/components/schemas/DirectionSource"
          },
          "dirAngle": {
            "type": "number",
            "description": "Direction angle for member orientation.",
            "format": "double"
          },
          "dirNode": {
            "type": "integer",
            "description": "Direction node for member orientation.",
            "format": "int32"
          },
          "dirAxis": {
            "$ref": "#/components/schemas/DirectionAxis"
          }
        },
        "additionalProperties": false,
        "description": "DTO for reading member direction data.\r\nDirection defines the orientation of the member's local coordinate system.\r\nAlways present on every member — the parent MemberDto's `id` is authoritative."
      },
      "MemberDistributedLoad": {
        "required": [
          "member",
          "subLoad"
        ],
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "The load case number this load belongs to.",
            "format": "int32"
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "member": {
            "type": "integer",
            "description": "The member number this load is applied to.",
            "format": "int32"
          },
          "subLoad": {
            "type": "integer",
            "description": "The auto-assigned sub-load number within the member+case combination.",
            "format": "int32"
          },
          "axes": {
            "$ref": "#/components/schemas/LoadAxes"
          },
          "positionUnits": {
            "$ref": "#/components/schemas/LoadPositionUnits"
          },
          "startPosition": {
            "type": "number",
            "description": "Start position of the distributed load along the member.",
            "format": "double"
          },
          "finishPosition": {
            "type": "number",
            "description": "Finish position of the distributed load along the member.",
            "format": "double"
          },
          "fxStart": {
            "type": "number",
            "description": "Distributed force intensity in X direction at the start position.",
            "format": "double"
          },
          "fxFinish": {
            "type": "number",
            "description": "Distributed force intensity in X direction at the finish position.",
            "format": "double"
          },
          "fyStart": {
            "type": "number",
            "description": "Distributed force intensity in Y direction at the start position.",
            "format": "double"
          },
          "fyFinish": {
            "type": "number",
            "description": "Distributed force intensity in Y direction at the finish position.",
            "format": "double"
          },
          "fzStart": {
            "type": "number",
            "description": "Distributed force intensity in Z direction at the start position.",
            "format": "double"
          },
          "fzFinish": {
            "type": "number",
            "description": "Distributed force intensity in Z direction at the finish position.",
            "format": "double"
          }
        },
        "additionalProperties": false,
        "description": "DTO for reading a member distributed load entity.\r\nRepresents distributed forces applied along a member.\r\nComposite Id: (Case, Member, SubLoad)."
      },
      "MemberDistributedLoadBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MemberDistributedLoad"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "MemberDistributedLoadCreate": {
        "required": [
          "case",
          "member"
        ],
        "type": "object",
        "properties": {
          "case": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The load case number to create this load in.",
            "format": "int32"
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "member": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The member number to apply this load to.",
            "format": "int32"
          },
          "axes": {
            "$ref": "#/components/schemas/LoadAxes"
          },
          "positionUnits": {
            "$ref": "#/components/schemas/LoadPositionUnits"
          },
          "startPosition": {
            "type": "number",
            "description": "Start position of the distributed load along the member.",
            "format": "double",
            "nullable": true
          },
          "finishPosition": {
            "type": "number",
            "description": "Finish position of the distributed load along the member.",
            "format": "double",
            "nullable": true
          },
          "fxStart": {
            "type": "number",
            "description": "Distributed force intensity in X direction at the start position.",
            "format": "double",
            "nullable": true
          },
          "fxFinish": {
            "type": "number",
            "description": "Distributed force intensity in X direction at the finish position.",
            "format": "double",
            "nullable": true
          },
          "fyStart": {
            "type": "number",
            "description": "Distributed force intensity in Y direction at the start position.",
            "format": "double",
            "nullable": true
          },
          "fyFinish": {
            "type": "number",
            "description": "Distributed force intensity in Y direction at the finish position.",
            "format": "double",
            "nullable": true
          },
          "fzStart": {
            "type": "number",
            "description": "Distributed force intensity in Z direction at the start position.",
            "format": "double",
            "nullable": true
          },
          "fzFinish": {
            "type": "number",
            "description": "Distributed force intensity in Z direction at the finish position.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for creating a new member distributed load.\r\nThe sub-load number is auto-assigned — do not include it in the request."
      },
      "MemberDistributedLoadKey": {
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "The load case number.",
            "format": "int32"
          },
          "member": {
            "type": "integer",
            "description": "The member number.",
            "format": "int32"
          },
          "subLoad": {
            "type": "integer",
            "description": "The sub-load number.",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Composite Id object for bulk delete operations on member distributed loads."
      },
      "MemberDistributedLoadKeyBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MemberDistributedLoadKey"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "MemberDistributedLoadUpdate": {
        "type": "object",
        "properties": {
          "case": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The load case number.",
            "format": "int32",
            "nullable": true
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "member": {
            "type": "integer",
            "description": "The member number.",
            "format": "int32",
            "nullable": true
          },
          "subLoad": {
            "type": "integer",
            "description": "The sub-load number.",
            "format": "int32",
            "nullable": true
          },
          "axes": {
            "$ref": "#/components/schemas/LoadAxes"
          },
          "positionUnits": {
            "$ref": "#/components/schemas/LoadPositionUnits"
          },
          "startPosition": {
            "type": "number",
            "description": "Start position of the distributed load along the member.",
            "format": "double",
            "nullable": true
          },
          "finishPosition": {
            "type": "number",
            "description": "Finish position of the distributed load along the member.",
            "format": "double",
            "nullable": true
          },
          "fxStart": {
            "type": "number",
            "description": "Distributed force intensity in X direction at the start position.",
            "format": "double",
            "nullable": true
          },
          "fxFinish": {
            "type": "number",
            "description": "Distributed force intensity in X direction at the finish position.",
            "format": "double",
            "nullable": true
          },
          "fyStart": {
            "type": "number",
            "description": "Distributed force intensity in Y direction at the start position.",
            "format": "double",
            "nullable": true
          },
          "fyFinish": {
            "type": "number",
            "description": "Distributed force intensity in Y direction at the finish position.",
            "format": "double",
            "nullable": true
          },
          "fzStart": {
            "type": "number",
            "description": "Distributed force intensity in Z direction at the start position.",
            "format": "double",
            "nullable": true
          },
          "fzFinish": {
            "type": "number",
            "description": "Distributed force intensity in Z direction at the finish position.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for updating an existing member distributed load.\r\nOnly fields included in the request are updated; omit a field to keep its current value."
      },
      "MemberDistributedMoment": {
        "required": [
          "member",
          "subLoad"
        ],
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "The load case number this load belongs to.",
            "format": "int32"
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "member": {
            "type": "integer",
            "description": "The member number this load is applied to.",
            "format": "int32"
          },
          "subLoad": {
            "type": "integer",
            "description": "The auto-assigned sub-load number within the member+case combination.",
            "format": "int32"
          },
          "axes": {
            "$ref": "#/components/schemas/LoadAxes"
          },
          "positionUnits": {
            "$ref": "#/components/schemas/LoadPositionUnits"
          },
          "startPosition": {
            "type": "number",
            "description": "Start position of the distributed moment along the member.",
            "format": "double"
          },
          "finishPosition": {
            "type": "number",
            "description": "Finish position of the distributed moment along the member.",
            "format": "double"
          },
          "mxStart": {
            "type": "number",
            "description": "Distributed moment intensity about X axis at the start position.",
            "format": "double"
          },
          "mxFinish": {
            "type": "number",
            "description": "Distributed moment intensity about X axis at the finish position.",
            "format": "double"
          },
          "myStart": {
            "type": "number",
            "description": "Distributed moment intensity about Y axis at the start position.",
            "format": "double"
          },
          "myFinish": {
            "type": "number",
            "description": "Distributed moment intensity about Y axis at the finish position.",
            "format": "double"
          },
          "mzStart": {
            "type": "number",
            "description": "Distributed moment intensity about Z axis at the start position.",
            "format": "double"
          },
          "mzFinish": {
            "type": "number",
            "description": "Distributed moment intensity about Z axis at the finish position.",
            "format": "double"
          }
        },
        "additionalProperties": false,
        "description": "DTO for reading a member distributed moment entity.\r\nRepresents distributed moments applied along a member.\r\nComposite Id: (Case, Member, SubLoad)."
      },
      "MemberDistributedMomentBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MemberDistributedMoment"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "MemberDistributedMomentCreate": {
        "required": [
          "case",
          "member"
        ],
        "type": "object",
        "properties": {
          "case": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The load case number to create this load in.",
            "format": "int32"
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "member": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The member number to apply this load to.",
            "format": "int32"
          },
          "axes": {
            "$ref": "#/components/schemas/LoadAxes"
          },
          "positionUnits": {
            "$ref": "#/components/schemas/LoadPositionUnits"
          },
          "startPosition": {
            "type": "number",
            "description": "Start position of the distributed moment along the member.",
            "format": "double",
            "nullable": true
          },
          "finishPosition": {
            "type": "number",
            "description": "Finish position of the distributed moment along the member.",
            "format": "double",
            "nullable": true
          },
          "mxStart": {
            "type": "number",
            "description": "Distributed moment intensity about X axis at the start position.",
            "format": "double",
            "nullable": true
          },
          "mxFinish": {
            "type": "number",
            "description": "Distributed moment intensity about X axis at the finish position.",
            "format": "double",
            "nullable": true
          },
          "myStart": {
            "type": "number",
            "description": "Distributed moment intensity about Y axis at the start position.",
            "format": "double",
            "nullable": true
          },
          "myFinish": {
            "type": "number",
            "description": "Distributed moment intensity about Y axis at the finish position.",
            "format": "double",
            "nullable": true
          },
          "mzStart": {
            "type": "number",
            "description": "Distributed moment intensity about Z axis at the start position.",
            "format": "double",
            "nullable": true
          },
          "mzFinish": {
            "type": "number",
            "description": "Distributed moment intensity about Z axis at the finish position.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for creating a new member distributed moment.\r\nThe sub-load number is auto-assigned — do not include it in the request."
      },
      "MemberDistributedMomentKey": {
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "The load case number.",
            "format": "int32"
          },
          "member": {
            "type": "integer",
            "description": "The member number.",
            "format": "int32"
          },
          "subLoad": {
            "type": "integer",
            "description": "The sub-load number.",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Composite Id object for bulk delete operations on member distributed moments."
      },
      "MemberDistributedMomentKeyBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MemberDistributedMomentKey"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "MemberDistributedMomentUpdate": {
        "type": "object",
        "properties": {
          "case": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The load case number.",
            "format": "int32",
            "nullable": true
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "member": {
            "type": "integer",
            "description": "The member number.",
            "format": "int32",
            "nullable": true
          },
          "subLoad": {
            "type": "integer",
            "description": "The sub-load number.",
            "format": "int32",
            "nullable": true
          },
          "axes": {
            "$ref": "#/components/schemas/LoadAxes"
          },
          "positionUnits": {
            "$ref": "#/components/schemas/LoadPositionUnits"
          },
          "startPosition": {
            "type": "number",
            "description": "Start position of the distributed moment along the member.",
            "format": "double",
            "nullable": true
          },
          "finishPosition": {
            "type": "number",
            "description": "Finish position of the distributed moment along the member.",
            "format": "double",
            "nullable": true
          },
          "mxStart": {
            "type": "number",
            "description": "Distributed moment intensity about X axis at the start position.",
            "format": "double",
            "nullable": true
          },
          "mxFinish": {
            "type": "number",
            "description": "Distributed moment intensity about X axis at the finish position.",
            "format": "double",
            "nullable": true
          },
          "myStart": {
            "type": "number",
            "description": "Distributed moment intensity about Y axis at the start position.",
            "format": "double",
            "nullable": true
          },
          "myFinish": {
            "type": "number",
            "description": "Distributed moment intensity about Y axis at the finish position.",
            "format": "double",
            "nullable": true
          },
          "mzStart": {
            "type": "number",
            "description": "Distributed moment intensity about Z axis at the start position.",
            "format": "double",
            "nullable": true
          },
          "mzFinish": {
            "type": "number",
            "description": "Distributed moment intensity about Z axis at the finish position.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for updating an existing member distributed moment.\r\nOnly fields included in the request are updated; omit a field to keep its current value."
      },
      "MemberEndForce": {
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "Load case ID.",
            "format": "int32"
          },
          "member": {
            "type": "integer",
            "description": "Member key.",
            "format": "int32"
          },
          "node": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int32"
            },
            "description": "Node keys at start and end of member.",
            "nullable": true
          },
          "fx": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Axial force at each node. Unit: Force (see GET /job/units).",
            "nullable": true
          },
          "fy": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Shear force in Y at each node. Unit: Force (see GET /job/units).",
            "nullable": true
          },
          "fz": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Shear force in Z at each node. Unit: Force (see GET /job/units).",
            "nullable": true
          },
          "mx": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Torsion moment at each node. Unit: Moment (see GET /job/units).",
            "nullable": true
          },
          "my": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Bending moment about Y at each node. Unit: Moment (see GET /job/units).",
            "nullable": true
          },
          "mz": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Bending moment about Z at each node. Unit: Moment (see GET /job/units).",
            "nullable": true
          },
          "finalCableLength": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Final cable length at each node. Unit: Length (see GET /job/units).",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Member end force results grouped by load case and member.\r\nColumnar arrays hold force values at each node (start/end)."
      },
      "MemberEndForceQueryResult": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MemberEndForce"
            },
            "description": "The query result rows.",
            "nullable": true
          },
          "warnings": {
            "$ref": "#/components/schemas/QueryWarnings"
          }
        },
        "additionalProperties": false,
        "description": "Wrapper for analysis query results.\r\nContains the result data plus optional warnings about requested cases or modes\r\nthat produced no results (i.e. were not analysed)."
      },
      "MemberIntermediateDisplacement": {
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "Load case ID.",
            "format": "int32"
          },
          "member": {
            "type": "integer",
            "description": "Member key.",
            "format": "int32"
          },
          "station": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int32"
            },
            "description": "Station index at each output point.",
            "nullable": true
          },
          "location": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Distance along member at each station. Unit: Length (see GET /job/units).",
            "nullable": true
          },
          "txGlobal": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Global translational X displacement at each station. Unit: Translation (see GET /job/units).",
            "nullable": true
          },
          "tyGlobal": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Global translational Y displacement at each station. Unit: Translation (see GET /job/units).",
            "nullable": true
          },
          "tzGlobal": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Global translational Z displacement at each station. Unit: Translation (see GET /job/units).",
            "nullable": true
          },
          "txLocal": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Local translational X displacement at each station. Unit: Translation (see GET /job/units).",
            "nullable": true
          },
          "tyLocal": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Local translational Y displacement at each station. Unit: Translation (see GET /job/units).",
            "nullable": true
          },
          "tzLocal": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Local translational Z displacement at each station. Unit: Translation (see GET /job/units).",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Member intermediate displacement results grouped by load case and member.\r\nColumnar arrays hold displacement values at each station along the member."
      },
      "MemberIntermediateDisplacementQueryResult": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MemberIntermediateDisplacement"
            },
            "description": "The query result rows.",
            "nullable": true
          },
          "warnings": {
            "$ref": "#/components/schemas/QueryWarnings"
          }
        },
        "additionalProperties": false,
        "description": "Wrapper for analysis query results.\r\nContains the result data plus optional warnings about requested cases or modes\r\nthat produced no results (i.e. were not analysed)."
      },
      "MemberIntermediateForce": {
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "Load case ID.",
            "format": "int32"
          },
          "member": {
            "type": "integer",
            "description": "Member key.",
            "format": "int32"
          },
          "station": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int32"
            },
            "description": "Station index at each output point.",
            "nullable": true
          },
          "location": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Distance along member at each station. Unit: Length (see GET /job/units).",
            "nullable": true
          },
          "fx": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Axial force at each station. Unit: Force (see GET /job/units).",
            "nullable": true
          },
          "fy": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Shear force in Y at each station. Unit: Force (see GET /job/units).",
            "nullable": true
          },
          "fz": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Shear force in Z at each station. Unit: Force (see GET /job/units).",
            "nullable": true
          },
          "mx": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Torsion moment at each station. Unit: Moment (see GET /job/units).",
            "nullable": true
          },
          "my": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Bending moment about Y at each station. Unit: Moment (see GET /job/units).",
            "nullable": true
          },
          "mz": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Bending moment about Z at each station. Unit: Moment (see GET /job/units).",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Member intermediate force results grouped by load case and member.\r\nColumnar arrays hold force values at each station along the member."
      },
      "MemberIntermediateForceQueryResult": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MemberIntermediateForce"
            },
            "description": "The query result rows.",
            "nullable": true
          },
          "warnings": {
            "$ref": "#/components/schemas/QueryWarnings"
          }
        },
        "additionalProperties": false,
        "description": "Wrapper for analysis query results.\r\nContains the result data plus optional warnings about requested cases or modes\r\nthat produced no results (i.e. were not analysed)."
      },
      "MemberOffset": {
        "type": "object",
        "properties": {
          "member": {
            "type": "integer",
            "description": "The member Id this offset applies to.",
            "format": "int32"
          },
          "axes": {
            "$ref": "#/components/schemas/AxesType"
          },
          "xOffsetAtA": {
            "type": "number",
            "description": "X offset at end A. Unit: Length (see GET /job/units).",
            "format": "double"
          },
          "yOffsetAtA": {
            "type": "number",
            "description": "Y offset at end A. Unit: Length (see GET /job/units).",
            "format": "double"
          },
          "zOffsetAtA": {
            "type": "number",
            "description": "Z offset at end A. Unit: Length (see GET /job/units).",
            "format": "double"
          },
          "xOffsetAtB": {
            "type": "number",
            "description": "X offset at end B. Unit: Length (see GET /job/units).",
            "format": "double"
          },
          "yOffsetAtB": {
            "type": "number",
            "description": "Y offset at end B. Unit: Length (see GET /job/units).",
            "format": "double"
          },
          "zOffsetAtB": {
            "type": "number",
            "description": "Z offset at end B. Unit: Length (see GET /job/units).",
            "format": "double"
          }
        },
        "additionalProperties": false,
        "description": "DTO for reading member offset data.\r\nOffsets define rigid end zones at each end of a member.\r\nTop-level entity attribute keyed on the parent member."
      },
      "MemberOffsetBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MemberOffset"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "MemberOffsetCreate": {
        "required": [
          "member"
        ],
        "type": "object",
        "properties": {
          "member": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The member Id to create the offset for. Required in the request body.",
            "format": "int32"
          },
          "axes": {
            "$ref": "#/components/schemas/AxesType"
          },
          "xOffsetAtA": {
            "type": "number",
            "description": "X offset at end A. Unit: Length (see GET /job/units).",
            "format": "double"
          },
          "yOffsetAtA": {
            "type": "number",
            "description": "Y offset at end A. Unit: Length (see GET /job/units).",
            "format": "double"
          },
          "zOffsetAtA": {
            "type": "number",
            "description": "Z offset at end A. Unit: Length (see GET /job/units).",
            "format": "double"
          },
          "xOffsetAtB": {
            "type": "number",
            "description": "X offset at end B. Unit: Length (see GET /job/units).",
            "format": "double"
          },
          "yOffsetAtB": {
            "type": "number",
            "description": "Y offset at end B. Unit: Length (see GET /job/units).",
            "format": "double"
          },
          "zOffsetAtB": {
            "type": "number",
            "description": "Z offset at end B. Unit: Length (see GET /job/units).",
            "format": "double"
          }
        },
        "additionalProperties": false,
        "description": "DTO for creating member offsets. POST is entity-style: 409 if offsets already exist\r\nfor the supplied member — caller must DELETE first or PATCH instead."
      },
      "MemberOffsetUpdate": {
        "type": "object",
        "properties": {
          "member": {
            "type": "integer",
            "description": "The member Id whose offset is being updated.\r\nRequired for bulk PATCH; ignored for single-member PATCH (route value wins).",
            "format": "int32",
            "nullable": true
          },
          "axes": {
            "$ref": "#/components/schemas/AxesType"
          },
          "xOffsetAtA": {
            "type": "number",
            "description": "X offset at end A. Unit: Length (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "yOffsetAtA": {
            "type": "number",
            "description": "Y offset at end A. Unit: Length (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "zOffsetAtA": {
            "type": "number",
            "description": "Z offset at end A. Unit: Length (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "xOffsetAtB": {
            "type": "number",
            "description": "X offset at end B. Unit: Length (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "yOffsetAtB": {
            "type": "number",
            "description": "Y offset at end B. Unit: Length (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "zOffsetAtB": {
            "type": "number",
            "description": "Z offset at end B. Unit: Length (see GET /job/units).",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for partial updates to a member offset.\r\nOnly fields included in the request are updated; omit a field to keep its current value."
      },
      "MemberPrestressLoad": {
        "required": [
          "member"
        ],
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "The load case number this load belongs to.",
            "format": "int32"
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "member": {
            "type": "integer",
            "description": "The member number this prestress is applied to.",
            "format": "int32"
          },
          "prestress": {
            "type": "number",
            "description": "Prestress force applied to the member.",
            "format": "double"
          }
        },
        "additionalProperties": false,
        "description": "DTO for reading a member prestress load entity.\r\nRepresents a prestress force applied to a member."
      },
      "MemberPrestressLoadBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MemberPrestressLoad"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "MemberPrestressLoadCreate": {
        "required": [
          "case",
          "member"
        ],
        "type": "object",
        "properties": {
          "case": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The load case number to create this load in.",
            "format": "int32"
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "member": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The member number to apply this prestress to.",
            "format": "int32"
          },
          "prestress": {
            "type": "number",
            "description": "Prestress force applied to the member.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for creating a new member prestress load."
      },
      "MemberPrestressLoadKey": {
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "The load case number.",
            "format": "int32"
          },
          "member": {
            "type": "integer",
            "description": "The member number.",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Composite Id object for bulk delete operations."
      },
      "MemberPrestressLoadKeyBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MemberPrestressLoadKey"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "MemberPrestressLoadUpdate": {
        "type": "object",
        "properties": {
          "case": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The load case number.",
            "format": "int32",
            "nullable": true
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "member": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The member number.",
            "format": "int32",
            "nullable": true
          },
          "prestress": {
            "type": "number",
            "description": "Prestress force applied to the member.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for updating an existing member prestress load.\r\nOnly fields included in the request are updated; omit a field to keep its current value."
      },
      "MemberRelease": {
        "type": "object",
        "properties": {
          "fixityCodeAtA": {
            "type": "string",
            "description": "Fixity code at end A of the member.",
            "nullable": true
          },
          "fixityCodeAtB": {
            "type": "string",
            "description": "Fixity code at end B of the member.",
            "nullable": true
          },
          "txStiffnessAtA": {
            "type": "number",
            "description": "Translational X spring stiffness at end A. Unit: Force/Length (see GET /job/units).",
            "format": "double"
          },
          "tyStiffnessAtA": {
            "type": "number",
            "description": "Translational Y spring stiffness at end A. Unit: Force/Length (see GET /job/units).",
            "format": "double"
          },
          "tzStiffnessAtA": {
            "type": "number",
            "description": "Translational Z spring stiffness at end A. Unit: Force/Length (see GET /job/units).",
            "format": "double"
          },
          "rxStiffnessAtA": {
            "type": "number",
            "description": "Rotational X spring stiffness at end A. Unit: Moment/Radian (see GET /job/units).",
            "format": "double"
          },
          "ryStiffnessAtA": {
            "type": "number",
            "description": "Rotational Y spring stiffness at end A. Unit: Moment/Radian (see GET /job/units).",
            "format": "double"
          },
          "rzStiffnessAtA": {
            "type": "number",
            "description": "Rotational Z spring stiffness at end A. Unit: Moment/Radian (see GET /job/units).",
            "format": "double"
          },
          "txStiffnessAtB": {
            "type": "number",
            "description": "Translational X spring stiffness at end B. Unit: Force/Length (see GET /job/units).",
            "format": "double"
          },
          "tyStiffnessAtB": {
            "type": "number",
            "description": "Translational Y spring stiffness at end B. Unit: Force/Length (see GET /job/units).",
            "format": "double"
          },
          "tzStiffnessAtB": {
            "type": "number",
            "description": "Translational Z spring stiffness at end B. Unit: Force/Length (see GET /job/units).",
            "format": "double"
          },
          "rxStiffnessAtB": {
            "type": "number",
            "description": "Rotational X spring stiffness at end B. Unit: Moment/Radian (see GET /job/units).",
            "format": "double"
          },
          "ryStiffnessAtB": {
            "type": "number",
            "description": "Rotational Y spring stiffness at end B. Unit: Moment/Radian (see GET /job/units).",
            "format": "double"
          },
          "rzStiffnessAtB": {
            "type": "number",
            "description": "Rotational Z spring stiffness at end B. Unit: Moment/Radian (see GET /job/units).",
            "format": "double"
          }
        },
        "additionalProperties": false,
        "description": "DTO for reading member release data.\r\nReleases define fixity codes and spring stiffness at each end of a member.\r\nAlways present on every member, so the owning member Id\r\nis not duplicated here — the parent MemberDto's `id` is authoritative when\r\nreturned inline, and the route parameter is authoritative on the standalone endpoint."
      },
      "MemberReleaseUpdate": {
        "type": "object",
        "properties": {
          "fixityCodeAtA": {
            "type": "string",
            "description": "Fixity code at end A of the member.",
            "nullable": true
          },
          "fixityCodeAtB": {
            "type": "string",
            "description": "Fixity code at end B of the member.",
            "nullable": true
          },
          "txStiffnessAtA": {
            "type": "number",
            "description": "Translational X spring stiffness at end A. Unit: Force/Length (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "tyStiffnessAtA": {
            "type": "number",
            "description": "Translational Y spring stiffness at end A. Unit: Force/Length (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "tzStiffnessAtA": {
            "type": "number",
            "description": "Translational Z spring stiffness at end A. Unit: Force/Length (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "rxStiffnessAtA": {
            "type": "number",
            "description": "Rotational X spring stiffness at end A. Unit: Moment/Radian (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "ryStiffnessAtA": {
            "type": "number",
            "description": "Rotational Y spring stiffness at end A. Unit: Moment/Radian (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "rzStiffnessAtA": {
            "type": "number",
            "description": "Rotational Z spring stiffness at end A. Unit: Moment/Radian (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "txStiffnessAtB": {
            "type": "number",
            "description": "Translational X spring stiffness at end B. Unit: Force/Length (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "tyStiffnessAtB": {
            "type": "number",
            "description": "Translational Y spring stiffness at end B. Unit: Force/Length (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "tzStiffnessAtB": {
            "type": "number",
            "description": "Translational Z spring stiffness at end B. Unit: Force/Length (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "rxStiffnessAtB": {
            "type": "number",
            "description": "Rotational X spring stiffness at end B. Unit: Moment/Radian (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "ryStiffnessAtB": {
            "type": "number",
            "description": "Rotational Y spring stiffness at end B. Unit: Moment/Radian (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "rzStiffnessAtB": {
            "type": "number",
            "description": "Rotational Z spring stiffness at end B. Unit: Moment/Radian (see GET /job/units).",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for partial updates to a member release.\r\nOnly fields included in the request are updated; omit a field to keep its current value."
      },
      "MemberStress": {
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "Load case ID.",
            "format": "int32"
          },
          "member": {
            "type": "integer",
            "description": "Member key.",
            "format": "int32"
          },
          "station": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int32"
            },
            "description": "Station index at each output point.",
            "nullable": true
          },
          "position": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Fractional position along member (0.0 to 1.0).",
            "nullable": true
          },
          "n": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Axial stress at each station. Unit: Stress (see GET /job/units).",
            "nullable": true
          },
          "vy": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Shear stress in Y at each station. Unit: Stress (see GET /job/units).",
            "nullable": true
          },
          "vz": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Shear stress in Z at each station. Unit: Stress (see GET /job/units).",
            "nullable": true
          },
          "mx": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Torsion stress at each station. Unit: Stress (see GET /job/units).",
            "nullable": true
          },
          "myTop": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Bending stress about Y (top fibre) at each station. Unit: Stress (see GET /job/units).",
            "nullable": true
          },
          "myBtm": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Bending stress about Y (bottom fibre) at each station. Unit: Stress (see GET /job/units).",
            "nullable": true
          },
          "mzTop": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Bending stress about Z (top fibre) at each station. Unit: Stress (see GET /job/units).",
            "nullable": true
          },
          "mzBtm": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Bending stress about Z (bottom fibre) at each station. Unit: Stress (see GET /job/units).",
            "nullable": true
          },
          "nMyTop": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Combined axial + My stress (top fibre) at each station. Unit: Stress (see GET /job/units).",
            "nullable": true
          },
          "nMyBtm": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Combined axial + My stress (bottom fibre) at each station. Unit: Stress (see GET /job/units).",
            "nullable": true
          },
          "nMzTop": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Combined axial + Mz stress (top fibre) at each station. Unit: Stress (see GET /job/units).",
            "nullable": true
          },
          "nMzBtm": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Combined axial + Mz stress (bottom fibre) at each station. Unit: Stress (see GET /job/units).",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Member stress results grouped by load case and member.\r\nColumnar arrays hold stress values at each station along the member."
      },
      "MemberStressQueryResult": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MemberStress"
            },
            "description": "The query result rows.",
            "nullable": true
          },
          "warnings": {
            "$ref": "#/components/schemas/QueryWarnings"
          }
        },
        "additionalProperties": false,
        "description": "Wrapper for analysis query results.\r\nContains the result data plus optional warnings about requested cases or modes\r\nthat produced no results (i.e. were not analysed)."
      },
      "MemberType": {
        "enum": [
          "Normal",
          "TensionOnly",
          "CompressionOnly",
          "Cable",
          "Gap",
          "BrittleFuse",
          "PlasticFuse"
        ],
        "type": "string",
        "description": "Member element type. Determines the structural behavior of the member.\r\nMaps to SPACE GASS lookup table \"Member Type\"."
      },
      "MemberUpdate": {
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier of the entity to update.\r\nOptional for single updates (Id comes from route), required for bulk updates.",
            "format": "int32",
            "nullable": true,
            "example": 1
          },
          "nodeA": {
            "type": "integer",
            "description": "Node at end A of the member.",
            "format": "int32",
            "nullable": true
          },
          "nodeB": {
            "type": "integer",
            "description": "Node at end B of the member.",
            "format": "int32",
            "nullable": true
          },
          "type": {
            "$ref": "#/components/schemas/MemberType"
          },
          "section": {
            "type": "integer",
            "description": "Section number assigned to this member.",
            "format": "int32",
            "nullable": true
          },
          "material": {
            "type": "integer",
            "description": "Material number assigned to this member.",
            "format": "int32",
            "nullable": true
          },
          "direction": {
            "$ref": "#/components/schemas/DirectionUpdate"
          },
          "cableLength": {
            "type": "number",
            "description": "Cable length (for Cable type members). Unit: Length (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "gapTensionLimit": {
            "type": "number",
            "description": "Gap tension limit (for Gap type members). Unit: Force (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "gapCompressionLimit": {
            "type": "number",
            "description": "Gap compression limit (for Gap type members). Unit: Force (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "fuseTensionLimit": {
            "type": "number",
            "description": "Fuse tension limit (for Fuse type members). Unit: Force (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "fuseCompressionLimit": {
            "type": "number",
            "description": "Fuse compression limit (for Fuse type members). Unit: Force (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "releases": {
            "$ref": "#/components/schemas/MemberReleaseUpdate"
          }
        },
        "additionalProperties": false,
        "description": "DTO for updating an existing member.\r\nOnly fields included in the request are updated; omit a field to keep its current value."
      },
      "ModeShape": {
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "Load case ID.",
            "format": "int32"
          },
          "mode": {
            "type": "integer",
            "description": "Mode number.",
            "format": "int32"
          },
          "node": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int32"
            },
            "description": "Node keys.",
            "nullable": true
          },
          "tx": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Translational X displacement at each node. Unit: Translation (see GET /job/units).",
            "nullable": true
          },
          "ty": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Translational Y displacement at each node. Unit: Translation (see GET /job/units).",
            "nullable": true
          },
          "tz": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Translational Z displacement at each node. Unit: Translation (see GET /job/units).",
            "nullable": true
          },
          "rx": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Rotational X displacement at each node. Unit: Rotation (see GET /job/units).",
            "nullable": true
          },
          "ry": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Rotational Y displacement at each node. Unit: Rotation (see GET /job/units).",
            "nullable": true
          },
          "rz": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Rotational Z displacement at each node. Unit: Rotation (see GET /job/units).",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Dynamic mode shape results grouped by load case and mode (FileId 219).\r\nColumnar arrays hold displacement values at each node."
      },
      "ModeShapeQueryResult": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ModeShape"
            },
            "description": "The query result rows.",
            "nullable": true
          },
          "warnings": {
            "$ref": "#/components/schemas/QueryWarnings"
          }
        },
        "additionalProperties": false,
        "description": "Wrapper for analysis query results.\r\nContains the result data plus optional warnings about requested cases or modes\r\nthat produced no results (i.e. were not analysed)."
      },
      "ModelSummary": {
        "type": "object",
        "properties": {
          "nodes": {
            "type": "integer",
            "description": "Number of nodes (joints/points) in the structure.",
            "format": "int32"
          },
          "members": {
            "type": "integer",
            "description": "Number of members (beam/column elements) in the structure.",
            "format": "int32"
          },
          "plates": {
            "type": "integer",
            "description": "Number of plate/shell elements in the structure.",
            "format": "int32"
          },
          "nodeRestraints": {
            "type": "integer",
            "description": "Number of nodes with support restraint conditions.",
            "format": "int32"
          },
          "memberOffsets": {
            "type": "integer",
            "description": "Number of members with rigid end offsets.",
            "format": "int32"
          },
          "nodeConstraints": {
            "type": "integer",
            "description": "Number of master-slave node constraint definitions.",
            "format": "int32"
          },
          "sections": {
            "type": "integer",
            "description": "Number of cross-section profiles defined.",
            "format": "int32"
          },
          "materials": {
            "type": "integer",
            "description": "Number of materials defined.",
            "format": "int32"
          },
          "loadCases": {
            "type": "integer",
            "description": "Number of primary load cases defined.",
            "format": "int32"
          },
          "loadCaseGroups": {
            "type": "integer",
            "description": "Number of load case groups.",
            "format": "int32"
          },
          "loadCategories": {
            "type": "integer",
            "description": "Number of load categories (e.g. dead, live, wind).",
            "format": "int32"
          },
          "combinationLoadCases": {
            "type": "integer",
            "description": "Number of combination load cases.",
            "format": "int32"
          },
          "nodeLoads": {
            "type": "integer",
            "description": "Number of point loads applied to nodes.",
            "format": "int32"
          },
          "memberConcentratedLoads": {
            "type": "integer",
            "description": "Number of concentrated (point) loads applied to members.",
            "format": "int32"
          },
          "memberDistributedLoads": {
            "type": "integer",
            "description": "Number of distributed (UDL/trapezoidal) loads applied to members.",
            "format": "int32"
          },
          "memberTorsionLoads": {
            "type": "integer",
            "description": "Number of torsion loads applied to members.",
            "format": "int32"
          },
          "memberPrestressLoads": {
            "type": "integer",
            "description": "Number of prestress loads applied to members.",
            "format": "int32"
          },
          "plateLoads": {
            "type": "integer",
            "description": "Number of pressure/distributed loads applied to plates.",
            "format": "int32"
          },
          "prescribedDisplacements": {
            "type": "integer",
            "description": "Number of prescribed displacement constraints.",
            "format": "int32"
          },
          "selfWeightLoads": {
            "type": "integer",
            "description": "Number of self-weight load definitions.",
            "format": "int32"
          },
          "thermalLoads": {
            "type": "integer",
            "description": "Number of thermal (temperature) load definitions.",
            "format": "int32"
          },
          "lumpedMassLoads": {
            "type": "integer",
            "description": "Number of lumped mass definitions for dynamic analysis.",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Summary counts of all model entities in the current job."
      },
      "MomentUnit": {
        "enum": [
          "Kft",
          "Kin",
          "lbft",
          "lbin",
          "kNm",
          "kNcm",
          "kNmm",
          "Nm",
          "Ncm",
          "Nmm",
          "kgm",
          "kgcm",
          "kgmm"
        ],
        "type": "string",
        "description": "Moment unit. Members mirror SPACE GASS `SgMoment`."
      },
      "NaturalFrequency": {
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "Load case ID.",
            "format": "int32"
          },
          "mode": {
            "type": "integer",
            "description": "Mode number.",
            "format": "int32"
          },
          "warning": {
            "type": "string",
            "description": "Analysis engine warning message (empty if none).",
            "nullable": true
          },
          "naturalFrequency": {
            "type": "number",
            "description": "Natural frequency. Unit: Hz.",
            "format": "float"
          },
          "naturalPeriod": {
            "type": "number",
            "description": "Natural period. Unit: seconds.",
            "format": "float"
          },
          "frequencyTolerance": {
            "type": "number",
            "description": "Frequency convergence tolerance.",
            "format": "float"
          },
          "iterations": {
            "type": "integer",
            "description": "Number of iterations to converge.",
            "format": "int32"
          },
          "massPartX": {
            "type": "number",
            "description": "Mass participation factor in X direction.",
            "format": "float"
          },
          "massPartY": {
            "type": "number",
            "description": "Mass participation factor in Y direction.",
            "format": "float"
          },
          "massPartZ": {
            "type": "number",
            "description": "Mass participation factor in Z direction.",
            "format": "float"
          }
        },
        "additionalProperties": false,
        "description": "Dynamic natural frequency result (FileId 218)."
      },
      "NaturalFrequencyQueryResult": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NaturalFrequency"
            },
            "description": "The query result rows.",
            "nullable": true
          },
          "warnings": {
            "$ref": "#/components/schemas/QueryWarnings"
          }
        },
        "additionalProperties": false,
        "description": "Wrapper for analysis query results.\r\nContains the result data plus optional warnings about requested cases or modes\r\nthat produced no results (i.e. were not analysed)."
      },
      "Node": {
        "required": [
          "id",
          "x",
          "y",
          "z"
        ],
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier - must be unique, no duplicates allowed.\r\nRange: 1 to int.MaxValue",
            "format": "int32",
            "example": 1
          },
          "x": {
            "type": "number",
            "description": "X coordinate. Unit: Length (see GET /job/units).",
            "format": "double"
          },
          "y": {
            "type": "number",
            "description": "Y coordinate. Unit: Length (see GET /job/units).",
            "format": "double"
          },
          "z": {
            "type": "number",
            "description": "Z coordinate. Unit: Length (see GET /job/units).",
            "format": "double"
          },
          "hasConstraint": {
            "type": "boolean",
            "description": "True when this node is the slave side of a master-slave constraint.\r\nA node can be the slave of at most one constraint.\r\nUse `?expand=all` to include the full `constraint` object."
          },
          "hasRestraint": {
            "type": "boolean",
            "description": "True when this node has an explicit restraint row defined.\r\nFalse means the node uses default restraints (all DOFs free, no spring stiffness)."
          },
          "constraint": {
            "$ref": "#/components/schemas/NodeConstraint"
          },
          "restraint": {
            "$ref": "#/components/schemas/NodeRestraint"
          }
        },
        "additionalProperties": false,
        "description": "DTO for a single node in the structure\r\nOnly includes non-hidden fields from the SPACEGASS node definition"
      },
      "NodeBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Node"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "NodeConstraint": {
        "type": "object",
        "properties": {
          "slaveNode": {
            "type": "integer",
            "description": "The slave node number. This is the node whose DOFs are constrained to the master.",
            "format": "int32"
          },
          "masterNode": {
            "type": "integer",
            "description": "The master node number. The slave node's constrained DOFs follow this node's motion.",
            "format": "int32"
          },
          "constraintCode": {
            "type": "string",
            "description": "A 6-character string defining which degrees of freedom are constrained.\r\nEach character position maps to a DOF: UX, UY, UZ, RX, RY, RZ (left to right).\r\n'F' = Fixed (slave DOF is tied to master), 'R' = Released (slave DOF is free).\r\nExample: \"FFFRRR\" constrains translations only; \"FFFFFF\" constrains all 6 DOFs.",
            "nullable": true
          },
          "axes": {
            "$ref": "#/components/schemas/ConstraintAxes"
          },
          "xVector": {
            "type": "number",
            "description": "X component of the constraint axis direction vector.",
            "format": "double"
          },
          "yVector": {
            "type": "number",
            "description": "Y component of the constraint axis direction vector.",
            "format": "double"
          },
          "zVector": {
            "type": "number",
            "description": "Z component of the constraint axis direction vector.",
            "format": "double"
          },
          "guid": {
            "type": "string",
            "description": "The unique identifier for this constraint record.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for reading a node constraint (master-slave constraint).\r\nDefines a kinematic relationship between a slave node and a master node.\r\nThe slave node's degrees of freedom are tied to the master node according to the constraint code.\r\nTop-level entity attribute keyed on the slave node — each node can be a slave in at most one constraint."
      },
      "NodeConstraintBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NodeConstraint"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "NodeConstraintCreate": {
        "required": [
          "constraintCode",
          "masterNode",
          "slaveNode"
        ],
        "type": "object",
        "properties": {
          "slaveNode": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The slave node number. Required in the request body.",
            "format": "int32"
          },
          "masterNode": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The master node number. The slave node's constrained DOFs will follow this node's motion.",
            "format": "int32"
          },
          "constraintCode": {
            "maxLength": 6,
            "minLength": 6,
            "type": "string",
            "description": "A 6-character string defining which degrees of freedom are constrained.\r\nEach character position maps to a DOF: UX, UY, UZ, RX, RY, RZ (left to right).\r\n'F' = Fixed (tied to master), 'R' = Released (free).\r\nExample: \"FFFRRR\" constrains translations only; \"FFFFFF\" constrains all 6 DOFs."
          },
          "axes": {
            "$ref": "#/components/schemas/ConstraintAxes"
          },
          "xVector": {
            "type": "number",
            "description": "X component of the constraint axis direction vector.",
            "format": "double",
            "nullable": true
          },
          "yVector": {
            "type": "number",
            "description": "Y component of the constraint axis direction vector.",
            "format": "double",
            "nullable": true
          },
          "zVector": {
            "type": "number",
            "description": "Z component of the constraint axis direction vector.",
            "format": "double",
            "nullable": true
          },
          "guid": {
            "type": "string",
            "description": "Optional GUID for this constraint record.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for creating a node constraint. POST is entity-style: 409 if a constraint already exists\r\nfor the supplied slave node — caller must DELETE first or PATCH instead."
      },
      "NodeConstraintUpdate": {
        "type": "object",
        "properties": {
          "slaveNode": {
            "type": "integer",
            "description": "The slave node number that identifies which constraint to update.\r\nRequired for bulk PATCH; ignored for single-node PATCH (route value wins).",
            "format": "int32",
            "nullable": true
          },
          "masterNode": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The master node number.",
            "format": "int32",
            "nullable": true
          },
          "constraintCode": {
            "maxLength": 6,
            "minLength": 6,
            "type": "string",
            "description": "A 6-character string defining which degrees of freedom are constrained.\r\nEach character position maps to a DOF: UX, UY, UZ, RX, RY, RZ (left to right).\r\n'F' = Fixed (tied to master), 'R' = Released (free).",
            "nullable": true
          },
          "axes": {
            "$ref": "#/components/schemas/ConstraintAxes"
          },
          "xVector": {
            "type": "number",
            "description": "X component of the constraint axis direction vector.",
            "format": "double",
            "nullable": true
          },
          "yVector": {
            "type": "number",
            "description": "Y component of the constraint axis direction vector.",
            "format": "double",
            "nullable": true
          },
          "zVector": {
            "type": "number",
            "description": "Z component of the constraint axis direction vector.",
            "format": "double",
            "nullable": true
          },
          "guid": {
            "type": "string",
            "description": "Optional GUID for this constraint record.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for partially updating an existing node constraint.\r\nOnly fields included in the request are updated; omit a field to keep its current value."
      },
      "NodeCreate": {
        "required": [
          "x",
          "y",
          "z"
        ],
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier - must be unique, no duplicates allowed.\r\nOptional - will be auto-assigned to next available number if not provided.\r\nIf provided, must not already exist in the model.",
            "format": "int32",
            "nullable": true,
            "example": 1
          },
          "x": {
            "type": "number",
            "description": "X coordinate. Unit: Length (see GET /job/units).",
            "format": "double"
          },
          "y": {
            "type": "number",
            "description": "Y coordinate. Unit: Length (see GET /job/units).",
            "format": "double"
          },
          "z": {
            "type": "number",
            "description": "Z coordinate. Unit: Length (see GET /job/units).",
            "format": "double"
          }
        },
        "additionalProperties": false,
        "description": "DTO for creating a new node\r\nNode number may be auto-assigned if not provided"
      },
      "NodeDisplacement": {
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "Load case ID.",
            "format": "int32"
          },
          "node": {
            "type": "integer",
            "description": "Node key.",
            "format": "int32"
          },
          "tx": {
            "type": "number",
            "description": "Translational X displacement. Unit: Translation (see GET /job/units).",
            "format": "float"
          },
          "ty": {
            "type": "number",
            "description": "Translational Y displacement. Unit: Translation (see GET /job/units).",
            "format": "float"
          },
          "tz": {
            "type": "number",
            "description": "Translational Z displacement. Unit: Translation (see GET /job/units).",
            "format": "float"
          },
          "rx": {
            "type": "number",
            "description": "Rotational X displacement. Unit: Rotation (see GET /job/units).",
            "format": "float"
          },
          "ry": {
            "type": "number",
            "description": "Rotational Y displacement. Unit: Rotation (see GET /job/units).",
            "format": "float"
          },
          "rz": {
            "type": "number",
            "description": "Rotational Z displacement. Unit: Rotation (see GET /job/units).",
            "format": "float"
          }
        },
        "additionalProperties": false,
        "description": "Node displacement result for a specific load case (FileId 203)."
      },
      "NodeDisplacementQueryResult": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NodeDisplacement"
            },
            "description": "The query result rows.",
            "nullable": true
          },
          "warnings": {
            "$ref": "#/components/schemas/QueryWarnings"
          }
        },
        "additionalProperties": false,
        "description": "Wrapper for analysis query results.\r\nContains the result data plus optional warnings about requested cases or modes\r\nthat produced no results (i.e. were not analysed)."
      },
      "NodeLoad": {
        "required": [
          "node"
        ],
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "The load case number this load belongs to.",
            "format": "int32"
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "node": {
            "type": "integer",
            "description": "The node number this load is applied to.",
            "format": "int32"
          },
          "fx": {
            "type": "number",
            "description": "Force in the global X direction.",
            "format": "double"
          },
          "fy": {
            "type": "number",
            "description": "Force in the global Y direction.",
            "format": "double"
          },
          "fz": {
            "type": "number",
            "description": "Force in the global Z direction.",
            "format": "double"
          },
          "mx": {
            "type": "number",
            "description": "Moment about the global X axis.",
            "format": "double"
          },
          "my": {
            "type": "number",
            "description": "Moment about the global Y axis.",
            "format": "double"
          },
          "mz": {
            "type": "number",
            "description": "Moment about the global Z axis.",
            "format": "double"
          }
        },
        "additionalProperties": false,
        "description": "DTO for reading a node load entity.\r\nRepresents concentrated forces and moments applied at a node."
      },
      "NodeLoadBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NodeLoad"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "NodeLoadCreate": {
        "required": [
          "case",
          "node"
        ],
        "type": "object",
        "properties": {
          "case": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The load case number to create this load in.",
            "format": "int32"
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "node": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The node number to apply this load to.",
            "format": "int32"
          },
          "fx": {
            "type": "number",
            "description": "Force in the global X direction.",
            "format": "double",
            "nullable": true
          },
          "fy": {
            "type": "number",
            "description": "Force in the global Y direction.",
            "format": "double",
            "nullable": true
          },
          "fz": {
            "type": "number",
            "description": "Force in the global Z direction.",
            "format": "double",
            "nullable": true
          },
          "mx": {
            "type": "number",
            "description": "Moment about the global X axis.",
            "format": "double",
            "nullable": true
          },
          "my": {
            "type": "number",
            "description": "Moment about the global Y axis.",
            "format": "double",
            "nullable": true
          },
          "mz": {
            "type": "number",
            "description": "Moment about the global Z axis.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for creating a new node load."
      },
      "NodeLoadKey": {
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "The load case number.",
            "format": "int32"
          },
          "node": {
            "type": "integer",
            "description": "The node number.",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Composite Id object for bulk delete operations."
      },
      "NodeLoadKeyBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NodeLoadKey"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "NodeLoadUpdate": {
        "type": "object",
        "properties": {
          "case": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The load case number.",
            "format": "int32",
            "nullable": true
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "node": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The node number.",
            "format": "int32",
            "nullable": true
          },
          "fx": {
            "type": "number",
            "description": "Force in the global X direction.",
            "format": "double",
            "nullable": true
          },
          "fy": {
            "type": "number",
            "description": "Force in the global Y direction.",
            "format": "double",
            "nullable": true
          },
          "fz": {
            "type": "number",
            "description": "Force in the global Z direction.",
            "format": "double",
            "nullable": true
          },
          "mx": {
            "type": "number",
            "description": "Moment about the global X axis.",
            "format": "double",
            "nullable": true
          },
          "my": {
            "type": "number",
            "description": "Moment about the global Y axis.",
            "format": "double",
            "nullable": true
          },
          "mz": {
            "type": "number",
            "description": "Moment about the global Z axis.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for updating an existing node load.\r\nOnly fields included in the request are updated; omit a field to keep its current value."
      },
      "NodeReaction": {
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "Load case ID.",
            "format": "int32"
          },
          "node": {
            "type": "integer",
            "description": "Node key.",
            "format": "int32"
          },
          "fx": {
            "type": "number",
            "description": "Reaction force in X direction. Unit: Force (see GET /job/units).",
            "format": "float"
          },
          "fy": {
            "type": "number",
            "description": "Reaction force in Y direction. Unit: Force (see GET /job/units).",
            "format": "float"
          },
          "fz": {
            "type": "number",
            "description": "Reaction force in Z direction. Unit: Force (see GET /job/units).",
            "format": "float"
          },
          "mx": {
            "type": "number",
            "description": "Reaction moment about X axis. Unit: Moment (see GET /job/units).",
            "format": "float"
          },
          "my": {
            "type": "number",
            "description": "Reaction moment about Y axis. Unit: Moment (see GET /job/units).",
            "format": "float"
          },
          "mz": {
            "type": "number",
            "description": "Reaction moment about Z axis. Unit: Moment (see GET /job/units).",
            "format": "float"
          }
        },
        "additionalProperties": false,
        "description": "Node reaction result for a specific load case (FileId 205)."
      },
      "NodeReactionQueryResult": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NodeReaction"
            },
            "description": "The query result rows.",
            "nullable": true
          },
          "warnings": {
            "$ref": "#/components/schemas/QueryWarnings"
          }
        },
        "additionalProperties": false,
        "description": "Wrapper for analysis query results.\r\nContains the result data plus optional warnings about requested cases or modes\r\nthat produced no results (i.e. were not analysed)."
      },
      "NodeRestraint": {
        "type": "object",
        "properties": {
          "node": {
            "type": "integer",
            "description": "The node Id this restraint applies to.",
            "format": "int32"
          },
          "restraintCode": {
            "type": "string",
            "description": "6-character restraint code for TX,TY,TZ,RX,RY,RZ.\r\nEach character: F=Fixed (prevents movement), R=Released (allows movement), S=Spring (movement governed by a spring stiffness), V=Variable spring (multiple stiffnesses via a stiffness-vs-deflection table), P=Plastic (upper force/moment limit on the reaction), N=Friction (upper limit on reaction proportional to the normal-axis reaction).",
            "nullable": true
          },
          "activeDirection": {
            "type": "string",
            "description": "6-character active direction code for TX,TY,TZ,RX,RY,RZ.\r\nEach character: B=Both, P=Positive only, N=Negative only.",
            "nullable": true
          },
          "generalRestraint": {
            "type": "boolean",
            "description": "Whether this is the general restraint for the model."
          },
          "txStiffness": {
            "type": "number",
            "description": "Translational X spring stiffness. Unit: Force/Length (see GET /job/units).",
            "format": "double"
          },
          "tyStiffness": {
            "type": "number",
            "description": "Translational Y spring stiffness. Unit: Force/Length (see GET /job/units).",
            "format": "double"
          },
          "tzStiffness": {
            "type": "number",
            "description": "Translational Z spring stiffness. Unit: Force/Length (see GET /job/units).",
            "format": "double"
          },
          "rxStiffness": {
            "type": "number",
            "description": "Rotational X spring stiffness. Unit: Moment/Radian (see GET /job/units).",
            "format": "double"
          },
          "ryStiffness": {
            "type": "number",
            "description": "Rotational Y spring stiffness. Unit: Moment/Radian (see GET /job/units).",
            "format": "double"
          },
          "rzStiffness": {
            "type": "number",
            "description": "Rotational Z spring stiffness. Unit: Moment/Radian (see GET /job/units).",
            "format": "double"
          },
          "xFrictionNormalAxis": {
            "$ref": "#/components/schemas/FrictionNormalAxis"
          },
          "yFrictionNormalAxis": {
            "$ref": "#/components/schemas/FrictionNormalAxis"
          },
          "zFrictionNormalAxis": {
            "$ref": "#/components/schemas/FrictionNormalAxis"
          },
          "xFrictionNormalDirection": {
            "$ref": "#/components/schemas/FrictionNormalDirection"
          },
          "yFrictionNormalDirection": {
            "$ref": "#/components/schemas/FrictionNormalDirection"
          },
          "zFrictionNormalDirection": {
            "$ref": "#/components/schemas/FrictionNormalDirection"
          },
          "xFrictionFactor": {
            "type": "number",
            "description": "X-axis friction factor.",
            "format": "double"
          },
          "yFrictionFactor": {
            "type": "number",
            "description": "Y-axis friction factor.",
            "format": "double"
          },
          "zFrictionFactor": {
            "type": "number",
            "description": "Z-axis friction factor.",
            "format": "double"
          },
          "txPlasticLimit": {
            "type": "number",
            "description": "Translational X plastic limit. Unit: Force (see GET /job/units).",
            "format": "double"
          },
          "tyPlasticLimit": {
            "type": "number",
            "description": "Translational Y plastic limit. Unit: Force (see GET /job/units).",
            "format": "double"
          },
          "tzPlasticLimit": {
            "type": "number",
            "description": "Translational Z plastic limit. Unit: Force (see GET /job/units).",
            "format": "double"
          },
          "rxPlasticLimit": {
            "type": "number",
            "description": "Rotational X plastic limit. Unit: Moment (see GET /job/units).",
            "format": "double"
          },
          "ryPlasticLimit": {
            "type": "number",
            "description": "Rotational Y plastic limit. Unit: Moment (see GET /job/units).",
            "format": "double"
          },
          "rzPlasticLimit": {
            "type": "number",
            "description": "Rotational Z plastic limit. Unit: Moment (see GET /job/units).",
            "format": "double"
          },
          "txVariableTable": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "double"
              }
            },
            "description": "Variable-spring stiffness table for translational X. Points are (deflection, stiffness).",
            "nullable": true
          },
          "tyVariableTable": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "double"
              }
            },
            "description": "Variable-spring stiffness table for translational Y. Points are (deflection, stiffness).",
            "nullable": true
          },
          "tzVariableTable": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "double"
              }
            },
            "description": "Variable-spring stiffness table for translational Z. Points are (deflection, stiffness).",
            "nullable": true
          },
          "rxVariableTable": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "double"
              }
            },
            "description": "Variable-spring stiffness table for rotational X. Points are (rotation, stiffness).",
            "nullable": true
          },
          "ryVariableTable": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "double"
              }
            },
            "description": "Variable-spring stiffness table for rotational Y. Points are (rotation, stiffness).",
            "nullable": true
          },
          "rzVariableTable": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "double"
              }
            },
            "description": "Variable-spring stiffness table for rotational Z. Points are (rotation, stiffness).",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for reading a node restraint. Restraints define boundary conditions\r\nat nodes (fixed, released, spring, etc.) using a 6-character restraint code (FRSVPN).\r\nTop-level entity attribute keyed on the parent node."
      },
      "NodeRestraintBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NodeRestraint"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "NodeRestraintCreate": {
        "required": [
          "node",
          "restraintCode"
        ],
        "type": "object",
        "properties": {
          "node": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The node Id to create the restraint for. Required in the request body.",
            "format": "int32"
          },
          "restraintCode": {
            "minLength": 1,
            "type": "string",
            "description": "6-character restraint code for TX,TY,TZ,RX,RY,RZ. Each character is one of:\r\nF = Fixed (prevents movement);\r\nR = Released (allows movement);\r\nS = Spring (movement governed by a spring stiffness);\r\nV = Variable spring (multiple stiffnesses via a stiffness-vs-deflection table);\r\nP = Plastic (upper force/moment limit on the reaction);\r\nN = Friction (upper limit proportional to the normal-axis reaction).",
            "example": "FFFRRR"
          },
          "activeDirection": {
            "type": "string",
            "description": "6-character active direction code for TX,TY,TZ,RX,RY,RZ.",
            "nullable": true,
            "example": "BBBBBB"
          },
          "txStiffness": {
            "type": "number",
            "description": "Translational X spring stiffness. Unit: Force/Length (see GET /job/units).",
            "format": "double"
          },
          "tyStiffness": {
            "type": "number",
            "description": "Translational Y spring stiffness. Unit: Force/Length (see GET /job/units).",
            "format": "double"
          },
          "tzStiffness": {
            "type": "number",
            "description": "Translational Z spring stiffness. Unit: Force/Length (see GET /job/units).",
            "format": "double"
          },
          "rxStiffness": {
            "type": "number",
            "description": "Rotational X spring stiffness. Unit: Moment/Radian (see GET /job/units).",
            "format": "double"
          },
          "ryStiffness": {
            "type": "number",
            "description": "Rotational Y spring stiffness. Unit: Moment/Radian (see GET /job/units).",
            "format": "double"
          },
          "rzStiffness": {
            "type": "number",
            "description": "Rotational Z spring stiffness. Unit: Moment/Radian (see GET /job/units).",
            "format": "double"
          },
          "xFrictionNormalAxis": {
            "$ref": "#/components/schemas/FrictionNormalAxis"
          },
          "yFrictionNormalAxis": {
            "$ref": "#/components/schemas/FrictionNormalAxis"
          },
          "zFrictionNormalAxis": {
            "$ref": "#/components/schemas/FrictionNormalAxis"
          },
          "xFrictionNormalDirection": {
            "$ref": "#/components/schemas/FrictionNormalDirection"
          },
          "yFrictionNormalDirection": {
            "$ref": "#/components/schemas/FrictionNormalDirection"
          },
          "zFrictionNormalDirection": {
            "$ref": "#/components/schemas/FrictionNormalDirection"
          },
          "xFrictionFactor": {
            "type": "number",
            "description": "X-axis friction factor.",
            "format": "double"
          },
          "yFrictionFactor": {
            "type": "number",
            "description": "Y-axis friction factor.",
            "format": "double"
          },
          "zFrictionFactor": {
            "type": "number",
            "description": "Z-axis friction factor.",
            "format": "double"
          },
          "txPlasticLimit": {
            "type": "number",
            "description": "Translational X plastic limit. Unit: Force (see GET /job/units).",
            "format": "double"
          },
          "tyPlasticLimit": {
            "type": "number",
            "description": "Translational Y plastic limit. Unit: Force (see GET /job/units).",
            "format": "double"
          },
          "tzPlasticLimit": {
            "type": "number",
            "description": "Translational Z plastic limit. Unit: Force (see GET /job/units).",
            "format": "double"
          },
          "rxPlasticLimit": {
            "type": "number",
            "description": "Rotational X plastic limit. Unit: Moment (see GET /job/units).",
            "format": "double"
          },
          "ryPlasticLimit": {
            "type": "number",
            "description": "Rotational Y plastic limit. Unit: Moment (see GET /job/units).",
            "format": "double"
          },
          "rzPlasticLimit": {
            "type": "number",
            "description": "Rotational Z plastic limit. Unit: Moment (see GET /job/units).",
            "format": "double"
          },
          "txVariableTable": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "double"
              }
            },
            "description": "Variable-spring stiffness table for translational X.",
            "nullable": true
          },
          "tyVariableTable": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "double"
              }
            },
            "description": "Variable-spring stiffness table for translational Y.",
            "nullable": true
          },
          "tzVariableTable": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "double"
              }
            },
            "description": "Variable-spring stiffness table for translational Z.",
            "nullable": true
          },
          "rxVariableTable": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "double"
              }
            },
            "description": "Variable-spring stiffness table for rotational X.",
            "nullable": true
          },
          "ryVariableTable": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "double"
              }
            },
            "description": "Variable-spring stiffness table for rotational Y.",
            "nullable": true
          },
          "rzVariableTable": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "double"
              }
            },
            "description": "Variable-spring stiffness table for rotational Z.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for creating a node restraint. POST is entity-style: 409 if a restraint\r\nalready exists for the supplied node — caller must DELETE first or PATCH instead."
      },
      "NodeRestraintUpdate": {
        "type": "object",
        "properties": {
          "node": {
            "type": "integer",
            "description": "The node number that identifies which restraint to update.\r\nRequired for bulk PATCH; ignored for single-node PATCH (route value wins).",
            "format": "int32",
            "nullable": true
          },
          "restraintCode": {
            "type": "string",
            "description": "6-character restraint code for TX,TY,TZ,RX,RY,RZ.\r\nEach character: F=Fixed (prevents movement), R=Released (allows movement), S=Spring (movement governed by a spring stiffness), V=Variable spring (multiple stiffnesses via a stiffness-vs-deflection table), P=Plastic (upper force/moment limit on the reaction), N=Friction (upper limit on reaction proportional to the normal-axis reaction).",
            "nullable": true
          },
          "activeDirection": {
            "type": "string",
            "description": "6-character active direction code for TX,TY,TZ,RX,RY,RZ.\r\nEach character: B=Both, P=Positive only, N=Negative only.",
            "nullable": true
          },
          "txStiffness": {
            "type": "number",
            "description": "Translational X spring stiffness. Unit: Force/Length (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "tyStiffness": {
            "type": "number",
            "description": "Translational Y spring stiffness. Unit: Force/Length (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "tzStiffness": {
            "type": "number",
            "description": "Translational Z spring stiffness. Unit: Force/Length (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "rxStiffness": {
            "type": "number",
            "description": "Rotational X spring stiffness. Unit: Moment/Radian (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "ryStiffness": {
            "type": "number",
            "description": "Rotational Y spring stiffness. Unit: Moment/Radian (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "rzStiffness": {
            "type": "number",
            "description": "Rotational Z spring stiffness. Unit: Moment/Radian (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "xFrictionNormalAxis": {
            "$ref": "#/components/schemas/FrictionNormalAxis"
          },
          "yFrictionNormalAxis": {
            "$ref": "#/components/schemas/FrictionNormalAxis"
          },
          "zFrictionNormalAxis": {
            "$ref": "#/components/schemas/FrictionNormalAxis"
          },
          "xFrictionNormalDirection": {
            "$ref": "#/components/schemas/FrictionNormalDirection"
          },
          "yFrictionNormalDirection": {
            "$ref": "#/components/schemas/FrictionNormalDirection"
          },
          "zFrictionNormalDirection": {
            "$ref": "#/components/schemas/FrictionNormalDirection"
          },
          "xFrictionFactor": {
            "type": "number",
            "description": "X-axis friction factor.",
            "format": "double",
            "nullable": true
          },
          "yFrictionFactor": {
            "type": "number",
            "description": "Y-axis friction factor.",
            "format": "double",
            "nullable": true
          },
          "zFrictionFactor": {
            "type": "number",
            "description": "Z-axis friction factor.",
            "format": "double",
            "nullable": true
          },
          "txPlasticLimit": {
            "type": "number",
            "description": "Translational X plastic limit. Unit: Force (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "tyPlasticLimit": {
            "type": "number",
            "description": "Translational Y plastic limit. Unit: Force (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "tzPlasticLimit": {
            "type": "number",
            "description": "Translational Z plastic limit. Unit: Force (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "rxPlasticLimit": {
            "type": "number",
            "description": "Rotational X plastic limit. Unit: Moment (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "ryPlasticLimit": {
            "type": "number",
            "description": "Rotational Y plastic limit. Unit: Moment (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "rzPlasticLimit": {
            "type": "number",
            "description": "Rotational Z plastic limit. Unit: Moment (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "txVariableTable": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "double"
              }
            },
            "description": "Variable-spring stiffness table for translational X.",
            "nullable": true
          },
          "tyVariableTable": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "double"
              }
            },
            "description": "Variable-spring stiffness table for translational Y.",
            "nullable": true
          },
          "tzVariableTable": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "double"
              }
            },
            "description": "Variable-spring stiffness table for translational Z.",
            "nullable": true
          },
          "rxVariableTable": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "double"
              }
            },
            "description": "Variable-spring stiffness table for rotational X.",
            "nullable": true
          },
          "ryVariableTable": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "double"
              }
            },
            "description": "Variable-spring stiffness table for rotational Y.",
            "nullable": true
          },
          "rzVariableTable": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "double"
              }
            },
            "description": "Variable-spring stiffness table for rotational Z.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for partial updates to a node restraint.\r\nOnly fields included in the request are updated; omit a field to keep its current value."
      },
      "NodeTypeFilter": {
        "enum": [
          "All_Types",
          "Restrained"
        ],
        "type": "string",
        "description": "Filters nodes by type (e.g., restrained only)."
      },
      "NodeUpdate": {
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier of the entity to update.\r\nOptional for single updates (Id comes from route), required for bulk updates.",
            "format": "int32",
            "nullable": true,
            "example": 1
          },
          "x": {
            "type": "number",
            "description": "X coordinate. Unit: Length (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "y": {
            "type": "number",
            "description": "Y coordinate. Unit: Length (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "z": {
            "type": "number",
            "description": "Z coordinate. Unit: Length (see GET /job/units).",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for updating an existing node.\r\nAll coordinate fields are optional to support partial updates.\r\nId is inherited from EntityUpdateBaseDto - nullable because single updates\r\nreceive the Id from the route, while bulk updates include it in the body."
      },
      "NonLinearTheory": {
        "enum": [
          "Small",
          "Finite",
          "Large"
        ],
        "type": "string",
        "description": "Non-linear static analysis theory type.\r\nOnly used for non-linear static analysis."
      },
      "ObjectBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {},
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "OpenJobRequest": {
        "required": [
          "filePath"
        ],
        "type": "object",
        "properties": {
          "filePath": {
            "minLength": 1,
            "type": "string",
            "description": "Full path to the .sg job file to open."
          },
          "forceOption": {
            "$ref": "#/components/schemas/JobForceAccessOption"
          }
        },
        "additionalProperties": false,
        "description": "Request DTO for opening a job file."
      },
      "OpenSampleRequest": {
        "required": [
          "fileName"
        ],
        "type": "object",
        "properties": {
          "fileName": {
            "minLength": 1,
            "type": "string",
            "description": "Sample file name (e.g. \"Portal Frame.SG\").\r\nUse GET /api/v1/file/samples to list available samples."
          }
        },
        "additionalProperties": false,
        "description": "Request DTO for opening a sample project as a new unsaved job."
      },
      "OptimizationAxis": {
        "enum": [
          "X",
          "Y",
          "Z",
          "Vector"
        ],
        "type": "string",
        "description": "Axis used for optimization in analysis."
      },
      "OptimizationMethod": {
        "enum": [
          "None",
          "Auto",
          "General",
          "Linear",
          "Circular"
        ],
        "type": "string",
        "description": "Optimization method for analysis."
      },
      "Plate": {
        "required": [
          "id",
          "nodeA",
          "nodeB",
          "nodeC"
        ],
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier - must be unique, no duplicates allowed.\r\nRange: 1 to int.MaxValue",
            "format": "int32",
            "example": 1
          },
          "nodeA": {
            "type": "integer",
            "description": "Node at corner A of the plate.",
            "format": "int32"
          },
          "nodeB": {
            "type": "integer",
            "description": "Node at corner B of the plate.",
            "format": "int32"
          },
          "nodeC": {
            "type": "integer",
            "description": "Node at corner C of the plate.",
            "format": "int32"
          },
          "nodeD": {
            "type": "integer",
            "description": "Node at corner D of the plate. 0 indicates a triangular (3-node) plate.",
            "format": "int32"
          },
          "material": {
            "type": "integer",
            "description": "Material number assigned to this plate.",
            "format": "int32"
          },
          "actualThickness": {
            "type": "number",
            "description": "Actual thickness of the plate. Unit: Section Properties (see GET /job/units).",
            "format": "double"
          },
          "membraneThickness": {
            "type": "number",
            "description": "Membrane thickness of the plate. Unit: Section Properties (see GET /job/units).",
            "format": "double"
          },
          "bendingThickness": {
            "type": "number",
            "description": "Bending thickness of the plate. Unit: Section Properties (see GET /job/units).",
            "format": "double"
          },
          "shearThickness": {
            "type": "number",
            "description": "Shear thickness of the plate. Unit: Section Properties (see GET /job/units).",
            "format": "double"
          },
          "direction": {
            "$ref": "#/components/schemas/PlateDirection"
          },
          "theory": {
            "$ref": "#/components/schemas/PlateTheory"
          },
          "offset": {
            "type": "number",
            "description": "Plate offset. Unit: Length (see GET /job/units).",
            "format": "double"
          }
        },
        "additionalProperties": false,
        "description": "DTO for reading a plate entity.\r\nContains core plate properties without fixity data (handled separately if needed)."
      },
      "PlateBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Plate"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "PlateCreate": {
        "required": [
          "nodeA",
          "nodeB",
          "nodeC"
        ],
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier - must be unique, no duplicates allowed.\r\nOptional - will be auto-assigned to next available number if not provided.\r\nIf provided, must not already exist in the model.",
            "format": "int32",
            "nullable": true,
            "example": 1
          },
          "nodeA": {
            "type": "integer",
            "description": "Node at corner A of the plate.",
            "format": "int32"
          },
          "nodeB": {
            "type": "integer",
            "description": "Node at corner B of the plate.",
            "format": "int32"
          },
          "nodeC": {
            "type": "integer",
            "description": "Node at corner C of the plate.",
            "format": "int32"
          },
          "nodeD": {
            "type": "integer",
            "description": "Node at corner D of the plate. Omit or set to 0 for a triangular (3-node) plate.",
            "format": "int32",
            "nullable": true
          },
          "material": {
            "type": "integer",
            "description": "Material number assigned to this plate.",
            "format": "int32",
            "nullable": true
          },
          "actualThickness": {
            "type": "number",
            "description": "Actual thickness of the plate. Unit: Section Properties (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "membraneThickness": {
            "type": "number",
            "description": "Membrane thickness of the plate. Unit: Section Properties (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "bendingThickness": {
            "type": "number",
            "description": "Bending thickness of the plate. Unit: Section Properties (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "shearThickness": {
            "type": "number",
            "description": "Shear thickness of the plate. Unit: Section Properties (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "direction": {
            "$ref": "#/components/schemas/DirectionUpdate"
          },
          "theory": {
            "$ref": "#/components/schemas/PlateTheory"
          },
          "offset": {
            "type": "number",
            "description": "Plate offset. Unit: Length (see GET /job/units).",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for creating a new plate.\r\nNodeA, NodeB and NodeC are required; all other fields are optional."
      },
      "PlateCut": {
        "required": [
          "endNode",
          "endPlate",
          "id",
          "startNode",
          "startPlate"
        ],
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier - must be unique, no duplicates allowed.\r\nRange: 1 to int.MaxValue",
            "format": "int32",
            "example": 1
          },
          "title": {
            "type": "string",
            "description": "User-defined title for the plate cut.",
            "nullable": true
          },
          "startPlate": {
            "type": "integer",
            "description": "Start plate number for the cut.",
            "format": "int32"
          },
          "endPlate": {
            "type": "integer",
            "description": "End plate number for the cut.",
            "format": "int32"
          },
          "startNode": {
            "type": "integer",
            "description": "Start node number for the cut.",
            "format": "int32"
          },
          "endNode": {
            "type": "integer",
            "description": "End node number for the cut.",
            "format": "int32"
          },
          "startOffsetLongitudinal": {
            "type": "number",
            "description": "Longitudinal offset at the start of the cut.",
            "format": "double"
          },
          "startOffsetTransverse": {
            "type": "number",
            "description": "Transverse offset at the start of the cut.",
            "format": "double"
          },
          "endOffsetLongitudinal": {
            "type": "number",
            "description": "Longitudinal offset at the end of the cut.",
            "format": "double"
          },
          "endOffsetTransverse": {
            "type": "number",
            "description": "Transverse offset at the end of the cut.",
            "format": "double"
          },
          "outOfPlaneTolerance": {
            "type": "number",
            "description": "Out-of-plane tolerance for the cut.",
            "format": "double"
          }
        },
        "additionalProperties": false,
        "description": "DTO for reading a plate cut entity.\r\nA plate cut defines a cross-section cut through a plate element, used to extract\r\nresults along a line between two nodes across one or more plates."
      },
      "PlateCutBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlateCut"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "PlateCutCreate": {
        "required": [
          "endNode",
          "endPlate",
          "startNode",
          "startPlate"
        ],
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier - must be unique, no duplicates allowed.\r\nOptional - will be auto-assigned to next available number if not provided.\r\nIf provided, must not already exist in the model.",
            "format": "int32",
            "nullable": true,
            "example": 1
          },
          "title": {
            "maxLength": 100,
            "minLength": 0,
            "type": "string",
            "description": "User-defined title for the plate cut.",
            "nullable": true
          },
          "startPlate": {
            "type": "integer",
            "description": "Start plate number for the cut.",
            "format": "int32"
          },
          "endPlate": {
            "type": "integer",
            "description": "End plate number for the cut.",
            "format": "int32"
          },
          "startNode": {
            "type": "integer",
            "description": "Start node number for the cut.",
            "format": "int32"
          },
          "endNode": {
            "type": "integer",
            "description": "End node number for the cut.",
            "format": "int32"
          },
          "startOffsetLongitudinal": {
            "type": "number",
            "description": "Longitudinal offset at the start of the cut.",
            "format": "double",
            "nullable": true
          },
          "startOffsetTransverse": {
            "type": "number",
            "description": "Transverse offset at the start of the cut.",
            "format": "double",
            "nullable": true
          },
          "endOffsetLongitudinal": {
            "type": "number",
            "description": "Longitudinal offset at the end of the cut.",
            "format": "double",
            "nullable": true
          },
          "endOffsetTransverse": {
            "type": "number",
            "description": "Transverse offset at the end of the cut.",
            "format": "double",
            "nullable": true
          },
          "outOfPlaneTolerance": {
            "type": "number",
            "description": "Out-of-plane tolerance for the cut.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for creating a new plate cut.\r\nStartPlate, EndPlate, StartNode, and EndNode are required; all other fields are optional."
      },
      "PlateCutUpdate": {
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier of the entity to update.\r\nOptional for single updates (Id comes from route), required for bulk updates.",
            "format": "int32",
            "nullable": true,
            "example": 1
          },
          "title": {
            "maxLength": 100,
            "minLength": 0,
            "type": "string",
            "description": "User-defined title for the plate cut.",
            "nullable": true
          },
          "startPlate": {
            "type": "integer",
            "description": "Start plate number for the cut.",
            "format": "int32",
            "nullable": true
          },
          "endPlate": {
            "type": "integer",
            "description": "End plate number for the cut.",
            "format": "int32",
            "nullable": true
          },
          "startNode": {
            "type": "integer",
            "description": "Start node number for the cut.",
            "format": "int32",
            "nullable": true
          },
          "endNode": {
            "type": "integer",
            "description": "End node number for the cut.",
            "format": "int32",
            "nullable": true
          },
          "startOffsetLongitudinal": {
            "type": "number",
            "description": "Longitudinal offset at the start of the cut.",
            "format": "double",
            "nullable": true
          },
          "startOffsetTransverse": {
            "type": "number",
            "description": "Transverse offset at the start of the cut.",
            "format": "double",
            "nullable": true
          },
          "endOffsetLongitudinal": {
            "type": "number",
            "description": "Longitudinal offset at the end of the cut.",
            "format": "double",
            "nullable": true
          },
          "endOffsetTransverse": {
            "type": "number",
            "description": "Transverse offset at the end of the cut.",
            "format": "double",
            "nullable": true
          },
          "outOfPlaneTolerance": {
            "type": "number",
            "description": "Out-of-plane tolerance for the cut.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for updating an existing plate cut.\r\nOnly fields included in the request are updated; omit a field to keep its current value."
      },
      "PlateDirection": {
        "type": "object",
        "properties": {
          "source": {
            "$ref": "#/components/schemas/DirectionSource"
          },
          "dirAngle": {
            "type": "number",
            "description": "Direction angle for plate orientation.",
            "format": "double"
          },
          "dirNode": {
            "type": "integer",
            "description": "Direction node for plate orientation.",
            "format": "int32"
          },
          "dirAxis": {
            "$ref": "#/components/schemas/DirectionAxis"
          }
        },
        "additionalProperties": false,
        "description": "DTO for reading plate direction data.\r\nDirection defines the orientation of the plate's local coordinate system.\r\nAlways present on every plate — the parent PlateDto's `id` is authoritative."
      },
      "PlateElementForce": {
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "Load case ID.",
            "format": "int32"
          },
          "plate": {
            "type": "integer",
            "description": "Plate key.",
            "format": "int32"
          },
          "fx": {
            "type": "number",
            "description": "Membrane force in X. Unit: Force/Length (see GET /job/units).",
            "format": "float"
          },
          "fy": {
            "type": "number",
            "description": "Membrane force in Y. Unit: Force/Length (see GET /job/units).",
            "format": "float"
          },
          "fxy": {
            "type": "number",
            "description": "Membrane shear force. Unit: Force/Length (see GET /job/units).",
            "format": "float"
          },
          "mx": {
            "type": "number",
            "description": "Bending moment about X. Unit: Moment/Length (see GET /job/units).",
            "format": "float"
          },
          "my": {
            "type": "number",
            "description": "Bending moment about Y. Unit: Moment/Length (see GET /job/units).",
            "format": "float"
          },
          "mxy": {
            "type": "number",
            "description": "Twisting moment. Unit: Moment/Length (see GET /job/units).",
            "format": "float"
          },
          "vxz": {
            "type": "number",
            "description": "Transverse shear in XZ. Unit: Force/Length (see GET /job/units).",
            "format": "float"
          },
          "vyz": {
            "type": "number",
            "description": "Transverse shear in YZ. Unit: Force/Length (see GET /job/units).",
            "format": "float"
          },
          "mxTop": {
            "type": "number",
            "description": "Bending moment about X at top surface. Unit: Moment/Length (see GET /job/units).",
            "format": "float"
          },
          "myTop": {
            "type": "number",
            "description": "Bending moment about Y at top surface. Unit: Moment/Length (see GET /job/units).",
            "format": "float"
          },
          "mxBtm": {
            "type": "number",
            "description": "Bending moment about X at bottom surface. Unit: Moment/Length (see GET /job/units).",
            "format": "float"
          },
          "myBtm": {
            "type": "number",
            "description": "Bending moment about Y at bottom surface. Unit: Moment/Length (see GET /job/units).",
            "format": "float"
          }
        },
        "additionalProperties": false,
        "description": "Plate element force result for a specific load case (FileId 207)."
      },
      "PlateElementForceQueryResult": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlateElementForce"
            },
            "description": "The query result rows.",
            "nullable": true
          },
          "warnings": {
            "$ref": "#/components/schemas/QueryWarnings"
          }
        },
        "additionalProperties": false,
        "description": "Wrapper for analysis query results.\r\nContains the result data plus optional warnings about requested cases or modes\r\nthat produced no results (i.e. were not analysed)."
      },
      "PlateNodalForce": {
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "Load case ID.",
            "format": "int32"
          },
          "plate": {
            "type": "integer",
            "description": "Plate key.",
            "format": "int32"
          },
          "node": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int32"
            },
            "description": "Node keys at each corner of the plate element.",
            "nullable": true
          },
          "fx": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Force in X at each node. Unit: Force (see GET /job/units).",
            "nullable": true
          },
          "fy": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Force in Y at each node. Unit: Force (see GET /job/units).",
            "nullable": true
          },
          "fz": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Force in Z at each node. Unit: Force (see GET /job/units).",
            "nullable": true
          },
          "mx": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Moment about X at each node. Unit: Moment (see GET /job/units).",
            "nullable": true
          },
          "my": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Moment about Y at each node. Unit: Moment (see GET /job/units).",
            "nullable": true
          },
          "mz": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "float"
            },
            "description": "Moment about Z at each node. Unit: Moment (see GET /job/units).",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Plate nodal force results grouped by load case and plate.\r\nColumnar arrays hold force values at each node of the plate element."
      },
      "PlateNodalForceQueryResult": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlateNodalForce"
            },
            "description": "The query result rows.",
            "nullable": true
          },
          "warnings": {
            "$ref": "#/components/schemas/QueryWarnings"
          }
        },
        "additionalProperties": false,
        "description": "Wrapper for analysis query results.\r\nContains the result data plus optional warnings about requested cases or modes\r\nthat produced no results (i.e. were not analysed)."
      },
      "PlatePressureLoad": {
        "required": [
          "plate"
        ],
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "The load case number this load belongs to.",
            "format": "int32"
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "plate": {
            "type": "integer",
            "description": "The plate number this pressure load is applied to.",
            "format": "int32"
          },
          "axes": {
            "$ref": "#/components/schemas/LoadAxes"
          },
          "px": {
            "type": "number",
            "description": "Pressure in the X direction of the selected axes.",
            "format": "double"
          },
          "py": {
            "type": "number",
            "description": "Pressure in the Y direction of the selected axes.",
            "format": "double"
          },
          "pz": {
            "type": "number",
            "description": "Pressure in the Z direction of the selected axes.",
            "format": "double"
          }
        },
        "additionalProperties": false,
        "description": "DTO for reading a plate pressure load entity.\r\nRepresents a distributed pressure load applied to a plate."
      },
      "PlatePressureLoadBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlatePressureLoad"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "PlatePressureLoadCreate": {
        "required": [
          "case",
          "plate"
        ],
        "type": "object",
        "properties": {
          "case": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The load case number to create this load in.",
            "format": "int32"
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "plate": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The plate number to apply this pressure load to.",
            "format": "int32"
          },
          "axes": {
            "$ref": "#/components/schemas/LoadAxes"
          },
          "px": {
            "type": "number",
            "description": "Pressure in the X direction of the selected axes.",
            "format": "double",
            "nullable": true
          },
          "py": {
            "type": "number",
            "description": "Pressure in the Y direction of the selected axes.",
            "format": "double",
            "nullable": true
          },
          "pz": {
            "type": "number",
            "description": "Pressure in the Z direction of the selected axes.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for creating a new plate pressure load."
      },
      "PlatePressureLoadKey": {
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "The load case number.",
            "format": "int32"
          },
          "plate": {
            "type": "integer",
            "description": "The plate number.",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Composite Id object for bulk delete operations."
      },
      "PlatePressureLoadKeyBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlatePressureLoadKey"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "PlatePressureLoadUpdate": {
        "type": "object",
        "properties": {
          "case": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The load case number.",
            "format": "int32",
            "nullable": true
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "plate": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The plate number.",
            "format": "int32",
            "nullable": true
          },
          "axes": {
            "$ref": "#/components/schemas/LoadAxes"
          },
          "px": {
            "type": "number",
            "description": "Pressure in the X direction of the selected axes.",
            "format": "double",
            "nullable": true
          },
          "py": {
            "type": "number",
            "description": "Pressure in the Y direction of the selected axes.",
            "format": "double",
            "nullable": true
          },
          "pz": {
            "type": "number",
            "description": "Pressure in the Z direction of the selected axes.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for updating an existing plate pressure load.\r\nOnly fields included in the request are updated; omit a field to keep its current value."
      },
      "PlateStress": {
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "Load case ID.",
            "format": "int32"
          },
          "plate": {
            "type": "integer",
            "description": "Plate key.",
            "format": "int32"
          },
          "sxTop": {
            "type": "number",
            "description": "Normal stress in X at top surface. Unit: Stress (see GET /job/units).",
            "format": "float"
          },
          "syTop": {
            "type": "number",
            "description": "Normal stress in Y at top surface. Unit: Stress (see GET /job/units).",
            "format": "float"
          },
          "txyTop": {
            "type": "number",
            "description": "Shear stress XY at top surface. Unit: Stress (see GET /job/units).",
            "format": "float"
          },
          "sxpTop": {
            "type": "number",
            "description": "Principal stress in X at top surface. Unit: Stress (see GET /job/units).",
            "format": "float"
          },
          "sypTop": {
            "type": "number",
            "description": "Principal stress in Y at top surface. Unit: Stress (see GET /job/units).",
            "format": "float"
          },
          "tmaxTop": {
            "type": "number",
            "description": "Maximum shear stress at top surface. Unit: Stress (see GET /job/units).",
            "format": "float"
          },
          "svmTop": {
            "type": "number",
            "description": "Von Mises stress at top surface. Unit: Stress (see GET /job/units).",
            "format": "float"
          },
          "paTop": {
            "type": "number",
            "description": "Principal angle at top surface. Unit: Rotation (see GET /job/units).",
            "format": "float"
          },
          "sxBtm": {
            "type": "number",
            "description": "Normal stress in X at bottom surface. Unit: Stress (see GET /job/units).",
            "format": "float"
          },
          "syBtm": {
            "type": "number",
            "description": "Normal stress in Y at bottom surface. Unit: Stress (see GET /job/units).",
            "format": "float"
          },
          "txyBtm": {
            "type": "number",
            "description": "Shear stress XY at bottom surface. Unit: Stress (see GET /job/units).",
            "format": "float"
          },
          "sxpBtm": {
            "type": "number",
            "description": "Principal stress in X at bottom surface. Unit: Stress (see GET /job/units).",
            "format": "float"
          },
          "sypBtm": {
            "type": "number",
            "description": "Principal stress in Y at bottom surface. Unit: Stress (see GET /job/units).",
            "format": "float"
          },
          "tmaxBtm": {
            "type": "number",
            "description": "Maximum shear stress at bottom surface. Unit: Stress (see GET /job/units).",
            "format": "float"
          },
          "svmBtm": {
            "type": "number",
            "description": "Von Mises stress at bottom surface. Unit: Stress (see GET /job/units).",
            "format": "float"
          },
          "paBtm": {
            "type": "number",
            "description": "Principal angle at bottom surface. Unit: Rotation (see GET /job/units).",
            "format": "float"
          },
          "txz": {
            "type": "number",
            "description": "Transverse shear stress in XZ. Unit: Stress (see GET /job/units).",
            "format": "float"
          },
          "tyz": {
            "type": "number",
            "description": "Transverse shear stress in YZ. Unit: Stress (see GET /job/units).",
            "format": "float"
          }
        },
        "additionalProperties": false,
        "description": "Plate stress result for a specific load case (FileId 208)."
      },
      "PlateStressQueryResult": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlateStress"
            },
            "description": "The query result rows.",
            "nullable": true
          },
          "warnings": {
            "$ref": "#/components/schemas/QueryWarnings"
          }
        },
        "additionalProperties": false,
        "description": "Wrapper for analysis query results.\r\nContains the result data plus optional warnings about requested cases or modes\r\nthat produced no results (i.e. were not analysed)."
      },
      "PlateStrip": {
        "required": [
          "endNode",
          "endPlate",
          "id",
          "startNode",
          "startPlate"
        ],
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier - must be unique, no duplicates allowed.\r\nRange: 1 to int.MaxValue",
            "format": "int32",
            "example": 1
          },
          "title": {
            "type": "string",
            "description": "User-defined title for the plate strip.",
            "nullable": true
          },
          "startPlate": {
            "type": "integer",
            "description": "Start plate number for the strip.",
            "format": "int32"
          },
          "endPlate": {
            "type": "integer",
            "description": "End plate number for the strip.",
            "format": "int32"
          },
          "startNode": {
            "type": "integer",
            "description": "Start node number for the strip.",
            "format": "int32"
          },
          "endNode": {
            "type": "integer",
            "description": "End node number for the strip.",
            "format": "int32"
          },
          "uniformWidth": {
            "type": "boolean",
            "description": "Whether the strip has uniform width along its length."
          },
          "width": {
            "type": "number",
            "description": "Uniform width of the strip.",
            "format": "double"
          },
          "startWidthLeft": {
            "type": "number",
            "description": "Left width at the start of the strip.",
            "format": "double"
          },
          "startWidthRight": {
            "type": "number",
            "description": "Right width at the start of the strip.",
            "format": "double"
          },
          "endWidthLeft": {
            "type": "number",
            "description": "Left width at the end of the strip.",
            "format": "double"
          },
          "endWidthRight": {
            "type": "number",
            "description": "Right width at the end of the strip.",
            "format": "double"
          },
          "startOffsetLongitudinal": {
            "type": "number",
            "description": "Longitudinal offset at the start of the strip.",
            "format": "double"
          },
          "startOffsetTransverse": {
            "type": "number",
            "description": "Transverse offset at the start of the strip.",
            "format": "double"
          },
          "endOffsetLongitudinal": {
            "type": "number",
            "description": "Longitudinal offset at the end of the strip.",
            "format": "double"
          },
          "endOffsetTransverse": {
            "type": "number",
            "description": "Transverse offset at the end of the strip.",
            "format": "double"
          },
          "transverseIncrement": {
            "type": "number",
            "description": "Transverse increment spacing along the strip.",
            "format": "double"
          },
          "outOfPlaneTolerance": {
            "type": "number",
            "description": "Out-of-plane tolerance for the strip.",
            "format": "double"
          }
        },
        "additionalProperties": false,
        "description": "DTO for reading a plate strip entity.\r\nA plate strip defines a result-extraction strip through one or more plates between two nodes,\r\nwith configurable uniform or non-uniform width."
      },
      "PlateStripBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlateStrip"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "PlateStripCreate": {
        "required": [
          "endNode",
          "endPlate",
          "startNode",
          "startPlate",
          "uniformWidth"
        ],
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier - must be unique, no duplicates allowed.\r\nOptional - will be auto-assigned to next available number if not provided.\r\nIf provided, must not already exist in the model.",
            "format": "int32",
            "nullable": true,
            "example": 1
          },
          "title": {
            "maxLength": 100,
            "minLength": 0,
            "type": "string",
            "description": "User-defined title for the plate strip.",
            "nullable": true
          },
          "startPlate": {
            "type": "integer",
            "description": "Start plate number for the strip.",
            "format": "int32"
          },
          "endPlate": {
            "type": "integer",
            "description": "End plate number for the strip.",
            "format": "int32"
          },
          "startNode": {
            "type": "integer",
            "description": "Start node number for the strip.",
            "format": "int32"
          },
          "endNode": {
            "type": "integer",
            "description": "End node number for the strip.",
            "format": "int32"
          },
          "uniformWidth": {
            "type": "boolean",
            "description": "Whether the strip has uniform width along its length."
          },
          "width": {
            "type": "number",
            "description": "Uniform width of the strip.",
            "format": "double",
            "nullable": true
          },
          "startWidthLeft": {
            "type": "number",
            "description": "Left width at the start of the strip.",
            "format": "double",
            "nullable": true
          },
          "startWidthRight": {
            "type": "number",
            "description": "Right width at the start of the strip.",
            "format": "double",
            "nullable": true
          },
          "endWidthLeft": {
            "type": "number",
            "description": "Left width at the end of the strip.",
            "format": "double",
            "nullable": true
          },
          "endWidthRight": {
            "type": "number",
            "description": "Right width at the end of the strip.",
            "format": "double",
            "nullable": true
          },
          "startOffsetLongitudinal": {
            "type": "number",
            "description": "Longitudinal offset at the start of the strip.",
            "format": "double",
            "nullable": true
          },
          "startOffsetTransverse": {
            "type": "number",
            "description": "Transverse offset at the start of the strip.",
            "format": "double",
            "nullable": true
          },
          "endOffsetLongitudinal": {
            "type": "number",
            "description": "Longitudinal offset at the end of the strip.",
            "format": "double",
            "nullable": true
          },
          "endOffsetTransverse": {
            "type": "number",
            "description": "Transverse offset at the end of the strip.",
            "format": "double",
            "nullable": true
          },
          "transverseIncrement": {
            "type": "number",
            "description": "Transverse increment spacing along the strip.",
            "format": "double",
            "nullable": true
          },
          "outOfPlaneTolerance": {
            "type": "number",
            "description": "Out-of-plane tolerance for the strip.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for creating a new plate strip.\r\nStartPlate, EndPlate, StartNode, EndNode, and UniformWidth are required; all other fields are optional."
      },
      "PlateStripUpdate": {
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier of the entity to update.\r\nOptional for single updates (Id comes from route), required for bulk updates.",
            "format": "int32",
            "nullable": true,
            "example": 1
          },
          "title": {
            "maxLength": 100,
            "minLength": 0,
            "type": "string",
            "description": "User-defined title for the plate strip.",
            "nullable": true
          },
          "startPlate": {
            "type": "integer",
            "description": "Start plate number for the strip.",
            "format": "int32",
            "nullable": true
          },
          "endPlate": {
            "type": "integer",
            "description": "End plate number for the strip.",
            "format": "int32",
            "nullable": true
          },
          "startNode": {
            "type": "integer",
            "description": "Start node number for the strip.",
            "format": "int32",
            "nullable": true
          },
          "endNode": {
            "type": "integer",
            "description": "End node number for the strip.",
            "format": "int32",
            "nullable": true
          },
          "uniformWidth": {
            "type": "boolean",
            "description": "Whether the strip has uniform width along its length.",
            "nullable": true
          },
          "width": {
            "type": "number",
            "description": "Uniform width of the strip.",
            "format": "double",
            "nullable": true
          },
          "startWidthLeft": {
            "type": "number",
            "description": "Left width at the start of the strip.",
            "format": "double",
            "nullable": true
          },
          "startWidthRight": {
            "type": "number",
            "description": "Right width at the start of the strip.",
            "format": "double",
            "nullable": true
          },
          "endWidthLeft": {
            "type": "number",
            "description": "Left width at the end of the strip.",
            "format": "double",
            "nullable": true
          },
          "endWidthRight": {
            "type": "number",
            "description": "Right width at the end of the strip.",
            "format": "double",
            "nullable": true
          },
          "startOffsetLongitudinal": {
            "type": "number",
            "description": "Longitudinal offset at the start of the strip.",
            "format": "double",
            "nullable": true
          },
          "startOffsetTransverse": {
            "type": "number",
            "description": "Transverse offset at the start of the strip.",
            "format": "double",
            "nullable": true
          },
          "endOffsetLongitudinal": {
            "type": "number",
            "description": "Longitudinal offset at the end of the strip.",
            "format": "double",
            "nullable": true
          },
          "endOffsetTransverse": {
            "type": "number",
            "description": "Transverse offset at the end of the strip.",
            "format": "double",
            "nullable": true
          },
          "transverseIncrement": {
            "type": "number",
            "description": "Transverse increment spacing along the strip.",
            "format": "double",
            "nullable": true
          },
          "outOfPlaneTolerance": {
            "type": "number",
            "description": "Out-of-plane tolerance for the strip.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for updating an existing plate strip.\r\nOnly fields included in the request are updated; omit a field to keep its current value."
      },
      "PlateTheory": {
        "enum": [
          "Kirchoff",
          "Mindlin"
        ],
        "type": "string",
        "description": "Plate theory type for finite element analysis.\r\nMaps to SPACE GASS lookup table \"Plate Theory\"."
      },
      "PlateType": {
        "enum": [
          "BCPlates",
          "DLPlates"
        ],
        "type": "string",
        "description": "Plate element formulation type."
      },
      "PlateUpdate": {
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier of the entity to update.\r\nOptional for single updates (Id comes from route), required for bulk updates.",
            "format": "int32",
            "nullable": true,
            "example": 1
          },
          "nodeA": {
            "type": "integer",
            "description": "Node at corner A of the plate.",
            "format": "int32",
            "nullable": true
          },
          "nodeB": {
            "type": "integer",
            "description": "Node at corner B of the plate.",
            "format": "int32",
            "nullable": true
          },
          "nodeC": {
            "type": "integer",
            "description": "Node at corner C of the plate.",
            "format": "int32",
            "nullable": true
          },
          "nodeD": {
            "type": "integer",
            "description": "Node at corner D of the plate. Set to 0 for a triangular (3-node) plate.",
            "format": "int32",
            "nullable": true
          },
          "material": {
            "type": "integer",
            "description": "Material number assigned to this plate.",
            "format": "int32",
            "nullable": true
          },
          "actualThickness": {
            "type": "number",
            "description": "Actual thickness of the plate. Unit: Section Properties (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "membraneThickness": {
            "type": "number",
            "description": "Membrane thickness of the plate. Unit: Section Properties (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "bendingThickness": {
            "type": "number",
            "description": "Bending thickness of the plate. Unit: Section Properties (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "shearThickness": {
            "type": "number",
            "description": "Shear thickness of the plate. Unit: Section Properties (see GET /job/units).",
            "format": "double",
            "nullable": true
          },
          "direction": {
            "$ref": "#/components/schemas/DirectionUpdate"
          },
          "theory": {
            "$ref": "#/components/schemas/PlateTheory"
          },
          "offset": {
            "type": "number",
            "description": "Plate offset. Unit: Length (see GET /job/units).",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for updating an existing plate.\r\nOnly fields included in the request are updated; omit a field to keep its current value."
      },
      "PrescribedDisplacement": {
        "required": [
          "node"
        ],
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "The load case number this load belongs to.",
            "format": "int32"
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "node": {
            "type": "integer",
            "description": "The node number this displacement is applied to.",
            "format": "int32"
          },
          "tx": {
            "type": "number",
            "description": "Prescribed translation in the global X direction.",
            "format": "double"
          },
          "ty": {
            "type": "number",
            "description": "Prescribed translation in the global Y direction.",
            "format": "double"
          },
          "tz": {
            "type": "number",
            "description": "Prescribed translation in the global Z direction.",
            "format": "double"
          },
          "rx": {
            "type": "number",
            "description": "Prescribed rotation about the global X axis.",
            "format": "double"
          },
          "ry": {
            "type": "number",
            "description": "Prescribed rotation about the global Y axis.",
            "format": "double"
          },
          "rz": {
            "type": "number",
            "description": "Prescribed rotation about the global Z axis.",
            "format": "double"
          }
        },
        "additionalProperties": false,
        "description": "DTO for reading a prescribed displacement entity.\r\nRepresents a prescribed displacement or rotation applied at a node."
      },
      "PrescribedDisplacementBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PrescribedDisplacement"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "PrescribedDisplacementCreate": {
        "required": [
          "case",
          "node"
        ],
        "type": "object",
        "properties": {
          "case": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The load case number to create this load in.",
            "format": "int32"
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "node": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The node number to apply this displacement to.",
            "format": "int32"
          },
          "tx": {
            "type": "number",
            "description": "Prescribed translation in the global X direction.",
            "format": "double",
            "nullable": true
          },
          "ty": {
            "type": "number",
            "description": "Prescribed translation in the global Y direction.",
            "format": "double",
            "nullable": true
          },
          "tz": {
            "type": "number",
            "description": "Prescribed translation in the global Z direction.",
            "format": "double",
            "nullable": true
          },
          "rx": {
            "type": "number",
            "description": "Prescribed rotation about the global X axis.",
            "format": "double",
            "nullable": true
          },
          "ry": {
            "type": "number",
            "description": "Prescribed rotation about the global Y axis.",
            "format": "double",
            "nullable": true
          },
          "rz": {
            "type": "number",
            "description": "Prescribed rotation about the global Z axis.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for creating a new prescribed displacement."
      },
      "PrescribedDisplacementKey": {
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "The load case number.",
            "format": "int32"
          },
          "node": {
            "type": "integer",
            "description": "The node number.",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Composite Id object for bulk delete operations."
      },
      "PrescribedDisplacementKeyBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PrescribedDisplacementKey"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "PrescribedDisplacementUpdate": {
        "type": "object",
        "properties": {
          "case": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The load case number.",
            "format": "int32",
            "nullable": true
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "node": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The node number.",
            "format": "int32",
            "nullable": true
          },
          "tx": {
            "type": "number",
            "description": "Prescribed translation in the global X direction.",
            "format": "double",
            "nullable": true
          },
          "ty": {
            "type": "number",
            "description": "Prescribed translation in the global Y direction.",
            "format": "double",
            "nullable": true
          },
          "tz": {
            "type": "number",
            "description": "Prescribed translation in the global Z direction.",
            "format": "double",
            "nullable": true
          },
          "rx": {
            "type": "number",
            "description": "Prescribed rotation about the global X axis.",
            "format": "double",
            "nullable": true
          },
          "ry": {
            "type": "number",
            "description": "Prescribed rotation about the global Y axis.",
            "format": "double",
            "nullable": true
          },
          "rz": {
            "type": "number",
            "description": "Prescribed rotation about the global Z axis.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for updating an existing prescribed displacement.\r\nOnly fields included in the request are updated; omit a field to keep its current value."
      },
      "ProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "detail": {
            "type": "string",
            "nullable": true
          },
          "instance": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": {}
      },
      "PropertySource": {
        "enum": [
          "User",
          "Library"
        ],
        "type": "string",
        "description": "Indicates whether a section or material was user-defined or imported from a library."
      },
      "QueryWarnings": {
        "type": "object",
        "properties": {
          "casesNotAnalyzed": {
            "type": "string",
            "description": "Load case Ids that exist in the model but produced no result rows for this query\r\n— typically because the analysis has not been run for those cases.\r\nSG list-format string (e.g. `\"2,5-7\"`) — already intersected against the\r\ncaller's original filter, ready to paste back into `POST /job/analysis/run`'s\r\n`loadCases` field.",
            "nullable": true,
            "example": "2,5-7"
          },
          "modesNotAnalyzed": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseModesWarning"
            },
            "description": "Per-case list of modes the caller requested that did not produce result rows\r\nfor that specific case. Each analysed case can compute a different number of\r\nmodes, so a flattened across-cases warning would hide gaps. Each entry names\r\nthe case and the SG list-format string of missing mode numbers for it.\r\nInformational — to resolve, raise the analysis `modes` count to at least\r\nthe largest missing mode number and re-run.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Warnings returned when some requested load cases or modes did not have analysis\r\nresults in the response. (Filter Ids that don't exist in the model are rejected\r\nup-front with HTTP 400 by the controller — they never reach this DTO.)\r\n\r\n`casesNotAnalyzed` is an SG list-format string that can be pasted straight\r\ninto `POST /job/analysis/run`'s `loadCases` field to re-run only those\r\ncases. `modesNotAnalyzed` is a per-case list — each analysed case can compute\r\na different number of modes, so the warning is keyed by case rather than flattened."
      },
      "RegistrationStatus": {
        "enum": [
          "TitanCloud",
          "TitanLM",
          "Unsupported",
          "Unregistered"
        ],
        "type": "string",
        "description": "Outcome of probing the machine for a SPACE GASS registration.\r\nMirrors the precedence used by desktop SPACE GASS in\r\n`NETLicenses\\Licenses.vb::RegistrationSetupCheck`: legacy SGREG.DAT\r\nshort-circuits before any Titan-type probing, then TitanCloud, then Titan LM."
      },
      "ResourceMetadata": {
        "type": "object",
        "properties": {
          "resourceType": {
            "$ref": "#/components/schemas/EntityId"
          },
          "count": {
            "type": "integer",
            "description": "Current count of items in this resource.\r\nNull for sub-resources whose count does not apply uniformly.",
            "format": "int32",
            "nullable": true
          },
          "maxId": {
            "type": "integer",
            "description": "Maximum Id currently in use (single-int Id entities only).",
            "format": "int32",
            "nullable": true
          },
          "nextId": {
            "type": "integer",
            "description": "Next available Id (single-int Id entities only).",
            "format": "int32",
            "nullable": true
          },
          "fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FieldMetadata"
            },
            "description": "Field definitions describing the resource's wire shape. Each entry corresponds\r\nto a property on the read DTO; `jsonName` matches the JSON key clients see.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Metadata describing an API resource — entity, sub-resource, or result set.\r\nReturned from `GET …/metadata` endpoints so clients can introspect the\r\nshape, units, and valid values of the data without hitting a live endpoint."
      },
      "SaveJobRequest": {
        "type": "object",
        "properties": {
          "filePath": {
            "type": "string",
            "description": "Target file path. Omit to save to current location.\r\nRequired if the job is new (never saved before).",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Request DTO for saving a job."
      },
      "Section": {
        "required": [
          "id"
        ],
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier - must be unique, no duplicates allowed.\r\nRange: 1 to int.MaxValue",
            "format": "int32",
            "example": 1
          },
          "name": {
            "type": "string",
            "description": "Section name.",
            "nullable": true,
            "example": "360 UB 44.7"
          },
          "library": {
            "type": "string",
            "description": "Library name.",
            "nullable": true,
            "example": "Aust300"
          },
          "mark": {
            "type": "string",
            "description": "Section mark / designation.",
            "nullable": true,
            "example": "B1"
          },
          "a": {
            "type": "number",
            "description": "Cross-sectional area.",
            "format": "double",
            "example": 5720
          },
          "j": {
            "type": "number",
            "description": "Torsion constant.",
            "format": "double",
            "example": 158000
          },
          "iy": {
            "type": "number",
            "description": "Second moment of area about the principal Y axis.",
            "format": "double",
            "example": 121000000
          },
          "iz": {
            "type": "number",
            "description": "Second moment of area about the principal Z axis.",
            "format": "double",
            "example": 8970000
          },
          "ay": {
            "type": "number",
            "description": "Shear area in the Y direction.",
            "format": "double",
            "example": 2720
          },
          "az": {
            "type": "number",
            "description": "Shear area in the Z direction.",
            "format": "double",
            "example": 2010
          },
          "principalAngle": {
            "type": "number",
            "description": "Principal axis rotation angle.",
            "format": "double",
            "example": 0
          },
          "source": {
            "$ref": "#/components/schemas/PropertySource"
          },
          "shapes": {
            "type": "integer",
            "description": "Number of shapes in the section (1 for a standard library section).",
            "format": "int32",
            "example": 1
          },
          "areaFactor": {
            "type": "number",
            "description": "Area modification factor.",
            "format": "double",
            "example": 1
          },
          "torsionFactor": {
            "type": "number",
            "description": "Torsion modification factor.",
            "format": "double",
            "example": 1
          },
          "iyFactor": {
            "type": "number",
            "description": "Iy modification factor.",
            "format": "double",
            "example": 1
          },
          "izFactor": {
            "type": "number",
            "description": "Iz modification factor.",
            "format": "double",
            "example": 1
          },
          "angleType": {
            "$ref": "#/components/schemas/AngleType"
          },
          "transposed": {
            "type": "boolean",
            "description": "Whether the section's principal axes are swapped (transposed shape).",
            "example": false
          }
        },
        "additionalProperties": false,
        "description": "DTO for reading a section entity."
      },
      "SectionBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Section"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "SectionLibraryCreate": {
        "required": [
          "library",
          "name"
        ],
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier - must be unique, no duplicates allowed.\r\nOptional - will be auto-assigned to next available number if not provided.\r\nIf provided, must not already exist in the model.",
            "format": "int32",
            "nullable": true,
            "example": 1
          },
          "name": {
            "minLength": 1,
            "type": "string",
            "description": "Section item name within the library.",
            "example": "360 UB 44.7"
          },
          "library": {
            "minLength": 1,
            "type": "string",
            "description": "Library name.",
            "example": "Aust300"
          },
          "mark": {
            "type": "string",
            "description": "Section mark / designation.",
            "nullable": true,
            "example": "B1"
          },
          "angleType": {
            "$ref": "#/components/schemas/AngleType"
          },
          "transposed": {
            "type": "boolean",
            "description": "Whether the section's principal axes are swapped (transposed shape).",
            "nullable": true,
            "example": false
          },
          "ay": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Shear area in the Y direction.",
            "format": "double",
            "nullable": true,
            "example": 2720
          },
          "az": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Shear area in the Z direction.",
            "format": "double",
            "nullable": true,
            "example": 2010
          },
          "areaFactor": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Area modification factor.",
            "format": "double",
            "nullable": true,
            "example": 1
          },
          "torsionFactor": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Torsion modification factor.",
            "format": "double",
            "nullable": true,
            "example": 1
          },
          "iyFactor": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Iy modification factor.",
            "format": "double",
            "nullable": true,
            "example": 1
          },
          "izFactor": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Iz modification factor.",
            "format": "double",
            "nullable": true,
            "example": 1
          }
        },
        "additionalProperties": false,
        "description": "DTO for creating a library-sourced section. Structural properties (A, J, Iy, Iz, etc.)\r\nand cross-section shape data are resolved from the SPACE GASS section library by\r\n(name, library)."
      },
      "SectionPropertiesUnit": {
        "enum": [
          "ft",
          "in",
          "m",
          "cm",
          "mm"
        ],
        "type": "string",
        "description": "Unit for section properties (area, moment of inertia, etc.). Members mirror\r\nSPACE GASS `SgSectionProperties` (`NetCommon/CommonEnums.vb`)."
      },
      "SectionUpdate": {
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier of the entity to update.\r\nOptional for single updates (Id comes from route), required for bulk updates.",
            "format": "int32",
            "nullable": true,
            "example": 1
          },
          "name": {
            "type": "string",
            "description": "Section name.",
            "nullable": true,
            "example": "Custom-1"
          },
          "mark": {
            "type": "string",
            "description": "Section mark / designation.",
            "nullable": true,
            "example": "B1"
          },
          "a": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Cross-sectional area.",
            "format": "double",
            "nullable": true,
            "example": 5720
          },
          "j": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Torsion constant.",
            "format": "double",
            "nullable": true,
            "example": 158000
          },
          "iy": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Second moment of area about the principal Y axis.",
            "format": "double",
            "nullable": true,
            "example": 121000000
          },
          "iz": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Second moment of area about the principal Z axis.",
            "format": "double",
            "nullable": true,
            "example": 8970000
          },
          "ay": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Shear area in the Y direction.",
            "format": "double",
            "nullable": true,
            "example": 2720
          },
          "az": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Shear area in the Z direction.",
            "format": "double",
            "nullable": true,
            "example": 2010
          },
          "principalAngle": {
            "type": "number",
            "description": "Principal axis rotation angle.",
            "format": "double",
            "nullable": true,
            "example": 0
          },
          "areaFactor": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Area modification factor.",
            "format": "double",
            "nullable": true,
            "example": 1
          },
          "torsionFactor": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Torsion modification factor.",
            "format": "double",
            "nullable": true,
            "example": 1
          },
          "iyFactor": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Iy modification factor.",
            "format": "double",
            "nullable": true,
            "example": 1
          },
          "izFactor": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Iz modification factor.",
            "format": "double",
            "nullable": true,
            "example": 1
          }
        },
        "additionalProperties": false,
        "description": "DTO for partially updating an existing section. All fields are optional — only fields\r\npresent on the request are updated."
      },
      "SectionUserCreate": {
        "required": [
          "a",
          "ay",
          "az",
          "iy",
          "iz",
          "j",
          "name"
        ],
        "type": "object",
        "properties": {
          "id": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "Primary identifier - must be unique, no duplicates allowed.\r\nOptional - will be auto-assigned to next available number if not provided.\r\nIf provided, must not already exist in the model.",
            "format": "int32",
            "nullable": true,
            "example": 1
          },
          "name": {
            "minLength": 1,
            "type": "string",
            "description": "Section name.",
            "example": "Custom-1"
          },
          "mark": {
            "type": "string",
            "description": "Section mark / designation.",
            "nullable": true,
            "example": "B1"
          },
          "a": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Cross-sectional area.",
            "format": "double",
            "example": 5720
          },
          "j": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Torsion constant.",
            "format": "double",
            "example": 158000
          },
          "iy": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Second moment of area about the principal Y axis.",
            "format": "double",
            "example": 121000000
          },
          "iz": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Second moment of area about the principal Z axis.",
            "format": "double",
            "example": 8970000
          },
          "ay": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Shear area in the Y direction.",
            "format": "double",
            "example": 2720
          },
          "az": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Shear area in the Z direction.",
            "format": "double",
            "example": 2010
          },
          "principalAngle": {
            "type": "number",
            "description": "Principal axis rotation angle.",
            "format": "double",
            "nullable": true,
            "example": 0
          },
          "areaFactor": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Area modification factor.",
            "format": "double",
            "nullable": true,
            "example": 1
          },
          "torsionFactor": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Torsion modification factor.",
            "format": "double",
            "nullable": true,
            "example": 1
          },
          "iyFactor": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Iy modification factor.",
            "format": "double",
            "nullable": true,
            "example": 1
          },
          "izFactor": {
            "maximum": 1.7976931348623157e+308,
            "minimum": 5e-324,
            "type": "number",
            "description": "Iz modification factor.",
            "format": "double",
            "nullable": true,
            "example": 1
          }
        },
        "additionalProperties": false,
        "description": "DTO for creating a user-defined section with explicit structural properties."
      },
      "SelfWeightLoad": {
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "The load case number this load belongs to.",
            "format": "int32"
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "accelerationX": {
            "type": "number",
            "description": "Gravitational acceleration in the global X direction.",
            "format": "double"
          },
          "accelerationY": {
            "type": "number",
            "description": "Gravitational acceleration in the global Y direction.",
            "format": "double"
          },
          "accelerationZ": {
            "type": "number",
            "description": "Gravitational acceleration in the global Z direction.",
            "format": "double"
          }
        },
        "additionalProperties": false,
        "description": "DTO for reading a self-weight load entity.\r\nRepresents gravitational acceleration applied to the structure's own weight.\r\nKey: (Case) — one self-weight load per load case."
      },
      "SelfWeightLoadCreate": {
        "required": [
          "case"
        ],
        "type": "object",
        "properties": {
          "case": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The load case number to create this load in.",
            "format": "int32"
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "accelerationX": {
            "type": "number",
            "description": "Gravitational acceleration in the global X direction.",
            "format": "double",
            "nullable": true
          },
          "accelerationY": {
            "type": "number",
            "description": "Gravitational acceleration in the global Y direction.",
            "format": "double",
            "nullable": true
          },
          "accelerationZ": {
            "type": "number",
            "description": "Gravitational acceleration in the global Z direction.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for creating a new self-weight load.\r\nOnly one self-weight load is permitted per load case (case is the entire key)."
      },
      "SelfWeightLoadUpdate": {
        "type": "object",
        "properties": {
          "case": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The load case number.",
            "format": "int32",
            "nullable": true
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "accelerationX": {
            "type": "number",
            "description": "Gravitational acceleration in the global X direction.",
            "format": "double",
            "nullable": true
          },
          "accelerationY": {
            "type": "number",
            "description": "Gravitational acceleration in the global Y direction.",
            "format": "double",
            "nullable": true
          },
          "accelerationZ": {
            "type": "number",
            "description": "Gravitational acceleration in the global Z direction.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for updating an existing self-weight load.\r\nOnly fields included in the request are updated; omit a field to keep its current value."
      },
      "ServiceInfo": {
        "type": "object",
        "properties": {
          "apiPath": {
            "type": "string",
            "description": "The API base URL (e.g. https://localhost:34560/api).",
            "nullable": true
          },
          "spaceGassVersion": {
            "type": "string",
            "description": "SPACE GASS version number in format \"X.XX.XXXX (ProgramType)\"\r\n(e.g. \"15.2.100 (Commercial)\").",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Service information including API path and SPACE GASS version."
      },
      "SetGeneralRestraintRequest": {
        "type": "object",
        "properties": {
          "node": {
            "type": "integer",
            "description": "The node to promote as the general restraint, or `null` to clear.",
            "format": "int32",
            "nullable": true,
            "example": 5
          }
        },
        "additionalProperties": false,
        "description": "Request body for `POST job/structure/node-restraints/set-general`.\r\nProvide a node Id to promote that node as the general restraint\r\n(demoting every other row); pass `null` to clear the flag from every node."
      },
      "SolverType": {
        "enum": [
          "Paradise",
          "Wavefront",
          "SGX"
        ],
        "type": "string",
        "description": "Matrix solver type used by the analysis engine.\r\nInteger values mirror SPACE GASS's `SGSolverType` enum\r\n(NetCommon/CommonEnums.vb): 0=Paradise, 1=Wavefront, 2=Watcom (legacy,\r\nnot exposed), 3=SG-X (cloud, dispatched externally — not yet supported\r\nby the in-process API analysis path)."
      },
      "StaticSettings": {
        "type": "object",
        "properties": {
          "loadCases": {
            "type": "string",
            "description": "Load cases to include in the analysis, in SG list format (e.g. `\"1,3,5-10\"`).\r\nOmit or pass an empty string to include all load cases (default).\r\nMaximum 50 entries (individual numbers and ranges each count as entries).",
            "nullable": true,
            "example": "1,3,5-10"
          },
          "retainCases": {
            "type": "boolean",
            "description": "Whether to retain results of other load cases during analysis.\r\nWhen true, results from previously analysed load cases are preserved."
          },
          "checkNonExistentCases": {
            "type": "boolean",
            "description": "Whether to check for non-existent load cases referenced in the analysis.\r\nWhen true, warnings are generated for missing load cases."
          },
          "stabilizeUnrestrainedNodes": {
            "type": "boolean",
            "description": "Whether to stabilize unrestrained nodes during analysis.\r\nWhen true, temporary restraints are added to prevent instability."
          },
          "tensionCompressionOnly": {
            "$ref": "#/components/schemas/TensionCompressionOnlyMode"
          },
          "reversalIterations": {
            "type": "integer",
            "description": "Number of iterations before disabling reversal of tension/compression-only members.\r\nOnly relevant when TensionCompressionOnly is Activated.",
            "format": "int32"
          },
          "dampingFactor": {
            "type": "number",
            "description": "Cable damping factor (%).\r\nNon-linear only.",
            "format": "float"
          },
          "dampingSteps": {
            "type": "integer",
            "description": "Number of damping relaxation steps.\r\nNon-linear only.",
            "format": "int32"
          },
          "loadSteps": {
            "type": "integer",
            "description": "Number of load steps.\r\nNon-linear only.",
            "format": "int32"
          },
          "loadStepIterations": {
            "type": "integer",
            "description": "Number of iterations per load step.",
            "format": "int32"
          },
          "convergenceAccuracy": {
            "type": "number",
            "description": "Convergence accuracy (%).\r\nNon-linear only.",
            "format": "float"
          },
          "frameBucklingCheck": {
            "type": "boolean",
            "description": "Whether to perform frame buckling check."
          },
          "rotateLocalLoads": {
            "type": "boolean",
            "description": "Whether to rotate local loads with member chord rotation.\r\nNon-linear only."
          },
          "theory": {
            "$ref": "#/components/schemas/NonLinearTheory"
          },
          "matrixType": {
            "$ref": "#/components/schemas/MatrixType"
          },
          "loading": {
            "$ref": "#/components/schemas/LoadingType"
          },
          "deflectionsConvergence": {
            "type": "boolean",
            "description": "Whether to include deflections in convergence check.\r\nNon-linear only."
          },
          "residualsConvergence": {
            "type": "boolean",
            "description": "Whether to include residuals in convergence check.\r\nNon-linear only."
          },
          "pDeltaBig": {
            "type": "boolean",
            "description": "Whether to include big P-delta effect.\r\nNon-linear only."
          },
          "pDeltaSmall": {
            "type": "boolean",
            "description": "Whether to include small P-delta effect.\r\nNon-linear only."
          },
          "optimizationMethod": {
            "$ref": "#/components/schemas/OptimizationMethod"
          },
          "optimizationAxis": {
            "$ref": "#/components/schemas/OptimizationAxis"
          },
          "optimizationX": {
            "type": "number",
            "description": "X coordinate or X component of the optimization vector.\r\nOnly used when OptimizationAxis is Vector, or as angular coordinate for axis modes.",
            "format": "float"
          },
          "optimizationY": {
            "type": "number",
            "description": "Y coordinate or Y component of the optimization vector.",
            "format": "float"
          },
          "optimizationZ": {
            "type": "number",
            "description": "Z coordinate or Z component of the optimization vector.",
            "format": "float"
          },
          "solverType": {
            "$ref": "#/components/schemas/SolverType"
          },
          "drillingStiffness": {
            "type": "number",
            "description": "Drilling stiffness multiplier for plate elements.",
            "format": "float"
          },
          "plateType": {
            "$ref": "#/components/schemas/PlateType"
          },
          "steppingMethod": {
            "$ref": "#/components/schemas/SteppingMethod"
          }
        },
        "additionalProperties": false,
        "description": "Settings for Static Analysis (Linear and Non-Linear).\r\nUsed for GET (read current settings) and as the base for the update DTO.\r\nFields marked as \"Non-linear only\" are only used during non-linear static analysis."
      },
      "StaticSettingsUpdate": {
        "type": "object",
        "properties": {
          "loadCases": {
            "type": "string",
            "nullable": true
          },
          "retainCases": {
            "type": "boolean",
            "nullable": true
          },
          "checkNonExistentCases": {
            "type": "boolean",
            "nullable": true
          },
          "stabilizeUnrestrainedNodes": {
            "type": "boolean",
            "nullable": true
          },
          "tensionCompressionOnly": {
            "$ref": "#/components/schemas/TensionCompressionOnlyMode"
          },
          "reversalIterations": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "dampingFactor": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "dampingSteps": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "loadSteps": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "loadStepIterations": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "convergenceAccuracy": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "frameBucklingCheck": {
            "type": "boolean",
            "nullable": true
          },
          "rotateLocalLoads": {
            "type": "boolean",
            "nullable": true
          },
          "theory": {
            "$ref": "#/components/schemas/NonLinearTheory"
          },
          "matrixType": {
            "$ref": "#/components/schemas/MatrixType"
          },
          "loading": {
            "$ref": "#/components/schemas/LoadingType"
          },
          "deflectionsConvergence": {
            "type": "boolean",
            "nullable": true
          },
          "residualsConvergence": {
            "type": "boolean",
            "nullable": true
          },
          "pDeltaBig": {
            "type": "boolean",
            "nullable": true
          },
          "pDeltaSmall": {
            "type": "boolean",
            "nullable": true
          },
          "optimizationMethod": {
            "$ref": "#/components/schemas/OptimizationMethod"
          },
          "optimizationAxis": {
            "$ref": "#/components/schemas/OptimizationAxis"
          },
          "optimizationX": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "optimizationY": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "optimizationZ": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "solverType": {
            "$ref": "#/components/schemas/SolverType"
          },
          "drillingStiffness": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "plateType": {
            "$ref": "#/components/schemas/PlateType"
          }
        },
        "additionalProperties": false,
        "description": "Update request for Static Analysis settings.\r\nOnly fields included in the request are updated; omit a field to keep its current value.\r\nUsed by PATCH /static/settings and the POST run endpoints."
      },
      "SteelCheckSummary": {
        "type": "object",
        "properties": {
          "member": {
            "type": "integer",
            "description": "Member key (group key).",
            "format": "int32"
          },
          "flag": {
            "type": "string",
            "description": "Design check status flag.",
            "nullable": true
          },
          "section": {
            "type": "string",
            "description": "Section name used for the design check.",
            "nullable": true
          },
          "yield": {
            "type": "number",
            "description": "Yield stress. Unit: Stress (see GET /job/units).",
            "format": "float"
          },
          "totalLength": {
            "type": "number",
            "description": "Total member length. Unit: Length (see GET /job/units).",
            "format": "float"
          },
          "segmentLength": {
            "type": "number",
            "description": "Critical segment length. Unit: Length (see GET /job/units).",
            "format": "float"
          },
          "failure": {
            "type": "string",
            "description": "Failure mode description.",
            "nullable": true
          },
          "criticalCase": {
            "type": "integer",
            "description": "Load case ID of the critical case.",
            "format": "int32"
          },
          "loadFactor": {
            "type": "number",
            "description": "Design load factor (capacity ratio).",
            "format": "float"
          }
        },
        "additionalProperties": false,
        "description": "Steel member design check summary."
      },
      "SteelCheckSummaryQueryResult": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SteelCheckSummary"
            },
            "description": "The query result rows.",
            "nullable": true
          },
          "warnings": {
            "$ref": "#/components/schemas/QueryWarnings"
          }
        },
        "additionalProperties": false,
        "description": "Wrapper for analysis query results.\r\nContains the result data plus optional warnings about requested cases or modes\r\nthat produced no results (i.e. were not analysed)."
      },
      "SteppingMethod": {
        "enum": [
          "Linear",
          "Parabolic",
          "File"
        ],
        "type": "string",
        "description": "Load stepping method for non-linear static analysis."
      },
      "StiffnessDirection": {
        "enum": [
          "Tx",
          "Ty",
          "Tz",
          "Rx",
          "Ry",
          "Rz"
        ],
        "type": "string",
        "description": "Identifies one of the six DOFs on a node restraint (Tx, Ty, Tz, Rx, Ry, Rz).\r\nInteger values match SPACE GASS's `NodeRestraint.StiffnessDirectionIndex`\r\nand the offset added to `sgFRAME_RESTRAINTS_RestraintTable_Tx` (27)\r\nwhen indexing the per-DOF table fields."
      },
      "StressUnit": {
        "enum": [
          "Ksf",
          "Psf",
          "Ksi",
          "Psi",
          "MPa",
          "kPa",
          "Pa",
          "kgperm2",
          "kgpercm2",
          "kgpermm2",
          "kNperm2",
          "Npermm2"
        ],
        "type": "string",
        "description": "Stress unit. Members mirror SPACE GASS `SgStress`."
      },
      "TableMetadata": {
        "type": "object",
        "properties": {
          "tableName": {
            "type": "string",
            "description": "Human-readable title, e.g. \"Stiffness vs Deflection\".",
            "nullable": true
          },
          "columns": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FieldMetadata"
            },
            "description": "Column metadata in the same order the values appear in each row of SpaceGassApi.Models.Dtos.Common.TableDto.Rows.\r\nEach entry uses the same SpaceGassApi.Models.Dtos.Common.FieldMetadataDto shape as resource-level\r\nmetadata (`jsonName`, `dataType`, `units`, `min`, `max`,\r\n`description`).",
            "nullable": true
          },
          "maxRows": {
            "type": "integer",
            "description": "Maximum number of rows the table accepts.",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Schema metadata for a generic 2D data table — display title, per-column metadata\r\n(reusing SpaceGassApi.Models.Dtos.Common.FieldMetadataDto for parity with the rest of the API's\r\nmetadata responses), and the maximum number of rows the table accepts."
      },
      "TemperatureUnit": {
        "enum": [
          "degF",
          "degC"
        ],
        "type": "string",
        "description": "Temperature unit. Members mirror SPACE GASS `SgTemperature`."
      },
      "TensionCompressionOnlyMode": {
        "enum": [
          "Activated",
          "NoReversal",
          "Deactivated",
          "GradualActivation"
        ],
        "type": "string",
        "description": "Controls how tension-only and compression-only members are handled during analysis."
      },
      "ThermalElementType": {
        "enum": [
          "Member",
          "Plate"
        ],
        "type": "string",
        "description": "Element type discriminator for thermal loads.\r\nDetermines whether a thermal load applies to a member or plate element.\r\nMaps to SPACE GASS lookup table \"Element Type\"."
      },
      "ThermalLoad": {
        "required": [
          "elementId",
          "elementType"
        ],
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "The load case number this load belongs to.",
            "format": "int32"
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "elementId": {
            "type": "integer",
            "description": "The Id of the element this load is applied to (member number or plate number, depending on ElementType).",
            "format": "int32"
          },
          "elementType": {
            "$ref": "#/components/schemas/ThermalElementType"
          },
          "thermalLoad": {
            "type": "number",
            "description": "The uniform temperature change applied to the element.",
            "format": "double"
          },
          "yThermalGradient": {
            "type": "number",
            "description": "The thermal gradient about the local Y axis.",
            "format": "double"
          },
          "zThermalGradient": {
            "type": "number",
            "description": "The thermal gradient about the local Z axis.",
            "format": "double"
          }
        },
        "additionalProperties": false,
        "description": "DTO for reading a thermal load entity.\r\nRepresents temperature change and gradient loads applied to members or plates.\r\nComposite Id: (Case, Element, ElementType)."
      },
      "ThermalLoadBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThermalLoad"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "ThermalLoadCreate": {
        "required": [
          "case",
          "elementId",
          "elementType"
        ],
        "type": "object",
        "properties": {
          "case": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The load case number to create this load in.",
            "format": "int32"
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "elementId": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The Id of the element to apply this load to (member number or plate number, depending on ElementType).",
            "format": "int32"
          },
          "elementType": {
            "$ref": "#/components/schemas/ThermalElementType"
          },
          "thermalLoad": {
            "type": "number",
            "description": "The uniform temperature change applied to the element.",
            "format": "double",
            "nullable": true
          },
          "yThermalGradient": {
            "type": "number",
            "description": "The thermal gradient about the local Y axis.",
            "format": "double",
            "nullable": true
          },
          "zThermalGradient": {
            "type": "number",
            "description": "The thermal gradient about the local Z axis.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for creating a new thermal load.\r\nSpecify the element type to target either a member or a plate element."
      },
      "ThermalLoadElementId": {
        "type": "object",
        "properties": {
          "case": {
            "type": "integer",
            "description": "The load case number.",
            "format": "int32"
          },
          "elementId": {
            "type": "integer",
            "description": "The element Id (member number or plate number, depending on ElementType).",
            "format": "int32"
          },
          "elementType": {
            "$ref": "#/components/schemas/ThermalElementType"
          }
        },
        "additionalProperties": false,
        "description": "Composite Id object for bulk delete operations on thermal loads."
      },
      "ThermalLoadElementIdBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThermalLoadElementId"
            },
            "description": "Successfully processed items.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkError"
            },
            "description": "Errors from failed items.",
            "nullable": true
          },
          "errorsTruncated": {
            "type": "boolean",
            "description": "True when the bulk operation stopped accumulating errors after reaching\r\nSpaceGassApi.Models.Dtos.Entity.BulkResultDto`1.ErrorMessageCap. Further failures may exist beyond what is reported."
          }
        },
        "additionalProperties": false,
        "description": "Result of a bulk operation."
      },
      "ThermalLoadUpdate": {
        "type": "object",
        "properties": {
          "case": {
            "maximum": 2147483647,
            "minimum": 1,
            "type": "integer",
            "description": "The load case number.",
            "format": "int32",
            "nullable": true
          },
          "loadCategory": {
            "type": "integer",
            "description": "Load category for grouping/organization.",
            "format": "int32",
            "nullable": true
          },
          "elementId": {
            "type": "integer",
            "description": "The element Id (member number or plate number).",
            "format": "int32",
            "nullable": true
          },
          "elementType": {
            "$ref": "#/components/schemas/ThermalElementType"
          },
          "thermalLoad": {
            "type": "number",
            "description": "The uniform temperature change applied to the element.",
            "format": "double",
            "nullable": true
          },
          "yThermalGradient": {
            "type": "number",
            "description": "The thermal gradient about the local Y axis.",
            "format": "double",
            "nullable": true
          },
          "zThermalGradient": {
            "type": "number",
            "description": "The thermal gradient about the local Z axis.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DTO for updating an existing thermal load.\r\nOnly fields included in the request are updated; omit a field to keep its current value."
      },
      "TranslationUnit": {
        "enum": [
          "ft",
          "inch",
          "m",
          "cm",
          "mm"
        ],
        "type": "string",
        "description": "Translation (displacement) unit. Members mirror SPACE GASS `SgTranslation`.\r\nSG uses `inch` here (not `in`) to dodge the VB reserved word; we mirror\r\nthat so the wire token stays `\"inch\"`."
      },
      "Units": {
        "type": "object",
        "properties": {
          "length": {
            "$ref": "#/components/schemas/LengthUnit"
          },
          "sectionProperties": {
            "$ref": "#/components/schemas/SectionPropertiesUnit"
          },
          "materialStrength": {
            "$ref": "#/components/schemas/MaterialStrengthUnit"
          },
          "massDensity": {
            "$ref": "#/components/schemas/MassDensityUnit"
          },
          "temperature": {
            "$ref": "#/components/schemas/TemperatureUnit"
          },
          "force": {
            "$ref": "#/components/schemas/ForceUnit"
          },
          "moment": {
            "$ref": "#/components/schemas/MomentUnit"
          },
          "mass": {
            "$ref": "#/components/schemas/MassUnit"
          },
          "acceleration": {
            "$ref": "#/components/schemas/AccelerationUnit"
          },
          "translation": {
            "$ref": "#/components/schemas/TranslationUnit"
          },
          "stress": {
            "$ref": "#/components/schemas/StressUnit"
          }
        },
        "additionalProperties": false,
        "description": "Unit settings for the current job."
      },
      "ValidationError": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string",
            "description": "Field or property name that caused the error",
            "nullable": true
          },
          "message": {
            "type": "string",
            "description": "Error message",
            "nullable": true
          },
          "code": {
            "type": "string",
            "description": "Error code for this specific validation",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Individual validation error"
      },
      "VerticalAxis": {
        "enum": [
          "YAxis",
          "ZAxis"
        ],
        "type": "string",
        "description": "Vertical (gravity) axis direction for the job.\r\nDetermines which global axis is treated as the vertical/gravity direction.\r\nMaps to SPACE GASS CommonEnums.SGVerticalAxis (YAxis=2, ZAxis=3).\r\nOnly YAxis and ZAxis are valid choices in SPACE GASS."
      }
    }
  },
  "tags": [
    {
      "name": "File",
      "description": "Read-only file inspection (no open job required)"
    },
    {
      "name": "Import",
      "description": "Import data into the current job"
    },
    {
      "name": "Job",
      "description": "Job lifecycle management — create, open, save, close, and check status"
    },
    {
      "name": "Units",
      "description": "Unit settings sub-resource of the job"
    },
    {
      "name": "Settings",
      "description": "Job-level settings sub-resource (vertical axis, etc.)"
    },
    {
      "name": "Sections",
      "description": "Structural sections"
    },
    {
      "name": "Materials",
      "description": "Structural materials"
    },
    {
      "name": "Nodes",
      "description": "Structural nodes"
    },
    {
      "name": "Node Constraints",
      "description": "Master-slave constraints between nodes"
    },
    {
      "name": "Node Restraints",
      "description": "Node boundary conditions and spring stiffness"
    },
    {
      "name": "Members",
      "description": "Structural members"
    },
    {
      "name": "Member Offsets",
      "description": "Member rigid end zones (offsets at each end)"
    },
    {
      "name": "Plates",
      "description": "Structural plates"
    },
    {
      "name": "Plate Cuts",
      "description": "Structural plate cuts"
    },
    {
      "name": "Plate Strips",
      "description": "Structural plate strips"
    },
    {
      "name": "Load Cases",
      "description": "Load cases"
    },
    {
      "name": "Combination Load Cases",
      "description": "Combination load cases"
    },
    {
      "name": "Load Case Groups",
      "description": "Load case groups"
    },
    {
      "name": "Load Categories",
      "description": "Load categories"
    },
    {
      "name": "Node Loads",
      "description": "Concentrated forces and moments applied at nodes"
    },
    {
      "name": "Node Displacements",
      "description": "Prescribed displacements and rotations applied at nodes"
    },
    {
      "name": "Member Concentrated Loads",
      "description": "Concentrated forces and moments applied at a point along a member"
    },
    {
      "name": "Member Distributed Loads",
      "description": "Distributed forces applied along a member"
    },
    {
      "name": "Member Distributed Moments",
      "description": "Distributed moments applied along a member"
    },
    {
      "name": "Member Prestress Loads",
      "description": "Prestress forces applied to members"
    },
    {
      "name": "Plate Pressure Loads",
      "description": "Distributed pressure loads applied to plates"
    },
    {
      "name": "Lumped Mass Loads",
      "description": "Lumped masses and rotational inertias applied at nodes"
    },
    {
      "name": "Self Weight Loads",
      "description": "Gravitational acceleration loads applied to the structure's own weight"
    },
    {
      "name": "Thermal Loads",
      "description": "Temperature change and gradient loads applied to members and plates"
    },
    {
      "name": "Analysis",
      "description": "Analysis runs and settings"
    },
    {
      "name": "Static Results",
      "description": "Static analysis results (nodes, members, plates)"
    },
    {
      "name": "Buckling Results",
      "description": "Buckling analysis results"
    },
    {
      "name": "Dynamic Results",
      "description": "Dynamic analysis results"
    },
    {
      "name": "Steel Design Results",
      "description": "Steel member design results"
    },
    {
      "name": "Errors",
      "description": "Diagnostic error messages"
    },
    {
      "name": "License",
      "description": "Licensing status for the API instance"
    },
    {
      "name": "Service",
      "description": "API service information and version details"
    },
    {
      "name": "Space Gass API"
    }
  ],
  "x-tagGroups": [
    {
      "name": "File",
      "tags": [
        "File"
      ]
    },
    {
      "name": "Import",
      "tags": [
        "Import"
      ]
    },
    {
      "name": "Job",
      "tags": [
        "Job",
        "Units",
        "Settings"
      ]
    },
    {
      "name": "Properties",
      "tags": [
        "Sections",
        "Materials"
      ]
    },
    {
      "name": "Structure",
      "tags": [
        "Nodes",
        "Node Constraints",
        "Node Restraints",
        "Members",
        "Member Offsets",
        "Plates",
        "Plate Cuts",
        "Plate Strips"
      ]
    },
    {
      "name": "Cases",
      "tags": [
        "Load Cases",
        "Combination Load Cases",
        "Load Case Groups",
        "Load Categories"
      ]
    },
    {
      "name": "Loads",
      "tags": [
        "Node Loads",
        "Node Displacements",
        "Member Concentrated Loads",
        "Member Distributed Loads",
        "Member Distributed Moments",
        "Member Prestress Loads",
        "Plate Pressure Loads",
        "Lumped Mass Loads",
        "Self Weight Loads",
        "Thermal Loads"
      ]
    },
    {
      "name": "Analysis",
      "tags": [
        "Analysis"
      ]
    },
    {
      "name": "Query",
      "tags": [
        "Static Results",
        "Buckling Results",
        "Dynamic Results",
        "Steel Design Results"
      ]
    },
    {
      "name": "Errors",
      "tags": [
        "Errors"
      ]
    },
    {
      "name": "Licensing",
      "tags": [
        "License"
      ]
    },
    {
      "name": "Service",
      "tags": [
        "Service"
      ]
    }
  ]
}