{
  "openapi": "3.1.1",
  "info": {
    "title": "Twinworks Buffer & Parameter Sweep API",
    "version": "1.0.0",
    "summary": "Sweep a buffer size (or any parameter) and get the throughput curve with confidence intervals.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://twinworksbuffersweep.usefulweb.site"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Sweep a buffer size (or any parameter) and get the throughput curve with confidence intervals.",
        "description": "Runs a Twinworks factory model repeatedly while one parameter changes — typically the capacity of a buffer from 1 to 10 places, but also servers, cycle times, MTTR, batch sizes, conveyor speed or the number of operators. Returns throughput, lead time and WIP per value with confidence intervals, plus the knee point where extra capacity stops paying off.\n\nMethodology:\n- For each parameter value the model is copied, the parameter is set and the model is simulated with the same seeds (common random numbers), so differences between values are not masked by random noise.\n- Throughput, lead time and WIP are reported as Student-t intervals across replications.\n- Knee point = smallest value whose mean throughput is at least 98 % of the best mean throughput in the sweep: beyond it, more buffer mostly adds WIP and lead time (Little’s law).\n\nThe sweep varies one parameter at a time; interactions between buffers are not optimised jointly.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "twinworks_buffer_sweep",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TwinworksBufferSweepInput"
              },
              "examples": {
                "example1": {
                  "summary": "Bottleneck demo: buffer B2 from 1 to 10",
                  "value": {
                    "template": "bottleneck-buffer-sizing",
                    "target": "B2",
                    "parameter": "capacity",
                    "from": 1,
                    "to": 10,
                    "step": 1,
                    "replications": 4,
                    "horizonHours": 6
                  }
                },
                "example2": {
                  "summary": "3-station line: arrival interval 45…70 s",
                  "value": {
                    "template": "three-station-line",
                    "target": "SRC1",
                    "parameter": "interval.mean",
                    "from": 45,
                    "to": 70,
                    "step": 5,
                    "replications": 3
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TwinworksBufferSweepResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "TwinworksBufferSweepInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "model": {
            "title": "Model or project JSON",
            "description": "A Twinworks project (.twinworks.json, format \"twinworks-project\") or a bare model with \"nodes\" and \"links\". Times in seconds, lengths in metres. Leave empty and pick a template instead.",
            "type": "string",
            "maxLength": 400000
          },
          "template": {
            "title": "Or start from a template",
            "type": "string",
            "enum": [
              "",
              "three-station-line",
              "line-with-failures",
              "assembly-two-feeders",
              "job-shop-routings",
              "bottleneck-buffer-sizing",
              "conveyor-packaging",
              "mm1-validation"
            ],
            "default": ""
          },
          "target": {
            "title": "Object id",
            "description": "Id of the buffer/machine/conveyor/source to change, or pool:<id> for an operator pool. Default for the bottleneck template: B2.",
            "type": "string",
            "maxLength": 60
          },
          "parameter": {
            "title": "Parameter",
            "type": "string",
            "enum": [
              "capacity",
              "servers",
              "cycle.value",
              "cycle.mean",
              "batchSize",
              "interval.mean",
              "interval.value",
              "speed",
              "length",
              "failure.mttr.mean",
              "failure.mtbf.mean",
              "setup.value",
              "scrapPct",
              "count"
            ],
            "default": "capacity"
          },
          "from": {
            "title": "From",
            "type": "number",
            "minimum": 0,
            "maximum": 10000000,
            "default": 1
          },
          "to": {
            "title": "To",
            "type": "number",
            "minimum": 0,
            "maximum": 10000000,
            "default": 10
          },
          "step": {
            "title": "Step",
            "type": "number",
            "minimum": 0.0001,
            "maximum": 10000000,
            "default": 1
          },
          "replications": {
            "title": "Replications per value",
            "type": "integer",
            "minimum": 1,
            "maximum": 20,
            "default": 4
          },
          "horizonHours": {
            "title": "Run length per replication",
            "description": "Overrides the model setting.",
            "type": "number",
            "minimum": 0.1,
            "maximum": 2400,
            "x-unit": "h"
          }
        },
        "required": []
      },
      "TwinworksBufferSweepResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "required": [
              "target",
              "parameter",
              "points",
              "knee",
              "bestThroughput"
            ],
            "properties": {
              "target": {
                "type": "string"
              },
              "parameter": {
                "type": "string"
              },
              "points": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "value",
                    "throughput",
                    "leadTime",
                    "wip"
                  ],
                  "properties": {
                    "value": {
                      "type": "number"
                    },
                    "throughput": {
                      "type": "object",
                      "required": [
                        "mean",
                        "lo",
                        "hi",
                        "halfWidth",
                        "n"
                      ],
                      "properties": {
                        "mean": {
                          "type": "number"
                        },
                        "lo": {
                          "type": "number"
                        },
                        "hi": {
                          "type": "number"
                        },
                        "halfWidth": {
                          "type": "number"
                        },
                        "n": {
                          "type": "integer"
                        }
                      }
                    },
                    "leadTime": {
                      "type": "object",
                      "required": [
                        "mean",
                        "lo",
                        "hi",
                        "halfWidth",
                        "n"
                      ],
                      "properties": {
                        "mean": {
                          "type": "number"
                        },
                        "lo": {
                          "type": "number"
                        },
                        "hi": {
                          "type": "number"
                        },
                        "halfWidth": {
                          "type": "number"
                        },
                        "n": {
                          "type": "integer"
                        }
                      }
                    },
                    "wip": {
                      "type": "object",
                      "required": [
                        "mean",
                        "lo",
                        "hi",
                        "halfWidth",
                        "n"
                      ],
                      "properties": {
                        "mean": {
                          "type": "number"
                        },
                        "lo": {
                          "type": "number"
                        },
                        "hi": {
                          "type": "number"
                        },
                        "halfWidth": {
                          "type": "number"
                        },
                        "n": {
                          "type": "integer"
                        }
                      }
                    },
                    "costPerGoodPart": {
                      "type": "object",
                      "required": [
                        "mean",
                        "lo",
                        "hi",
                        "halfWidth",
                        "n"
                      ],
                      "properties": {
                        "mean": {
                          "type": "number"
                        },
                        "lo": {
                          "type": "number"
                        },
                        "hi": {
                          "type": "number"
                        },
                        "halfWidth": {
                          "type": "number"
                        },
                        "n": {
                          "type": "integer"
                        }
                      }
                    },
                    "bottleneck": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                }
              },
              "knee": {
                "type": [
                  "number",
                  "null"
                ],
                "description": "Smallest value reaching 98 % of the best mean throughput."
              },
              "bestThroughput": {
                "type": "number"
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}