{
  "openapi": "3.0.3",
  "info": {
    "termsOfService": "https://smartcut.dev/terms",
    "license": {
      "name": "MIT (specification document only — API use governed by the Terms)",
      "url": "https://github.com/jgmedialtd/smartcut-api/blob/main/LICENSE"
    },
    "x-logo": {
      "url": "https://smartcut.dev/images/logo.svg",
      "altText": "SmartCut"
    },
    "title": "SmartCut API V2",
    "version": "V2",
    "description": "A modern, performant cut cutlist optimization API.\n\n**V2 Features:**\n- Separate saw configuration object\n- Dual side naming support (x1/x2/y1/y2 or l1/l2/w1/w2)\n- Hybrid banding support (top-level or extras structure)\n- Webhook support for async results\n- Custom data fields\n- Enhanced metadata with material summaries\n\n**Backward Compatibility:** V2 accepts both legacy and modern formats.",
    "contact": {
      "name": "SmartCut",
      "url": "https://api.smartcut.dev"
    }
  },
  "externalDocs": {
    "description": "Specification, runnable examples and MCP configuration",
    "url": "https://github.com/jgmedialtd/smartcut-api"
  },
  "paths": {
    "/v2/calculate": {
      "post": {
        "tags": [
          "Calculations"
        ],
        "summary": "Kick off the calculations",
        "description": "The response will contain a calculation ID. Please setup a webhook in your account to receive the result.\n\nIf you cannot use a webhook, this id can be used to obtain the results.\n\nResults will not be available immediately.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CalculateRequestV2"
              },
              "examples": {
                "basic": {
                  "summary": "Basic guillotine request",
                  "value": {
                    "saw": {
                      "cutType": "guillotine",
                      "cutPreference": "l",
                      "bladeWidth": 3,
                      "stockType": "sheet"
                    },
                    "stock": [
                      {
                        "l": 2400,
                        "w": 1200,
                        "t": 18,
                        "material": "Plywood",
                        "q": 1
                      }
                    ],
                    "parts": [
                      {
                        "l": 400,
                        "w": 300,
                        "t": 18,
                        "material": "Plywood",
                        "q": 5
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Calculation accepted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "jobId": {
                      "type": "number",
                      "description": "Calculation job identifier used to obtain result"
                    }
                  },
                  "required": [
                    "jobId"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad request. See the response for details.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "You have not been correctly authenticated."
          },
          "403": {
            "description": "Not allowed - see the response body for more information."
          },
          "429": {
            "description": "You are making requests too quickly - retry after the indicated time."
          },
          "500": {
            "description": "There has been a server error."
          },
          "503": {
            "description": "Server undergoing maintenance."
          }
        }
      }
    },
    "/result/ready": {
      "get": {
        "tags": [
          "Results"
        ],
        "summary": "Check if the calculation has finished",
        "description": "Please setup a webhook in your account to receive the result.\n\nIf you cannot use a webhook, once you have received the job id, you can check if the result is ready by polling this end point.\nWe suggest polling every couple of seconds - please do not hammer the server with poll requests.\n\nThe time taken for a calculation to be ready depends on the calculation complexity and the server load.\n\nOnce you get a 200 response, you're ready to obtain the result.",
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Job identifier"
          }
        ],
        "responses": {
          "200": {
            "description": "The result is ready."
          },
          "400": {
            "description": "Bad request. See the response for details."
          },
          "401": {
            "description": "You have not been correctly authenticated."
          },
          "404": {
            "description": "We cannot find your result yet."
          },
          "410": {
            "description": "Your job or result is no longer available - please stop sending requests."
          },
          "429": {
            "description": "You are making requests too quickly - retry after the indicated time."
          },
          "500": {
            "description": "There has been a server error."
          }
        }
      }
    },
    "/result": {
      "get": {
        "tags": [
          "Results"
        ],
        "summary": "Retrieve the calculation result",
        "description": "Once ready, fetch the complete optimization result.",
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Job identifier"
          }
        ],
        "responses": {
          "200": {
            "description": "Result retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResultResponseV2"
                }
              }
            }
          },
          "404": {
            "description": "Result not found"
          },
          "410": {
            "description": "Result no longer available"
          },
          "500": {
            "description": "Server error"
          }
        }
      }
    },
    "/export": {
      "get": {
        "tags": [
          "Exports"
        ],
        "summary": "Export result in various formats",
        "description": "Export as PDF, CSV, PTX, DXF, or SVG file",
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Job ID to export"
          },
          {
            "name": "format",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "pdf",
                "csv",
                "ptx",
                "dxf",
                "svg"
              ]
            },
            "description": "Export format"
          },
          {
            "name": "option",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "layout",
                "parts",
                "machining",
                "cuts"
              ]
            },
            "description": "Export variant: layout (full optimization), parts (parts list), machining (machining details), cuts (cut list)"
          },
          {
            "name": "units",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Unit system for DXF/SVG exports (e.g., mm, in)"
          },
          {
            "name": "numberFormat",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "decimal",
                "fraction"
              ]
            },
            "description": "Number format for PDF exports (also accepts unitType or units as aliases)"
          },
          {
            "name": "credit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Custom credit text for PDF exports (requires whiteLabel option)"
          },
          {
            "name": "cropLength",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "y",
                "n"
              ]
            },
            "description": "Crop stock length in PDF exports (y = crop, n = full length)"
          },
          {
            "name": "tables",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "y",
                "n"
              ]
            },
            "description": "Show/hide tables in PDF exports (n = hide tables)"
          }
        ],
        "responses": {
          "200": {
            "description": "File export successful"
          },
          "404": {
            "description": "Result not found"
          }
        }
      }
    },
    "/labels": {
      "post": {
        "tags": [
          "Labels"
        ],
        "summary": "Generate printable part labels",
        "description": "Generate customizable PDF labels for parts with options for layout, formatting, and content",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "Job ID to generate labels for"
                  },
                  "units": {
                    "type": "string",
                    "enum": [
                      "pt",
                      "px",
                      "in",
                      "mm",
                      "cm",
                      "ex",
                      "em",
                      "pc"
                    ],
                    "default": "mm",
                    "description": "Measurement units for labels"
                  },
                  "format": {
                    "type": "string",
                    "default": "a4",
                    "description": "Paper size (e.g., a4, letter)"
                  },
                  "orientation": {
                    "type": "string",
                    "enum": [
                      "portrait",
                      "landscape"
                    ],
                    "default": "portrait",
                    "description": "Page orientation"
                  },
                  "cols": {
                    "type": "number",
                    "default": 4,
                    "description": "Number of columns per page"
                  },
                  "rows": {
                    "type": "number",
                    "default": 4,
                    "description": "Number of rows per page"
                  },
                  "pageMarginH": {
                    "type": "number",
                    "default": 14,
                    "description": "Horizontal page margin"
                  },
                  "pageMarginW": {
                    "type": "number",
                    "default": 14,
                    "description": "Vertical page margin"
                  },
                  "padding": {
                    "type": "number",
                    "default": 0,
                    "description": "Padding around each label"
                  },
                  "fontSize": {
                    "type": "number",
                    "default": 10,
                    "description": "Base font size"
                  },
                  "largeFontSize": {
                    "type": "number",
                    "default": 12,
                    "description": "Large text font size"
                  },
                  "banding": {
                    "type": "boolean",
                    "default": true,
                    "description": "Show edge banding information"
                  },
                  "showId": {
                    "type": "boolean",
                    "default": true,
                    "description": "Show part IDs"
                  },
                  "stockId": {
                    "type": "boolean",
                    "default": true,
                    "description": "Show stock IDs"
                  },
                  "boxes": {
                    "type": "boolean",
                    "default": true,
                    "description": "Draw boxes around labels"
                  },
                  "includeOffcuts": {
                    "type": "boolean",
                    "default": true,
                    "description": "Include offcut labels"
                  },
                  "newStockNewPage": {
                    "type": "boolean",
                    "default": false,
                    "description": "Start new page for each stock item"
                  },
                  "materials": {
                    "type": "boolean",
                    "default": true,
                    "description": "Show material names"
                  },
                  "companyName": {
                    "type": "string",
                    "description": "Company name to display on labels"
                  },
                  "numberFormat": {
                    "type": "string",
                    "enum": [
                      "decimal",
                      "fraction"
                    ],
                    "description": "Number format for dimensions"
                  },
                  "decimalPlaces": {
                    "type": "number",
                    "description": "Number of decimal places (for decimal format)"
                  },
                  "fractionRoundTo": {
                    "type": "number",
                    "description": "Fraction denominator to round to (for fraction format)"
                  }
                },
                "required": [
                  "id",
                  "companyName",
                  "numberFormat",
                  "decimalPlaces",
                  "fractionRoundTo"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Labels PDF generated successfully - returns URL to download the PDF",
            "content": {
              "application/json": {
                "schema": {
                  "type": "string",
                  "description": "URL to download the generated labels PDF"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (missing ID, no parts found, etc.)"
          },
          "500": {
            "description": "Error generating labels"
          }
        }
      }
    },
    "/calls": {
      "get": {
        "tags": [
          "Stats"
        ],
        "summary": "Get API usage statistics",
        "responses": {
          "200": {
            "description": "Usage statistics retrieved",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "used": {
                      "type": "number"
                    },
                    "limit": {
                      "type": "number"
                    },
                    "remaining": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "Authorization",
        "description": "Example: `Authorization: <your-api-key>`. Obtain your key from https://smartcut.dev/account"
      }
    },
    "schemas": {
      "CalculateRequestV2": {
        "type": "object",
        "description": "V2 API calculation request with separate saw object",
        "properties": {
          "saw": {
            "$ref": "#/components/schemas/SawV2"
          },
          "stock": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StockV2"
            },
            "description": "Array of stock items"
          },
          "parts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PartV2"
            },
            "description": "Array of parts to cut"
          },
          "webhook": {
            "type": "string",
            "format": "uri",
            "description": "Webhook URL to receive results"
          }
        },
        "required": [
          "saw",
          "stock",
          "parts"
        ]
      },
      "SawV2": {
        "type": "object",
        "description": "Saw configuration (separate object in V2)",
        "properties": {
          "bladeWidth": {
            "type": "number",
            "minimum": 0,
            "description": "Blade kerf width"
          },
          "stockType": {
            "type": "string",
            "enum": [
              "sheet",
              "linear",
              "roll"
            ]
          },
          "cutType": {
            "type": "string",
            "enum": [
              "efficiency",
              "guillotine",
              "beam"
            ]
          },
          "cutPreference": {
            "type": "string",
            "enum": [
              "l",
              "w"
            ]
          },
          "guillotineOptions": {
            "type": "object",
            "properties": {
              "strategy": {
                "type": "string",
                "enum": [
                  "efficiency",
                  "time"
                ]
              },
              "maxPhase": {
                "type": "integer",
                "minimum": 0,
                "default": 0
              },
              "headCuts": {
                "type": "boolean",
                "default": false
              }
            }
          },
          "efficiencyOptions": {
            "type": "object",
            "properties": {
              "primaryCompression": {
                "type": "string",
                "enum": [
                  "y",
                  "x"
                ]
              }
            }
          },
          "stackHeight": {
            "type": "number"
          },
          "options": {
            "type": "object",
            "properties": {
              "stockSelection": {
                "type": "string",
                "enum": [
                  "efficiency",
                  "smallest"
                ],
                "default": "efficiency"
              },
              "minSpacing": {
                "type": "number",
                "minimum": 0
              },
              "stackingMode": {
                "type": "string",
                "enum": [
                  "dimensions",
                  "identical"
                ],
                "default": "dimensions"
              }
            }
          }
        },
        "required": [
          "bladeWidth",
          "stockType"
        ]
      },
      "StockV2": {
        "type": "object",
        "description": "Stock is the raw material you are cutting from ",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "l": {
            "type": "number",
            "minimum": 0
          },
          "w": {
            "type": "number",
            "minimum": 0
          },
          "t": {
            "type": "number",
            "nullable": true,
            "minimum": 0
          },
          "material": {
            "type": "string"
          },
          "q": {
            "type": "integer",
            "minimum": 1,
            "default": 1
          },
          "autoAdd": {
            "type": "boolean",
            "default": false
          },
          "grain": {
            "type": "string",
            "enum": [
              "l",
              "w",
              ""
            ],
            "nullable": true
          },
          "trim": {
            "$ref": "#/components/schemas/TrimAPI",
            "description": "Trim in V2 format (x1/x2/y1/y2)"
          },
          "allowExactFitShapes": {
            "type": "boolean",
            "default": false
          },
          "cost": {
            "type": "number",
            "minimum": 0
          },
          "notes": {
            "type": "string",
            "maxLength": 200,
            "nullable": true
          },
          "infiniteLength": {
            "type": "boolean",
            "default": false,
            "description": "For roll stock"
          }
        },
        "required": [
          "l",
          "w"
        ]
      },
      "PartV2": {
        "type": "object",
        "description": "Parts are what you are cutting from the stock",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "l": {
            "type": "number",
            "minimum": 0
          },
          "w": {
            "type": "number",
            "minimum": 0
          },
          "t": {
            "type": "number",
            "nullable": true,
            "minimum": 0
          },
          "material": {
            "type": "string"
          },
          "q": {
            "type": "integer",
            "minimum": 1,
            "default": 1
          },
          "trim": {
            "description": "Trim in V2 format (x1/x2/y1/y2)",
            "$ref": "#/components/schemas/TrimAPI"
          },
          "banding": {
            "$ref": "#/components/schemas/SideValues"
          },
          "finish": {
            "type": "object",
            "properties": {
              "a": {
                "type": "string"
              },
              "b": {
                "type": "string"
              }
            }
          },
          "orientationLock": {
            "type": "string",
            "enum": [
              "l",
              "w",
              ""
            ],
            "nullable": true
          },
          "upDirection": {
            "type": "string",
            "enum": [
              "l",
              "w",
              ""
            ],
            "nullable": true
          },
          "stockLock": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 0
            },
            "nullable": true,
            "default": null,
            "description": "Lock part to specific stock indices"
          },
          "notes": {
            "type": "string",
            "maxLength": 200,
            "nullable": true
          },
          "customData": {
            "type": "object",
            "description": "Custom user-defined data",
            "additionalProperties": {
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "number"
                },
                {
                  "type": "boolean"
                }
              ]
            }
          }
        },
        "required": [
          "l",
          "w"
        ]
      },
      "TrimAPI": {
        "type": "object",
        "description": "Trim in API coordinate system (x1/x2/y1/y2)",
        "properties": {
          "x1": {
            "type": "number",
            "minimum": 0,
            "default": 0
          },
          "x2": {
            "type": "number",
            "minimum": 0,
            "default": 0
          },
          "y1": {
            "type": "number",
            "minimum": 0,
            "default": 0
          },
          "y2": {
            "type": "number",
            "minimum": 0,
            "default": 0
          }
        }
      },
      "SideValues": {
        "type": "object",
        "description": "Side values in V2 format (x/y coordinate system)",
        "properties": {
          "x1": {
            "oneOf": [
              {
                "type": "boolean"
              },
              {
                "type": "string"
              }
            ]
          },
          "x2": {
            "oneOf": [
              {
                "type": "boolean"
              },
              {
                "type": "string"
              }
            ]
          },
          "y1": {
            "oneOf": [
              {
                "type": "boolean"
              },
              {
                "type": "string"
              }
            ]
          },
          "y2": {
            "oneOf": [
              {
                "type": "boolean"
              },
              {
                "type": "string"
              }
            ]
          }
        }
      },
      "StockAnalysisV2": {
        "type": "object",
        "description": "Analysis metrics for stock item",
        "properties": {
          "partArea": {
            "type": "number",
            "description": "Total area of parts on this stock"
          },
          "areaEfficiency": {
            "type": "number",
            "description": "Percentage efficiency of this stock"
          },
          "totalParts": {
            "type": "integer",
            "description": "Number of parts on this stock"
          },
          "numberOfCuts": {
            "type": "integer",
            "description": "Total number of cuts on this stock"
          },
          "stackedNumberOfCuts": {
            "type": "integer",
            "description": "Total cuts assuming stacked stock are cut once"
          },
          "cutLength": {
            "type": "number",
            "description": "Total length of cuts on this stock"
          },
          "stackedCutLength": {
            "type": "number",
            "description": "Total cut length assuming stacked stock are cut once"
          },
          "bandingLength": {
            "type": "number",
            "description": "Total banding length for parts on this stock"
          },
          "rollLength": {
            "type": "number",
            "description": "Roll length used (for roll stock)"
          }
        }
      },
      "CutV2": {
        "type": "object",
        "description": "Cut instruction",
        "properties": {
          "x1": {
            "type": "number",
            "description": "Cut start X"
          },
          "x2": {
            "type": "number",
            "description": "Cut end X"
          },
          "y1": {
            "type": "number",
            "description": "Cut start Y"
          },
          "y2": {
            "type": "number",
            "description": "Cut end Y"
          },
          "guillotine": {
            "type": "boolean",
            "description": "Whether this is a guillotine cut (edge to edge)"
          },
          "isTrim": {
            "type": "boolean",
            "description": "Whether this is a trim cut"
          },
          "stock": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              }
            }
          },
          "order": {
            "type": "number",
            "description": "Suggested cut order (if provided)"
          }
        }
      },
      "OffcutV2": {
        "type": "object",
        "description": "Remaining offcut piece",
        "properties": {
          "x": {
            "type": "number",
            "description": "X coordinate"
          },
          "y": {
            "type": "number",
            "description": "Y coordinate"
          },
          "l": {
            "type": "number",
            "description": "Offcut length"
          },
          "w": {
            "type": "number",
            "description": "Offcut width"
          },
          "t": {
            "type": "number",
            "description": "Offcut thickness"
          },
          "q": {
            "type": "number",
            "description": "Quantity of this offcut"
          },
          "material": {
            "type": "string",
            "description": "Material reference"
          },
          "stock": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "description": "Stock ID"
              }
            }
          },
          "grain": {
            "type": "string",
            "enum": [
              "l",
              "w",
              ""
            ],
            "nullable": true,
            "description": "Grain direction"
          },
          "type": {
            "type": "string",
            "description": "Material type"
          }
        }
      },
      "ResultResponseV2": {
        "type": "object",
        "description": "Complete V2 API response",
        "properties": {
          "jobId": {
            "type": "number",
            "description": "Job identifier"
          },
          "saw": {
            "$ref": "#/components/schemas/SawV2"
          },
          "stock": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ResultStockV2"
            }
          },
          "parts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ResultPartV2"
            }
          },
          "cuts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CutV2"
            }
          },
          "offcuts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OffcutV2"
            }
          },
          "unusableParts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UnusablePartV2"
            }
          },
          "metadata": {
            "$ref": "#/components/schemas/MetadataV2"
          }
        },
        "required": [
          "jobId",
          "stock",
          "parts"
        ]
      },
      "ResultStockV2": {
        "type": "object",
        "description": "Result stock (output from mapper)",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "duplicate": {
            "type": "boolean"
          },
          "used": {
            "type": "boolean"
          },
          "l": {
            "type": "number"
          },
          "w": {
            "type": "number"
          },
          "t": {
            "type": "number",
            "nullable": true
          },
          "material": {
            "type": "string"
          },
          "grain": {
            "type": "string",
            "enum": [
              "l",
              "w",
              ""
            ],
            "nullable": true
          },
          "trim": {
            "$ref": "#/components/schemas/TrimAPI"
          },
          "type": {
            "type": "string",
            "description": "Stock type (e.g., \"sheet\", \"length\")"
          },
          "cost": {
            "type": "number"
          },
          "notes": {
            "type": "string"
          },
          "analysis": {
            "$ref": "#/components/schemas/StockAnalysisV2"
          },
          "stack": {
            "type": "integer",
            "description": "Stack count for this stock"
          }
        },
        "required": [
          "id",
          "l",
          "w",
          "used",
          "duplicate",
          "type",
          "stack"
        ]
      },
      "ResultPartV2": {
        "type": "object",
        "description": "Result part (output from mapper)",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "duplicate": {
            "type": "boolean"
          },
          "added": {
            "type": "boolean"
          },
          "x": {
            "type": "number"
          },
          "y": {
            "type": "number"
          },
          "l": {
            "type": "number"
          },
          "w": {
            "type": "number"
          },
          "t": {
            "type": "number"
          },
          "material": {
            "type": "string"
          },
          "rot": {
            "type": "boolean"
          },
          "notes": {
            "type": "string"
          },
          "banding": {
            "type": "object",
            "properties": {
              "x1": {
                "type": "boolean",
                "description": "Banding on x1 edge"
              },
              "x2": {
                "type": "boolean",
                "description": "Banding on x2 edge"
              },
              "y1": {
                "type": "boolean",
                "description": "Banding on y1 edge"
              },
              "y2": {
                "type": "boolean",
                "description": "Banding on y2 edge"
              }
            }
          },
          "finish": {
            "type": "object",
            "properties": {
              "a": {
                "type": "string",
                "description": "Finish for face A"
              },
              "b": {
                "type": "string",
                "description": "Finish for face B"
              }
            }
          },
          "stock": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "description": "Stock ID reference"
              }
            },
            "required": [
              "id"
            ]
          },
          "customData": {
            "type": "object",
            "additionalProperties": true,
            "description": "Custom user data"
          }
        },
        "required": [
          "id",
          "l",
          "w",
          "x",
          "y",
          "rot",
          "added",
          "duplicate"
        ]
      },
      "UnusablePartV2": {
        "type": "object",
        "description": "Part that could not be placed",
        "properties": {
          "id": {
            "type": "string",
            "description": "Part ID"
          },
          "issues": {
            "type": "string",
            "description": "Reason part could not be placed"
          }
        },
        "required": [
          "id",
          "issues"
        ]
      },
      "MetadataV2": {
        "type": "object",
        "description": "Enhanced V2 metadata with material summary",
        "properties": {
          "totalEfficiency": {
            "type": "number",
            "default": 0
          },
          "totalStockArea": {
            "type": "number",
            "default": 0
          },
          "totalStockUsedArea": {
            "type": "number",
            "default": 0
          },
          "totalPartsArea": {
            "type": "number",
            "default": 0
          },
          "totalOffcutsArea": {
            "type": "number",
            "default": 0
          },
          "totalStockCost": {
            "type": "number",
            "default": 0
          },
          "bandingLengthByType": {
            "type": "object",
            "additionalProperties": {
              "type": "number"
            }
          },
          "finishAreaByType": {
            "type": "object",
            "additionalProperties": {
              "type": "number"
            }
          },
          "materialSummary": {
            "type": "object",
            "additionalProperties": {
              "type": "object",
              "additionalProperties": {
                "type": "object",
                "properties": {
                  "used": {
                    "type": "number"
                  },
                  "stacks": {
                    "type": "number"
                  },
                  "bandingLengthByType": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          },
          "totalBandingLength": {
            "type": "number",
            "default": 0
          },
          "totalFinishArea": {
            "type": "number",
            "default": 0
          },
          "totalCutLength": {
            "type": "number",
            "default": 0
          },
          "totalStackedCutLength": {
            "type": "number",
            "default": 0
          },
          "totalCuts": {
            "type": "number",
            "default": 0
          },
          "totalStackedCuts": {
            "type": "number",
            "default": 0
          },
          "totalBladeArea": {
            "type": "number",
            "default": 0
          },
          "totalTrimArea": {
            "type": "number",
            "default": 0
          },
          "totalUsedStock": {
            "type": "integer",
            "description": "Number of stock items used"
          },
          "totalPartArea": {
            "type": "number",
            "description": "Total area of all parts"
          },
          "totalPartsProduced": {
            "type": "integer",
            "description": "Number of parts successfully placed"
          },
          "unplacedParts": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "IDs of parts that could not be placed"
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "details": {
            "type": "object"
          }
        },
        "required": [
          "error"
        ]
      }
    }
  },
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "servers": [
    {
      "url": "https://api.smartcut.dev",
      "description": "Production"
    },
    {
      "url": "http://localhost:5000",
      "description": "Local development"
    }
  ],
  "tags": [
    {
      "name": "Calculations",
      "description": "Submit cutting optimization calculations"
    },
    {
      "name": "Results",
      "description": "Check status and retrieve calculation results"
    },
    {
      "name": "Exports",
      "description": "Export results in various formats (PDF, CSV, etc.)"
    },
    {
      "name": "Labels",
      "description": "Generate printable labels for parts"
    },
    {
      "name": "Stats",
      "description": "View API usage statistics and call history"
    }
  ]
}