{"openapi":"3.1.0","info":{"title":"TetriCut API","description":"\n**Engineering file processing and optimization solver APIs.**\n\nParse DXF/CAD files into structured geometry, optimize 2D sheet nesting and 1D cutting stock problems, and export results as G-code or DXF.\n\n## Endpoints\n\n### Parse\n- **POST /v1/parse/dxf** — Upload a DXF file, get structured JSON geometry (polygons, holes, layers, dimensions)\n- **POST /v1/parse/dxf-to-svg** — Upload a DXF file, get an SVG preview\n\n### Solve\n- **POST /v1/solve/nest-2d** — Optimize 2D part placement on sheets (bin packing). Minimizes material waste.\n- **POST /v1/solve/cut-1d** — Optimize 1D cutting from stock lengths (cutting stock problem). Minimizes waste/cost.\n\n### Export\n- **POST /v1/export/gcode** — Generate CNC G-code from nesting results\n- **POST /v1/export/dxf** — Generate DXF files from nesting results\n\n## Use Cases\n- **Manufacturing software** — quote material usage, optimize laser/plasma cutting\n- **CAM tools** — parse DXF files without building a parser\n- **Packaging** — optimize sheet/panel cutting layouts\n- **Construction** — optimize rebar, lumber, pipe cutting\n- **3D printing** — optimize build plate layouts\n","version":"1.0.0"},"paths":{"/v1/parse/dxf":{"post":{"tags":["Parse"],"summary":"Parse DXF file to JSON geometry","description":"Upload a DXF file and get structured JSON geometry back. Extracts polygons, holes, cut paths, bend lines, layers, and dimensions. Supports ASCII and binary DXF formats with automatic unit conversion (inches/feet to mm).","operationId":"parse_dxf_endpoint_v1_parse_dxf_post","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_parse_dxf_endpoint_v1_parse_dxf_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParseDXFResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/parse/dxf-to-svg":{"post":{"tags":["Parse"],"summary":"Convert DXF to SVG","description":"Upload a DXF file and get an SVG string back. Configurable output size, stroke color, and background.","operationId":"convert_dxf_to_svg_v1_parse_dxf_to_svg_post","parameters":[{"name":"width","in":"query","required":false,"schema":{"type":"integer","maximum":4000,"minimum":100,"default":800,"title":"Width"}},{"name":"height","in":"query","required":false,"schema":{"type":"integer","maximum":4000,"minimum":100,"default":600,"title":"Height"}},{"name":"stroke_color","in":"query","required":false,"schema":{"type":"string","pattern":"^#[0-9a-fA-F]{3,8}$|^[a-zA-Z]+$","default":"#000000","title":"Stroke Color"}},{"name":"stroke_width","in":"query","required":false,"schema":{"type":"number","maximum":10.0,"minimum":0.1,"default":1.0,"title":"Stroke Width"}},{"name":"background","in":"query","required":false,"schema":{"type":"string","pattern":"^#[0-9a-fA-F]{3,8}$|^[a-zA-Z]+$","default":"#ffffff","title":"Background"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_convert_dxf_to_svg_v1_parse_dxf_to_svg_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConvertDXFtoSVGResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/solve/nest-2d":{"post":{"tags":["Solve"],"summary":"2D Sheet Nesting Optimization","description":"Optimize placement of 2D parts on rectangular sheets to minimize material waste. Supports polygons with holes, rotation optimization (0/90 degrees), multi-sheet output, and configurable spacing/kerf. Uses STRtree collision detection and gravity compaction.","operationId":"solve_nest_2d_v1_solve_nest_2d_post","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Nest2DRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Nest2DResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/solve/cut-1d":{"post":{"tags":["Solve"],"summary":"1D Cutting Stock Optimization","description":"Optimize cutting pieces from stock lengths to minimize waste or cost. Uses First Fit Decreasing (FFD) algorithm with consolidation optimization. Supports multiple stock sizes, blade kerf, and cost optimization. Returns per-stock cut layouts with positions.","operationId":"solve_cut_1d_v1_solve_cut_1d_post","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Cut1DRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Cut1DResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/export/gcode":{"post":{"tags":["Export"],"summary":"Export Gcode","operationId":"export_gcode_v1_export_gcode_post","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportNestingRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/export/dxf":{"post":{"tags":["Export"],"summary":"Export Dxf","operationId":"export_dxf_v1_export_dxf_post","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportNestingRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health":{"get":{"summary":"Health","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"Body_convert_dxf_to_svg_v1_parse_dxf_to_svg_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_convert_dxf_to_svg_v1_parse_dxf_to_svg_post"},"Body_parse_dxf_endpoint_v1_parse_dxf_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File","description":"DXF file (max 10MB)"}},"type":"object","required":["file"],"title":"Body_parse_dxf_endpoint_v1_parse_dxf_post"},"Bounds":{"properties":{"min_x":{"type":"number","title":"Min X"},"min_y":{"type":"number","title":"Min Y"},"max_x":{"type":"number","title":"Max X"},"max_y":{"type":"number","title":"Max Y"}},"type":"object","required":["min_x","min_y","max_x","max_y"],"title":"Bounds"},"ConvertDXFtoSVGData":{"properties":{"svg":{"type":"string","title":"Svg"},"width":{"type":"number","title":"Width"},"height":{"type":"number","title":"Height"},"original_bounds":{"$ref":"#/components/schemas/Bounds"}},"type":"object","required":["svg","width","height","original_bounds"],"title":"ConvertDXFtoSVGData"},"ConvertDXFtoSVGResponse":{"properties":{"status":{"type":"string","title":"Status","default":"success"},"data":{"$ref":"#/components/schemas/ConvertDXFtoSVGData"},"meta":{"$ref":"#/components/schemas/Meta"}},"type":"object","required":["data","meta"],"title":"ConvertDXFtoSVGResponse"},"Cut1DData":{"properties":{"summary":{"$ref":"#/components/schemas/Cut1DSummary"},"layouts":{"items":{"$ref":"#/components/schemas/StockLayout"},"type":"array","title":"Layouts"},"unplaced":{"items":{"type":"string"},"type":"array","title":"Unplaced"}},"type":"object","required":["summary","layouts","unplaced"],"title":"Cut1DData"},"Cut1DRequest":{"properties":{"stocks":{"items":{"$ref":"#/components/schemas/CutStockInput"},"type":"array","maxItems":50,"minItems":1,"title":"Stocks"},"pieces":{"items":{"$ref":"#/components/schemas/CutPieceInput"},"type":"array","maxItems":1000,"minItems":1,"title":"Pieces"},"kerf":{"type":"number","maximum":100.0,"minimum":0.0,"title":"Kerf","default":0.0},"optimize":{"type":"string","title":"Optimize","default":"waste"}},"type":"object","required":["stocks","pieces"],"title":"Cut1DRequest","examples":[{"kerf":3,"optimize":"waste","pieces":[{"id":"piece-A","length":2500,"quantity":8},{"id":"piece-B","length":1200,"quantity":15},{"id":"piece-C","length":800,"quantity":24}],"stocks":[{"cost":25.0,"id":"6m-bar","length":6000,"quantity":20}]}]},"Cut1DResponse":{"properties":{"status":{"type":"string","title":"Status","default":"success"},"data":{"$ref":"#/components/schemas/Cut1DData"},"meta":{"type":"object","title":"Meta"}},"type":"object","required":["data","meta"],"title":"Cut1DResponse"},"Cut1DSummary":{"properties":{"stocks_used":{"type":"integer","title":"Stocks Used"},"total_stock_length":{"type":"number","title":"Total Stock Length"},"total_cut_length":{"type":"number","title":"Total Cut Length"},"total_waste":{"type":"number","title":"Total Waste"},"waste_percent":{"type":"number","title":"Waste Percent"},"total_cost":{"type":"number","title":"Total Cost"},"all_pieces_placed":{"type":"boolean","title":"All Pieces Placed"}},"type":"object","required":["stocks_used","total_stock_length","total_cut_length","total_waste","waste_percent","total_cost","all_pieces_placed"],"title":"Cut1DSummary"},"CutPieceInput":{"properties":{"id":{"type":"string","maxLength":100,"title":"Id"},"length":{"type":"number","maximum":1000000.0,"exclusiveMinimum":0.0,"title":"Length"},"quantity":{"type":"integer","maximum":10000.0,"minimum":1.0,"title":"Quantity","default":1}},"type":"object","required":["id","length"],"title":"CutPieceInput"},"CutPlacement":{"properties":{"piece_id":{"type":"string","title":"Piece Id"},"length":{"type":"number","title":"Length"},"position":{"type":"number","title":"Position"}},"type":"object","required":["piece_id","length","position"],"title":"CutPlacement"},"CutStockInput":{"properties":{"id":{"type":"string","maxLength":100,"title":"Id","default":"stock"},"length":{"type":"number","maximum":1000000.0,"exclusiveMinimum":0.0,"title":"Length"},"quantity":{"type":"integer","maximum":10000.0,"minimum":1.0,"title":"Quantity","default":999},"cost":{"type":"number","minimum":0.0,"title":"Cost","default":0.0}},"type":"object","required":["length"],"title":"CutStockInput"},"Dimensions":{"properties":{"width":{"type":"number","title":"Width"},"height":{"type":"number","title":"Height"},"unit":{"type":"string","title":"Unit","default":"mm"}},"type":"object","required":["width","height"],"title":"Dimensions"},"ExportNestingRequest":{"properties":{"sheet_width":{"type":"number","title":"Sheet Width"},"sheet_height":{"type":"number","title":"Sheet Height"},"sheet_index":{"type":"integer","title":"Sheet Index","default":0},"placements":{"items":{"type":"object"},"type":"array","title":"Placements"},"config":{"$ref":"#/components/schemas/GcodeExportConfig","default":{"feed_rate":1000.0,"travel_rate":3000.0,"laser_power":100.0,"kerf":0.0,"use_z":false}}},"type":"object","required":["sheet_width","sheet_height","placements"],"title":"ExportNestingRequest"},"GcodeExportConfig":{"properties":{"feed_rate":{"type":"number","title":"Feed Rate","default":1000},"travel_rate":{"type":"number","title":"Travel Rate","default":3000},"laser_power":{"type":"number","title":"Laser Power","default":100},"kerf":{"type":"number","title":"Kerf","default":0.0},"use_z":{"type":"boolean","title":"Use Z","default":false}},"type":"object","title":"GcodeExportConfig"},"Geometry":{"properties":{"exterior":{"items":{"items":{"type":"number"},"type":"array"},"type":"array","title":"Exterior"},"holes":{"items":{"items":{"items":{"type":"number"},"type":"array"},"type":"array"},"type":"array","title":"Holes"}},"type":"object","required":["exterior","holes"],"title":"Geometry"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"Meta":{"properties":{"processing_time_ms":{"type":"integer","title":"Processing Time Ms"},"engine_version":{"type":"string","title":"Engine Version","default":"1.0.0"}},"type":"object","required":["processing_time_ms"],"title":"Meta"},"Nest2DData":{"properties":{"summary":{"$ref":"#/components/schemas/NestSummary"},"sheets":{"items":{"$ref":"#/components/schemas/SheetOutput"},"type":"array","title":"Sheets"},"unplaced":{"items":{"type":"string"},"type":"array","title":"Unplaced"}},"type":"object","required":["summary","sheets","unplaced"],"title":"Nest2DData"},"Nest2DRequest":{"properties":{"parts":{"items":{"$ref":"#/components/schemas/NestPartInput"},"type":"array","maxItems":200,"minItems":1,"title":"Parts"},"sheet":{"$ref":"#/components/schemas/NestSheetInput"},"config":{"$ref":"#/components/schemas/NestConfigInput","default":{"spacing":3.0,"edge_margin":5.0,"rotation_step":90.0,"kerf":0.0}}},"type":"object","required":["parts","sheet"],"title":"Nest2DRequest","examples":[{"config":{"rotation_step":90,"spacing":3},"parts":[{"exterior":[[0,0],[100,0],[100,50],[0,50],[0,0]],"id":"rect-A","quantity":5},{"exterior":[[0,0],[80,0],[80,80],[0,80],[0,0]],"id":"square-B","quantity":3}],"sheet":{"height":2440,"width":1220}}]},"Nest2DResponse":{"properties":{"status":{"type":"string","title":"Status","default":"success"},"data":{"$ref":"#/components/schemas/Nest2DData"},"meta":{"type":"object","title":"Meta"}},"type":"object","required":["data","meta"],"title":"Nest2DResponse"},"NestConfigInput":{"properties":{"spacing":{"type":"number","maximum":100.0,"minimum":0.0,"title":"Spacing","default":3.0},"edge_margin":{"type":"number","maximum":100.0,"minimum":0.0,"title":"Edge Margin","default":5.0},"rotation_step":{"type":"number","maximum":90.0,"minimum":15.0,"title":"Rotation Step","default":90},"kerf":{"type":"number","maximum":50.0,"minimum":0.0,"title":"Kerf","default":0.0}},"type":"object","title":"NestConfigInput"},"NestPartInput":{"properties":{"id":{"type":"string","maxLength":100,"title":"Id"},"exterior":{"items":{"items":{"type":"number"},"type":"array"},"type":"array","maxItems":2000,"title":"Exterior"},"holes":{"items":{"items":{"items":{"type":"number"},"type":"array"},"type":"array"},"type":"array","maxItems":50,"title":"Holes","default":[]},"quantity":{"type":"integer","maximum":500.0,"minimum":1.0,"title":"Quantity","default":1}},"type":"object","required":["id","exterior"],"title":"NestPartInput"},"NestSheetInput":{"properties":{"width":{"type":"number","maximum":100000.0,"exclusiveMinimum":0.0,"title":"Width"},"height":{"type":"number","maximum":100000.0,"exclusiveMinimum":0.0,"title":"Height"}},"type":"object","required":["width","height"],"title":"NestSheetInput"},"NestSummary":{"properties":{"sheets_used":{"type":"integer","title":"Sheets Used"},"total_parts":{"type":"integer","title":"Total Parts"},"placed_parts":{"type":"integer","title":"Placed Parts"},"unplaced_parts":{"type":"integer","title":"Unplaced Parts"},"total_utilization":{"type":"number","title":"Total Utilization"},"total_waste_percent":{"type":"number","title":"Total Waste Percent"}},"type":"object","required":["sheets_used","total_parts","placed_parts","unplaced_parts","total_utilization","total_waste_percent"],"title":"NestSummary"},"ParseDXFData":{"properties":{"name":{"type":"string","title":"Name"},"bounds":{"$ref":"#/components/schemas/Bounds"},"dimensions":{"$ref":"#/components/schemas/Dimensions"},"area":{"type":"number","title":"Area"},"perimeter":{"type":"number","title":"Perimeter"},"geometry":{"$ref":"#/components/schemas/Geometry"},"layers":{"items":{"type":"string"},"type":"array","title":"Layers"},"cut_paths":{"items":{"items":{"items":{"type":"number"},"type":"array"},"type":"array"},"type":"array","title":"Cut Paths"},"bend_lines":{"anyOf":[{"items":{"items":{"items":{"type":"number"},"type":"array"},"type":"array"},"type":"array"},{"type":"null"}],"title":"Bend Lines"},"entity_count":{"type":"integer","title":"Entity Count"},"has_holes":{"type":"boolean","title":"Has Holes"},"hole_count":{"type":"integer","title":"Hole Count"}},"type":"object","required":["name","bounds","dimensions","area","perimeter","geometry","layers","cut_paths","bend_lines","entity_count","has_holes","hole_count"],"title":"ParseDXFData"},"ParseDXFResponse":{"properties":{"status":{"type":"string","title":"Status","default":"success"},"data":{"$ref":"#/components/schemas/ParseDXFData"},"meta":{"$ref":"#/components/schemas/Meta"}},"type":"object","required":["data","meta"],"title":"ParseDXFResponse"},"PlacementOutput":{"properties":{"part_id":{"type":"string","title":"Part Id"},"instance":{"type":"integer","title":"Instance"},"x":{"type":"number","title":"X"},"y":{"type":"number","title":"Y"},"rotation":{"type":"number","title":"Rotation"},"bounds":{"type":"object","title":"Bounds"}},"type":"object","required":["part_id","instance","x","y","rotation","bounds"],"title":"PlacementOutput"},"SheetOutput":{"properties":{"index":{"type":"integer","title":"Index"},"utilization":{"type":"number","title":"Utilization"},"placements":{"items":{"$ref":"#/components/schemas/PlacementOutput"},"type":"array","title":"Placements"}},"type":"object","required":["index","utilization","placements"],"title":"SheetOutput"},"StockLayout":{"properties":{"stock_id":{"type":"string","title":"Stock Id"},"stock_index":{"type":"integer","title":"Stock Index"},"cuts":{"items":{"$ref":"#/components/schemas/CutPlacement"},"type":"array","title":"Cuts"},"used_length":{"type":"number","title":"Used Length"},"waste":{"type":"number","title":"Waste"},"utilization":{"type":"number","title":"Utilization"}},"type":"object","required":["stock_id","stock_index","cuts","used_length","waste","utilization"],"title":"StockLayout"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}}}