{ "openapi": "3.1.0", "info": { "title": "Bitbybit CAD Cloud API", "version": "1.0.2", "description": "High-performance parametric CAD model generation API. Supports multi-format output (STEP, GLTF, decomposed mesh), pipeline execution, file-based conversion, and async job processing.", "contact": { "name": "Bitbybit", "url": "https://bitbybit.dev" }, "termsOfService": "https://bitbybit.dev/terms-and-conditions", "license": { "name": "Proprietary", "url": "https://bitbybit.dev/terms-and-conditions" } }, "servers": [ { "url": "https://api.bitbybit.dev", "description": "Production" } ], "security": [ { "ApiKeyAuth": [] } ], "paths": { "/health": { "get": { "tags": [ "Health" ], "summary": "Health - status check", "security": [], "responses": { "200": { "description": "Health status", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HealthResponse" } } } } } } }, "/api/v1/cad/execute": { "post": { "tags": [ "CAD Operations" ], "summary": "CAD - execute a single operation", "description": "Runs a single CAD operation by its fully-qualified identifier.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExecuteBody" } } } }, "responses": { "202": { "description": "Task accepted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TaskAcceptedResponse" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/cad/pipeline": { "post": { "tags": [ "CAD Operations" ], "summary": "CAD - execute a chained pipeline", "description": "Runs multiple operations sequentially. Use '$ref:N' in params to reference step N's result.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PipelineBody" } } } }, "responses": { "202": { "description": "Task accepted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TaskAcceptedResponse" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/cad/compound": { "post": { "tags": [ "CAD Operations" ], "summary": "CAD - execute compound (parallel) operations", "description": "Runs multiple independent operations in parallel.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CompoundExecuteBody" } } } }, "responses": { "202": { "description": "Compound task accepted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CompoundTaskAcceptedResponse" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/models": { "get": { "tags": [ "Models" ], "summary": "Models - list available models", "responses": { "200": { "description": "Model name list", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ModelListResponse" } } } } } } }, "/api/v1/models/definitions": { "post": { "tags": [ "Models" ], "summary": "Models - batch-fetch definitions", "description": "Returns parameter schemas and defaults for the requested model names.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DefinitionsBody" } } } }, "responses": { "200": { "description": "Model definitions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ModelBatchDefinitionsResponse" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/models/{modelName}": { "post": { "tags": [ "Models" ], "summary": "Models - execute a parametric model", "description": "Generic endpoint - works for any registered model. See model-specific endpoints for fully typed parameters. Always returns 202 with a task ID for polling.", "parameters": [ { "name": "modelName", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Model slug (e.g. dragon-cup, phone-nest)" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ModelSubmissionBody" } } } }, "responses": { "202": { "description": "Task accepted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TaskAcceptedResponse" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/models/{modelName}/batch": { "post": { "tags": [ "Models" ], "summary": "Models - generate a batch", "description": "Creates a compound task with one sub-task per item. Each item can have different parameters but shares the same output config.", "parameters": [ { "name": "modelName", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Model slug (e.g. dragon-cup, phone-nest)" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BatchModelSubmissionBody" } } } }, "responses": { "202": { "description": "Compound task accepted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CompoundTaskAcceptedResponse" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/models/{modelName}/params": { "get": { "tags": [ "Models" ], "summary": "Models - get parameter definitions", "description": "Returns parameter schema, types, defaults, and limits for the specified model.", "parameters": [ { "name": "modelName", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Model slug (e.g. dragon-cup, phone-nest)" } ], "responses": { "200": { "description": "Model definition", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ModelDefinitionResponse" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/models/dragon-cup": { "post": { "tags": [ "Models - Dragon Cup" ], "summary": "Models - build a Dragon Cup", "description": "Parametric dragon-scale textured cup with twisted lofted body, voronoi-like skin cells, and configurable shell thickness. All parameters are optional - defaults produce a ready-to-print model.", "requestBody": { "required": true, "content": { "application/json": { "example": { "params": { "height": 8, "radiusBottom": 4, "radiusTopOffset": 2, "radiusMidOffset": 2, "rotationTopAngle": 20, "rotationMidAngle": 20, "nrSkinCellsVertical": 5, "nrSkinCellsHorizontal": 10, "nrSkinCellDivisionsTop": 1, "nrSkinCellDivisionsBottom": 3, "skinCellOuterHeight": 0.4, "skinCellInnerHeight": 0.3, "skinCellBottomHeight": 0.4, "skinCellTopHeight": 0.4, "thickness": 0.6, "bottomThickness": 1, "precision": 0.01, "rotation": 0, "scale": 1, "origin": [ 0, 0, 0 ], "direction": [ 0, 1, 0 ] }, "outputs": { "formats": [ "step", "gltf" ] } }, "schema": { "$ref": "#/components/schemas/DragonCupBody" } } } }, "responses": { "202": { "description": "Task accepted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TaskAcceptedResponse" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/models/phone-nest": { "post": { "tags": [ "Models - Phone Nest" ], "summary": "Models - build a Phone Nest", "description": "Parametric 3D-printable desktop phone holder/stand with a lofted cradle surface, optional ornamental perforations, and a phone mock-up shape. All parameters are optional - defaults produce a ready-to-print model.", "requestBody": { "required": true, "content": { "application/json": { "example": { "params": { "heightBottom": 5, "heightTop": 16, "widthBack": 25, "widthFront": 10, "length": 16, "backOffset": 6, "thickness": 0.4, "applyOrnaments": false, "filletRadius": 2, "phoneHeight": 16.8, "phoneWidth": 7.8, "phoneThickness": 0.7, "precision": 0.01, "rotation": 0, "scale": 1, "origin": [ 0, 0, 0 ], "direction": [ 0, 1, 0 ] }, "outputs": { "formats": [ "step", "gltf" ] } }, "schema": { "$ref": "#/components/schemas/PhoneNestBody" } } } }, "responses": { "202": { "description": "Task accepted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TaskAcceptedResponse" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/convert/step-to-gltf": { "post": { "tags": [ "Convert" ], "summary": "Convert - STEP to glTF (.glb)", "description": "Simple STEP → glTF conversion using a previously uploaded file. Requires the 'convert' API key scope. Returns 202 with a task ID.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StepToGltfBody" } } } }, "responses": { "202": { "description": "Task accepted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TaskAcceptedResponse" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Insufficient scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/convert/step-to-gltf-advanced": { "post": { "tags": [ "Convert" ], "summary": "Convert - STEP to glTF (.glb), advanced options", "description": "Full-control STEP → glTF conversion with fine-grained mesh, export, and coordinate options. Requires the 'convert' API key scope. Returns 202 with a task ID.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StepToGltfAdvancedBody" } } } }, "responses": { "202": { "description": "Task accepted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TaskAcceptedResponse" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Insufficient scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/convert/step-to-gltf-with-draco": { "post": { "tags": [ "Convert" ], "summary": "Convert - STEP to Draco-compressed glTF (.glb)", "description": "STEP → glTF conversion with Draco geometry compression using a previously uploaded file. Requires the 'convert' API key scope. Returns 202 with a task ID.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StepToGltfWithDracoBody" } } } }, "responses": { "202": { "description": "Task accepted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TaskAcceptedResponse" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Insufficient scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/convert/step-to-gltf-advanced-with-draco": { "post": { "tags": [ "Convert" ], "summary": "Convert - STEP to Draco-compressed glTF (.glb), advanced options", "description": "Full-control STEP → glTF conversion with Draco geometry compression. Combines fine-grained mesh, export, and coordinate options with Draco quantization controls. Requires the 'convert' API key scope. Returns 202 with a task ID.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StepToGltfAdvancedWithDracoBody" } } } }, "responses": { "202": { "description": "Task accepted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TaskAcceptedResponse" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Insufficient scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/cad/pro/unfold/face-to-flat": { "post": { "tags": [ "Sheet Metal" ], "summary": "Sheet metal - unfold a face to flat geometry", "description": "Proprietary sheet-metal unfold: flattens a single developable face (by index) of an uploaded STEP shape. Requires the 'cad' API key scope. Returns 202 with a task ID; the flattened geometry is delivered as the task's output files.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UnfoldFaceToFlatBody" } } } }, "responses": { "202": { "description": "Task accepted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TaskAcceptedResponse" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Insufficient scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/cad/pro/unfold/face-report": { "post": { "tags": [ "Sheet Metal" ], "summary": "Sheet metal - unfold a face, metrics report", "description": "Proprietary sheet-metal analysis: computes the unfold metrics report (developability, area, ...) for a single face of an uploaded STEP shape. Requires the 'cad' API key scope. Returns 202 with a task ID; the JSON report is delivered in the task metadata.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UnfoldFaceReportBody" } } } }, "responses": { "202": { "description": "Task accepted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TaskAcceptedResponse" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Insufficient scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/cad/pro/unfold/solid-to-flat": { "post": { "tags": [ "Sheet Metal" ], "summary": "Sheet metal - unfold all solids to flat geometry", "description": "Proprietary sheet-metal unfold: loads every solid in an uploaded STEP file and flattens each to a flat pattern. Requires the 'cad' API key scope. Returns 202 with a task ID; all flats are combined into one compound output per format.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UnfoldSolidToFlatBody" } } } }, "responses": { "202": { "description": "Task accepted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TaskAcceptedResponse" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Insufficient scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/cad/pro/unfold/solid-report": { "post": { "tags": [ "Sheet Metal" ], "summary": "Sheet metal - unfold all solids, metrics report", "description": "Proprietary sheet-metal analysis: computes per-solid unfold metrics for every solid in an uploaded STEP file. Requires the 'cad' API key scope. Returns 202 with a task ID; the JSON report array is delivered in the task metadata.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UnfoldSolidReportBody" } } } }, "responses": { "202": { "description": "Task accepted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TaskAcceptedResponse" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Insufficient scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/cad/pro/unfold/solid": { "post": { "tags": [ "Sheet Metal" ], "summary": "Sheet metal - unfold all solids, geometry + report", "description": "Proprietary sheet-metal unfold, full workflow: flattens every solid in an uploaded STEP file AND returns per-solid metrics in one call. Requires the 'cad' API key scope. Returns 202 with a task ID; flats are combined into one compound output per format and the per-solid report array is delivered in the task metadata.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UnfoldSolidBody" } } } }, "responses": { "202": { "description": "Task accepted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TaskAcceptedResponse" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Insufficient scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/files/upload": { "post": { "tags": [ "Files" ], "summary": "Files - request an upload URL", "description": "Returns a pre-signed URL for uploading a file via PUT.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FileUploadBody" } } } }, "responses": { "201": { "description": "Upload URL and file ID", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UploadResponse" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/files": { "get": { "tags": [ "Files" ], "summary": "Files - list uploaded files", "description": "Returns paginated list of uploaded files.", "parameters": [ { "name": "page", "in": "query", "required": false, "schema": { "type": "integer", "default": 1 } }, { "name": "limit", "in": "query", "required": false, "schema": { "type": "integer", "default": 20 } }, { "name": "status", "in": "query", "required": false, "schema": { "type": "string", "enum": [ "pending", "confirmed", "expired" ] } } ], "responses": { "200": { "description": "File list", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FileListResponse" } } } } } } }, "/api/v1/files/{fileId}": { "get": { "tags": [ "Files" ], "summary": "Files - get file details", "description": "Returns metadata and download URL for a single file.", "parameters": [ { "name": "fileId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" }, "description": "File ID" } ], "responses": { "200": { "description": "File details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FileDetailResponse" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "tags": [ "Files" ], "summary": "Files - delete a file", "description": "Permanently removes a file and its stored blob.", "parameters": [ { "name": "fileId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" }, "description": "File ID" } ], "responses": { "200": { "description": "File deleted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DeleteFileResponse" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/files/{fileId}/confirm": { "post": { "tags": [ "Files" ], "summary": "Files - confirm upload", "description": "Confirms that the file was successfully uploaded to the pre-signed URL.", "parameters": [ { "name": "fileId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" }, "description": "File ID" } ], "responses": { "200": { "description": "File confirmed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConfirmResponse" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/tasks": { "get": { "tags": [ "Tasks" ], "summary": "Tasks - list tasks", "description": "Returns paginated list of tasks.", "parameters": [ { "name": "page", "in": "query", "required": false, "schema": { "type": "integer", "default": 1 } }, { "name": "limit", "in": "query", "required": false, "schema": { "type": "integer", "default": 20 } }, { "name": "status", "in": "query", "required": false, "schema": { "type": "string", "enum": [ "waiting", "queued", "processing", "completed", "failed", "cancelled", "expired" ] } }, { "name": "kind", "in": "query", "required": false, "schema": { "type": "string", "enum": [ "cad", "model", "convert-simple", "convert-advanced", "pipeline", "compound" ] } } ], "responses": { "200": { "description": "Task list", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TaskListResponse" } } } } } } }, "/api/v1/tasks/{taskId}": { "get": { "tags": [ "Tasks" ], "summary": "Tasks - get task status", "description": "Returns the current status and metadata of a task.", "parameters": [ { "name": "taskId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" }, "description": "Task ID" } ], "responses": { "200": { "description": "Task status", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TaskDetailResponse" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "tags": [ "Tasks" ], "summary": "Tasks - cancel a task", "description": "Cancels a waiting or queued task. Has no effect on completed/failed tasks.", "parameters": [ { "name": "taskId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" }, "description": "Task ID" } ], "responses": { "200": { "description": "Task cancelled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CancelTaskResponse" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/tasks/{taskId}/result": { "get": { "tags": [ "Tasks" ], "summary": "Tasks - get result (default format)", "description": "Returns a download URL for the task's primary result. For compound tasks, returns a manifest with per-sub-task download links.", "parameters": [ { "name": "taskId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" }, "description": "Task ID" } ], "responses": { "200": { "description": "Result download link (standard) or compound manifest", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TaskOrCompoundResultResponse" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Task is not yet completed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/tasks/{taskId}/result/{format}": { "get": { "tags": [ "Tasks" ], "summary": "Tasks - get result in a specific format", "description": "Returns a download URL for the requested output format (e.g. glb, step, stpz).", "parameters": [ { "name": "taskId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" }, "description": "Task ID" }, { "name": "format", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Result format (e.g. glb, step, stpz, metadata, decomposed-mesh)" } ], "responses": { "200": { "description": "Result download link", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TaskResultResponse" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Task is not yet completed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/tasks/{taskId}/results": { "get": { "tags": [ "Tasks" ], "summary": "Tasks - get all results", "description": "Returns download URLs for every available result format in a single call. Use this instead of making multiple requests to /result/{format}.", "parameters": [ { "name": "taskId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" }, "description": "Task ID" } ], "responses": { "200": { "description": "Download links for all available formats", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TaskResultsResponse" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Task is not yet completed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/tasks/{taskId}/retry": { "post": { "tags": [ "Tasks" ], "summary": "Tasks - retry a failed or cancelled task", "description": "Re-queues a failed or cancelled task with the same parameters.", "parameters": [ { "name": "taskId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" }, "description": "Task ID" } ], "responses": { "202": { "description": "Task re-queued", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TaskAcceptedResponse" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Task is not in a retryable state", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } } }, "components": { "schemas": { "ExecuteBody": { "type": "object", "properties": { "operation": { "type": "string", "minLength": 1, "description": "Fully-qualified CAD operation identifier (e.g. 'occt.shapes.solid.createBox', 'manifold.primitives.cube', 'jscad.booleans.union'). Supports OCCT, Manifold, JSCAD, and vector/math operations." }, "params": { "description": "Operation-specific parameters - varies by operation. See model definitions for available parameters." } }, "required": [ "operation" ], "additionalProperties": false, "description": "Execute a single Bitbybit CAD operation. The operation runs asynchronously and returns a task ID for polling." }, "PipelineBody": { "type": "object", "properties": { "steps": { "minItems": 1, "maxItems": 50, "type": "array", "items": { "$ref": "#/components/schemas/PipelineAnyStep" }, "description": "Ordered list of CAD operations executed sequentially. Later steps can reference earlier results using '$ref:N' syntax. Supports map and choice control-flow steps." }, "inputFiles": { "description": "References to previously uploaded files. Use '$file:N' in step params to inject file contents.", "maxItems": 5, "type": "array", "items": { "$ref": "#/components/schemas/InputFileItem" } }, "outputs": { "description": "Output format options applied to the final pipeline result. Supports json, csv, stl, 3mf in addition to standard formats. If omitted, raw result data is stored.", "$ref": "#/components/schemas/PipelineOutputOptions" } }, "required": [ "steps" ], "additionalProperties": false, "description": "Execute a chain of Bitbybit CAD operations sequentially. Supports $ref:N step references, $file:N file inputs, map iteration, and choice conditionals." }, "PipelineAnyStep": { "anyOf": [ { "$ref": "#/components/schemas/MapStep" }, { "$ref": "#/components/schemas/ChoiceStep" }, { "$ref": "#/components/schemas/PipelineStep" } ], "description": "A pipeline step - either a plain operation, a map (iteration), or a choice (conditional)." }, "MapStep": { "type": "object", "properties": { "type": { "type": "string", "const": "map", "description": "Declares this step as a map (iteration) step" }, "items": { "description": "Source array to iterate over. Typically a '$ref:N' reference to a previous step that produced an array." }, "steps": { "minItems": 1, "type": "array", "items": { "$ref": "#/components/schemas/PipelineStep" }, "description": "Sub-steps to execute for each item. Use '$item' for the current element, '$index' for the iteration number." }, "reduce": { "description": "Optional sub-steps to combine map results. Use '$mapResult' to reference the collected array of iteration outputs.", "type": "array", "items": { "$ref": "#/components/schemas/PipelineStep" } } }, "required": [ "type", "items", "steps" ], "description": "Iterate over an array, executing sub-steps for each element. Produces an array of results (or a reduced value)." }, "PipelineStep": { "type": "object", "properties": { "operation": { "type": "string", "minLength": 1, "description": "Fully-qualified CAD operation identifier (e.g. 'occt.shapes.solid.createSphere'). Supports OCCT, Manifold, JSCAD, and vector/math operations." }, "params": { "description": "Operation parameters. Use '$ref:N' (e.g. '$ref:0') to reference the output of a previous step by its zero-based index. Use '$file:N' to reference an input file's contents." }, "output": { "description": "When true, this step's result is included in a separate result.json output alongside any shape files.", "type": "boolean" } }, "required": [ "operation", "params" ], "description": "A single step in a sequential CAD pipeline. Steps can reference outputs of earlier steps via $ref or input files via $file." }, "ChoiceStep": { "type": "object", "properties": { "type": { "type": "string", "const": "choice", "description": "Declares this step as a choice (conditional) step" }, "value": { "description": "Value to compare. Typically a '$ref:N' reference to a previous step result." }, "operator": { "description": "Comparison operator to apply between value and compareTo", "$ref": "#/components/schemas/ComparisonOperator" }, "compareTo": { "description": "Value to compare against. Not required for 'exists' operator." }, "then": { "minItems": 1, "type": "array", "items": { "$ref": "#/components/schemas/PipelineStep" }, "description": "Sub-steps to execute when condition is true" }, "else": { "description": "Sub-steps to execute when condition is false. If omitted, produces null.", "type": "array", "items": { "$ref": "#/components/schemas/PipelineStep" } } }, "required": [ "type", "value", "operator", "then" ], "description": "Conditional execution - evaluate a condition and run the matching branch." }, "ComparisonOperator": { "type": "string", "enum": [ "eq", "neq", "gt", "gte", "lt", "lte", "exists" ], "description": "Comparison operator: 'eq' (equal), 'neq' (not equal), 'gt' (greater than), 'gte' (greater or equal), 'lt' (less than), 'lte' (less or equal), 'exists' (value is not null/undefined)." }, "InputFileItem": { "type": "object", "properties": { "fileId": { "type": "string", "minLength": 1, "description": "ID of a previously uploaded file (from POST /files/upload)" }, "role": { "type": "string", "minLength": 1, "description": "Role identifier for the file (e.g. 'step-model', 'coordinates-csv')" } }, "required": [ "fileId", "role" ], "additionalProperties": false, "description": "Reference to an uploaded file to be used as input" }, "PipelineOutputOptions": { "type": "object", "properties": { "formats": { "minItems": 1, "type": "array", "items": { "$ref": "#/components/schemas/PipelineOutputFormat" }, "description": "Output formats to generate. Supports standard CAD formats (step, stpz, gltf, decomposed-mesh) plus pipeline-specific formats (json, csv, stl, 3mf)." }, "meshPrecision": { "description": "Tessellation precision for mesh-based outputs (decomposed-mesh and gltf). Lower values produce denser meshes.", "$ref": "#/components/schemas/MeshPrecision" }, "gltfMeshPrecision": { "description": "Override tessellation precision specifically for glTF output. When set, takes precedence over meshPrecision for glTF only.", "$ref": "#/components/schemas/MeshPrecision" }, "adjustYtoZ": { "description": "Convert from Y-up to Z-up coordinate system in the output. Useful for software that expects Z-up.", "type": "boolean" }, "includePipelineInMetadata": { "description": "Include the full pipeline definition in metadata.json. Defaults to true. Set to false to exclude it for smaller metadata.", "type": "boolean" } }, "required": [ "formats" ], "additionalProperties": false, "description": "Controls which output formats are generated for pipeline results. Supports additional formats (json, csv, stl, 3mf) beyond standard model outputs." }, "PipelineOutputFormat": { "type": "string", "enum": [ "step", "stpz", "decomposed-mesh", "gltf", "json", "csv", "stl", "3mf" ], "description": "Pipeline output file format. Includes all standard formats plus: 'json' (JSON data), 'csv' (CSV text), 'stl' (binary STL mesh - Manifold/JSCAD only), '3mf' (3MF mesh package - Manifold/JSCAD only)." }, "MeshPrecision": { "type": "number", "minimum": 0.0001, "maximum": 10, "description": "Mesh tessellation precision (lower = finer). Range: [0.0001, 10]", "example": 0.1 }, "CompoundExecuteBody": { "type": "object", "properties": { "parallel": { "type": "boolean", "const": true, "description": "Must be true - signals that items should be processed concurrently" }, "items": { "minItems": 1, "maxItems": 100, "type": "array", "items": { "$ref": "#/components/schemas/CompoundItem" }, "description": "List of independent CAD operations to execute in parallel. Each item becomes a sub-task." } }, "required": [ "parallel", "items" ], "additionalProperties": false, "description": "Execute multiple independent Bitbybit CAD operations in parallel. Each item runs as a separate sub-task and can be polled individually." }, "CompoundItem": { "type": "object", "properties": { "operation": { "type": "string", "minLength": 1, "description": "Fully-qualified CAD operation identifier. Supports OCCT, Manifold, JSCAD, and vector/math operations." }, "params": { "description": "Operation-specific parameters for this sub-task" }, "inputFiles": { "description": "References to previously uploaded files to be used as inputs for this operation", "type": "array", "items": { "$ref": "#/components/schemas/InputFileItem" } }, "outputFormats": { "description": "Per-item output format overrides. If omitted, the task produces raw result data.", "maxItems": 10, "type": "array", "items": { "type": "string", "minLength": 1 } } }, "required": [ "operation" ], "additionalProperties": false, "description": "A single operation within a compound (parallel) task. Each item runs independently." }, "DefinitionsBody": { "type": "object", "properties": { "names": { "minItems": 1, "type": "array", "items": { "type": "string", "minLength": 1 }, "description": "Array of model slugs to fetch definitions for (e.g. ['dragon-cup', 'phone-nest'])" } }, "required": [ "names" ], "additionalProperties": false, "description": "Fetch parameter definitions for one or more parametric models. Returns available parameters, types, defaults, and constraints." }, "ModelSubmissionBody": { "type": "object", "properties": { "params": { "description": "Model-specific parameters. Omitted params use their defaults. See model definition for available options.", "type": "object", "propertyNames": { "type": "string" }, "additionalProperties": {} }, "outputs": { "$ref": "#/components/schemas/OutputOptions" } }, "required": [ "outputs" ], "description": "Submit a parametric model for generation with specified parameters and output formats" }, "OutputOptions": { "type": "object", "properties": { "formats": { "minItems": 1, "type": "array", "items": { "$ref": "#/components/schemas/OutputFormat" }, "description": "Output formats to generate. Multiple formats can be requested (e.g. ['gltf', 'stpz']) - each produces a separate downloadable result. Do not include both 'step' and 'stpz' - only one STEP variant is supported per request." }, "meshPrecision": { "description": "Tessellation precision for mesh-based outputs (decomposed-mesh and gltf). Lower values produce denser meshes. Only ignored when output is limited to step/stpz formats.", "$ref": "#/components/schemas/MeshPrecision" }, "gltfMeshPrecision": { "description": "Override tessellation precision specifically for glTF output. When set, takes precedence over meshPrecision for glTF only.", "$ref": "#/components/schemas/MeshPrecision" }, "adjustYtoZ": { "description": "Convert from Y-up to Z-up coordinate system in the output. Useful for software that expects Z-up.", "type": "boolean" } }, "required": [ "formats" ], "additionalProperties": false, "description": "Controls which output formats are generated and their quality settings" }, "OutputFormat": { "type": "string", "enum": [ "step", "stpz", "decomposed-mesh", "gltf" ], "description": "Output file format: 'step' (raw STEP), 'stpz' (gzip-compressed STEP), 'decomposed-mesh' (triangulated JSON), 'gltf' (glTF 2.0 binary .glb). Note: 'step' and 'stpz' are mutually exclusive - choose one or the other, not both." }, "BatchModelSubmissionBody": { "type": "object", "properties": { "items": { "minItems": 1, "maxItems": 50, "type": "array", "items": { "type": "object", "properties": { "params": { "type": "object", "propertyNames": { "type": "string" }, "additionalProperties": {} } } }, "description": "Array of parameter variations. Each item produces a separate output with the same model." }, "outputs": { "description": "Output format configuration applied to every item in the batch", "$ref": "#/components/schemas/OutputOptions" } }, "required": [ "items", "outputs" ], "description": "Submit multiple parameter variations of the same model for parallel generation" }, "DragonCupBody": { "type": "object", "properties": { "params": { "$ref": "#/components/schemas/DragonCupParams" }, "outputs": { "$ref": "#/components/schemas/OutputOptions" } }, "required": [ "outputs" ], "additionalProperties": false, "description": "Request body for the Dragon Cup model" }, "DragonCupParams": { "type": "object", "properties": { "height": { "description": "Total cup height (cm)", "type": "number", "exclusiveMinimum": 0, "maximum": 50 }, "radiusBottom": { "description": "Radius at the base (cm)", "type": "number", "exclusiveMinimum": 0, "maximum": 30 }, "radiusTopOffset": { "description": "How much the top radius differs from bottom", "type": "number", "minimum": 0, "maximum": 20 }, "radiusMidOffset": { "description": "Mid-section radius offset", "type": "number", "minimum": 0, "maximum": 20 }, "rotationTopAngle": { "description": "Top twist angle (degrees)", "type": "number", "minimum": -360, "maximum": 360 }, "rotationMidAngle": { "description": "Mid twist angle (degrees)", "type": "number", "minimum": -360, "maximum": 360 }, "nrSkinCellsVertical": { "description": "Vertical skin cell count", "type": "integer", "exclusiveMinimum": 0, "maximum": 30 }, "nrSkinCellsHorizontal": { "description": "Horizontal skin cell count", "type": "integer", "exclusiveMinimum": 0, "maximum": 50 }, "nrSkinCellDivisionsTop": { "description": "Subdivisions at top of each cell", "type": "integer", "exclusiveMinimum": 0, "maximum": 10 }, "nrSkinCellDivisionsBottom": { "description": "Subdivisions at bottom of each cell", "type": "integer", "exclusiveMinimum": 0, "maximum": 10 }, "skinCellOuterHeight": { "description": "Outer cell extrusion height", "type": "number", "exclusiveMinimum": 0, "maximum": 5 }, "skinCellInnerHeight": { "description": "Inner cell extrusion height", "type": "number", "exclusiveMinimum": 0, "maximum": 5 }, "skinCellBottomHeight": { "description": "Bottom cell height", "type": "number", "exclusiveMinimum": 0, "maximum": 5 }, "skinCellTopHeight": { "description": "Top cell height", "type": "number", "exclusiveMinimum": 0, "maximum": 5 }, "thickness": { "description": "Shell wall thickness", "type": "number", "exclusiveMinimum": 0, "maximum": 5 }, "bottomThickness": { "description": "Bottom plate thickness", "type": "number", "exclusiveMinimum": 0, "maximum": 5 }, "precision": { "description": "Geometry precision (lower = finer)", "$ref": "#/components/schemas/MeshPrecision" }, "rotation": { "description": "Final rotation angle (degrees)", "type": "number", "minimum": -360, "maximum": 360 }, "scale": { "description": "Uniform scale factor", "$ref": "#/components/schemas/PositiveScale" }, "origin": { "description": "[x, y, z] placement origin", "$ref": "#/components/schemas/Point3" }, "direction": { "description": "[x, y, z] up direction", "$ref": "#/components/schemas/Point3" } }, "additionalProperties": false, "description": "Dragon Cup model parameters - all optional, sane defaults apply" }, "PositiveScale": { "type": "number", "minimum": 0.000001, "maximum": 1000, "description": "Uniform scale factor. Range: [1e-6, 1000]" }, "Point3": { "type": "array", "prefixItems": [ { "type": "number", "minimum": -1000, "maximum": 1000 }, { "type": "number", "minimum": -1000, "maximum": 1000 }, { "type": "number", "minimum": -1000, "maximum": 1000 } ], "description": "3D point as [x, y, z] tuple, each coordinate in [-1000, 1000]" }, "PhoneNestBody": { "type": "object", "properties": { "params": { "$ref": "#/components/schemas/PhoneNestParams" }, "outputs": { "$ref": "#/components/schemas/OutputOptions" } }, "required": [ "outputs" ], "additionalProperties": false, "description": "Request body for the Phone Nest model" }, "PhoneNestParams": { "type": "object", "properties": { "heightBottom": { "description": "Height of the bottom section (cm)", "type": "number", "exclusiveMinimum": 0, "maximum": 50 }, "heightTop": { "description": "Height of the top section (cm)", "type": "number", "exclusiveMinimum": 0, "maximum": 50 }, "widthBack": { "description": "Width at the back (cm)", "type": "number", "exclusiveMinimum": 0, "maximum": 50 }, "widthFront": { "description": "Width at the front (cm)", "type": "number", "exclusiveMinimum": 0, "maximum": 50 }, "length": { "description": "Depth / length (cm)", "type": "number", "exclusiveMinimum": 0, "maximum": 50 }, "backOffset": { "description": "Back curve offset (cm)", "type": "number", "minimum": 0, "maximum": 30 }, "thickness": { "description": "Shell wall thickness", "type": "number", "exclusiveMinimum": 0, "maximum": 5 }, "applyOrnaments": { "description": "Add decorative perforations to the surface", "type": "boolean" }, "filletRadius": { "description": "Fillet radius on loft edges", "type": "number", "minimum": 0, "maximum": 15 }, "phoneHeight": { "description": "Phone mock-up height (cm)", "type": "number", "exclusiveMinimum": 0, "maximum": 35 }, "phoneWidth": { "description": "Phone mock-up width (cm)", "type": "number", "exclusiveMinimum": 0, "maximum": 35 }, "phoneThickness": { "description": "Phone mock-up thickness (cm)", "type": "number", "exclusiveMinimum": 0, "maximum": 3 }, "precision": { "description": "Geometry precision (lower = finer)", "$ref": "#/components/schemas/MeshPrecision" }, "rotation": { "description": "Final rotation angle (degrees)", "type": "number", "minimum": -360, "maximum": 360 }, "scale": { "description": "Uniform scale factor", "$ref": "#/components/schemas/PositiveScale" }, "origin": { "description": "[x, y, z] placement origin", "$ref": "#/components/schemas/Point3" }, "direction": { "description": "[x, y, z] up direction", "$ref": "#/components/schemas/Point3" } }, "additionalProperties": false, "description": "Phone Nest model parameters - all optional, sane defaults apply" }, "StepToGltfBody": { "type": "object", "properties": { "stepFileId": { "type": "string", "minLength": 1, "description": "ID of the previously uploaded STEP file (returned by the file upload endpoint)" }, "meshPrecision": { "description": "Mesh linear deflection. When meshRelative is true (default), this is a fraction of each edge's length (e.g. 0.005 = 0.5%). When false, it is an absolute value in model units (mm for STEP).", "$ref": "#/components/schemas/MeshPrecision" }, "meshAngle": { "description": "Angular deflection in radians for mesh tessellation - controls curvature approximation. Smaller values produce smoother curved surfaces.", "$ref": "#/components/schemas/MeshAngle" }, "meshRelative": { "description": "Use size-aware relative deflection per face. When true, meshPrecision is a fraction of each edge's length. Set to false for absolute deflection in model units.", "type": "boolean" }, "internalVerticesMode": { "description": "Add interior vertices for better curved face fidelity (slower, set false for speed).", "type": "boolean" }, "controlSurfaceDeflection": { "description": "Extra post-pass refining triangles that bulge beyond the deflection (slower, set false for speed).", "type": "boolean" } }, "required": [ "stepFileId" ], "additionalProperties": false, "description": "Convert a STEP file to glTF format with default settings. Upload the STEP file first, then pass its ID here." }, "MeshAngle": { "type": "number", "minimum": 0.01, "maximum": 3.141592653589793, "description": "Mesh angular deflection in radians. Range: [0.01, π]" }, "StepToGltfAdvancedBody": { "type": "object", "properties": { "stepFileId": { "type": "string", "minLength": 1, "description": "ID of the previously uploaded STEP file (returned by the file upload endpoint)" }, "options": { "description": "Advanced conversion settings. If omitted, sensible defaults are used.", "$ref": "#/components/schemas/ConvertAdvancedOptions" } }, "required": [ "stepFileId" ], "additionalProperties": false, "description": "Convert a STEP file to glTF with full control over tessellation, naming, coordinate systems, and output format." }, "ConvertAdvancedOptions": { "type": "object", "properties": { "readColors": { "description": "Extract color attributes from the STEP file and apply to glTF materials", "type": "boolean" }, "readNames": { "description": "Extract product/instance names from the STEP file and apply to glTF node names", "type": "boolean" }, "readMaterials": { "description": "Extract material definitions from the STEP file", "type": "boolean" }, "readLayers": { "description": "Extract layer/group structure from the STEP file", "type": "boolean" }, "readProps": { "description": "Extract custom properties (e.g. part numbers, metadata) from the STEP file", "type": "boolean" }, "meshDeflection": { "description": "Mesh linear deflection. When meshRelative is true (default), this is a fraction of each edge's length (e.g. 0.005 = 0.5%) so deflection auto-scales with feature size. When false, it is absolute in model units (mm for STEP).", "$ref": "#/components/schemas/MeshPrecision" }, "meshAngle": { "description": "Angular deflection for mesh tessellation (radians) - controls curvature approximation", "$ref": "#/components/schemas/MeshAngle" }, "meshParallel": { "description": "Enable parallel tessellation for faster processing", "type": "boolean" }, "meshRelative": { "description": "Use size-aware relative deflection per face. When true, meshDeflection is a fraction of each edge's length. Set to false for absolute deflection in model units.", "type": "boolean" }, "internalVerticesMode": { "description": "Add interior vertices for better curved face fidelity (slower, set false for speed).", "type": "boolean" }, "controlSurfaceDeflection": { "description": "Extra post-pass refining triangles that bulge beyond the deflection (slower, set false for speed).", "type": "boolean" }, "faceCountThreshold": { "description": "Face count threshold for per-sub-shape meshing fallback. Default -1 means single-pass meshing of the whole compound (fastest). Set to a positive value (e.g. 100000) to fall back to per-solid meshing for very large assemblies in memory-constrained environments.", "type": "integer", "minimum": -1, "maximum": 500000 }, "mergeFaces": { "description": "Merge co-planar adjacent faces to reduce mesh complexity", "type": "boolean" }, "splitIndices16": { "description": "Split meshes so each uses 16-bit index buffers (max 65535 vertices per mesh). Improves compatibility with some renderers.", "type": "boolean" }, "parallelWrite": { "description": "Write glTF output in parallel for faster file generation", "type": "boolean" }, "embedTextures": { "description": "Embed texture data directly in the .glb file instead of referencing external URIs", "type": "boolean" }, "forceUVExport": { "description": "Generate UV coordinates even when no textures are present (useful for post-processing)", "type": "boolean" }, "nodeNameFormat": { "description": "Strategy for naming glTF nodes from STEP product/instance labels", "$ref": "#/components/schemas/GltfNameFormat" }, "meshNameFormat": { "description": "Strategy for naming glTF meshes from STEP product/instance labels", "$ref": "#/components/schemas/GltfNameFormat" }, "transformFormat": { "description": "Transform representation in glTF: 'compact' (default), 'mat4' (4x4 matrix), or 'trs' (translation/rotation/scale)", "$ref": "#/components/schemas/GltfTransformFormat" }, "adjustZtoY": { "description": "Convert from Z-up (CAD convention) to Y-up (glTF/WebGL convention) coordinate system", "type": "boolean" }, "scale": { "description": "Uniform scale factor applied to the entire model (e.g. 0.001 to convert mm to meters)", "$ref": "#/components/schemas/PositiveScale" } }, "additionalProperties": false, "description": "Fine-grained options controlling STEP → glTF conversion: tessellation quality, attribute extraction, coordinate systems, and output format." }, "GltfNameFormat": { "type": "string", "enum": [ "empty", "product", "instance", "instanceOrProduct", "productOrInstance", "productAndInstance", "productAndInstanceAndOcaf" ], "description": "How node/mesh names are derived from STEP product/instance labels" }, "GltfTransformFormat": { "type": "string", "enum": [ "compact", "mat4", "trs" ], "description": "Transform representation in glTF output" }, "StepToGltfWithDracoBody": { "type": "object", "properties": { "stepFileId": { "type": "string", "minLength": 1, "description": "ID of the previously uploaded STEP file (returned by the file upload endpoint)" }, "meshPrecision": { "description": "Mesh linear deflection. When meshRelative is true (default), this is a fraction of each edge's length (e.g. 0.005 = 0.5%). When false, it is an absolute value in model units (mm for STEP).", "$ref": "#/components/schemas/MeshPrecision" }, "meshAngle": { "description": "Angular deflection in radians for mesh tessellation - controls curvature approximation. Smaller values produce smoother curved surfaces.", "$ref": "#/components/schemas/MeshAngle" }, "meshRelative": { "description": "Use size-aware relative deflection per face. When true, meshPrecision is a fraction of each edge's length. Set to false for absolute deflection in model units.", "type": "boolean" }, "internalVerticesMode": { "description": "Add interior vertices for better curved face fidelity (slower, set false for speed).", "type": "boolean" }, "controlSurfaceDeflection": { "description": "Extra post-pass refining triangles that bulge beyond the deflection (slower, set false for speed).", "type": "boolean" }, "draco": { "description": "Draco compression options. If omitted, sensible defaults are used (level 7, 14/10/12/8/12 bits).", "$ref": "#/components/schemas/DracoCompressionOptions" } }, "required": [ "stepFileId" ], "additionalProperties": false, "description": "Convert a STEP file to Draco-compressed glTF with default settings. Upload the STEP file first, then pass its ID here." }, "DracoCompressionOptions": { "type": "object", "properties": { "useDraco": { "description": "Apply Draco geometry compression to the glTF output. Defaults to true for the *-with-draco endpoints.", "type": "boolean" }, "dracoCompressionLevel": { "description": "Draco compression level (0 = fastest/largest, 10 = slowest/smallest). Typical good default is 7.", "type": "integer", "minimum": 0, "maximum": 10 }, "dracoQuantizePositionBits": { "description": "Quantization bits for vertex positions (higher = more precise, larger file). Typical: 14.", "type": "integer", "minimum": 0, "maximum": 31 }, "dracoQuantizeNormalBits": { "description": "Quantization bits for normal vectors. Typical: 10.", "type": "integer", "minimum": 0, "maximum": 31 }, "dracoQuantizeTexcoordBits": { "description": "Quantization bits for texture coordinates. Typical: 12.", "type": "integer", "minimum": 0, "maximum": 31 }, "dracoQuantizeColorBits": { "description": "Quantization bits for vertex colors. Typical: 8.", "type": "integer", "minimum": 0, "maximum": 31 }, "dracoQuantizeGenericBits": { "description": "Quantization bits for generic vertex attributes. Typical: 12.", "type": "integer", "minimum": 0, "maximum": 31 }, "dracoUnifiedQuantization": { "description": "Use unified quantization across all meshes (better when meshes share a coordinate frame).", "type": "boolean" } }, "additionalProperties": false, "description": "Draco geometry compression options applied during glTF export." }, "StepToGltfAdvancedWithDracoBody": { "type": "object", "properties": { "stepFileId": { "type": "string", "minLength": 1, "description": "ID of the previously uploaded STEP file (returned by the file upload endpoint)" }, "options": { "description": "Advanced conversion settings. If omitted, sensible defaults are used.", "$ref": "#/components/schemas/ConvertAdvancedOptions" }, "draco": { "description": "Draco compression options. If omitted, sensible defaults are used (level 7, 14/10/12/8/12 bits).", "$ref": "#/components/schemas/DracoCompressionOptions" } }, "required": [ "stepFileId" ], "additionalProperties": false, "description": "Convert a STEP file to Draco-compressed glTF with full control over tessellation, naming, coordinate systems, output format, and Draco quantization." }, "UnfoldFaceToFlatBody": { "type": "object", "properties": { "stepFileId": { "type": "string", "minLength": 1, "description": "ID of the previously uploaded STEP file (returned by the file upload endpoint)" }, "faceIndex": { "default": 0, "description": "0-based index of the developable face (in the shape's BRepGraph face array) to unfold.", "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "outputs": { "description": "Output formats for the flattened face geometry. Defaults to glTF.", "$ref": "#/components/schemas/OutputOptions" } }, "required": [ "stepFileId" ], "additionalProperties": false, "description": "Unfold a single developable face of an uploaded STEP shape to a flat face." }, "UnfoldFaceReportBody": { "type": "object", "properties": { "stepFileId": { "type": "string", "minLength": 1, "description": "ID of the previously uploaded STEP file (returned by the file upload endpoint)" }, "faceIndex": { "default": 0, "description": "0-based index of the face to analyze.", "type": "integer", "minimum": 0, "maximum": 9007199254740991 } }, "required": [ "stepFileId" ], "additionalProperties": false, "description": "Compute the sheet-metal unfold metrics report for a single face of an uploaded STEP shape." }, "UnfoldSolidToFlatBody": { "type": "object", "properties": { "stepFileId": { "type": "string", "minLength": 1, "description": "ID of the previously uploaded STEP file (returned by the file upload endpoint)" }, "kFactor": { "default": 0.5, "description": "Sheet-metal K-factor (neutral-axis position), typically ~0.5.", "type": "number", "minimum": 0, "maximum": 1 }, "thicknessOverride": { "default": 0, "description": "Sheet thickness override in model units; 0 auto-detects thickness from face pairs.", "type": "number", "minimum": 0 }, "outputs": { "description": "Output formats for the flattened patterns. Every solid's flat is combined into one compound output per format. Defaults to glTF.", "$ref": "#/components/schemas/OutputOptions" } }, "required": [ "stepFileId" ], "additionalProperties": false, "description": "Flatten every constant-thickness sheet-metal solid in an uploaded STEP file to flat patterns." }, "UnfoldSolidReportBody": { "type": "object", "properties": { "stepFileId": { "type": "string", "minLength": 1, "description": "ID of the previously uploaded STEP file (returned by the file upload endpoint)" }, "kFactor": { "default": 0.5, "description": "Sheet-metal K-factor (neutral-axis position), typically ~0.5.", "type": "number", "minimum": 0, "maximum": 1 }, "thicknessOverride": { "default": 0, "description": "Sheet thickness override in model units; 0 auto-detects thickness from face pairs.", "type": "number", "minimum": 0 } }, "required": [ "stepFileId" ], "additionalProperties": false, "description": "Compute per-solid sheet-metal unfold metrics for every solid in an uploaded STEP file." }, "UnfoldSolidBody": { "type": "object", "properties": { "stepFileId": { "type": "string", "minLength": 1, "description": "ID of the previously uploaded STEP file (returned by the file upload endpoint)" }, "kFactor": { "default": 0.5, "description": "Sheet-metal K-factor (neutral-axis position), typically ~0.5.", "type": "number", "minimum": 0, "maximum": 1 }, "thicknessOverride": { "default": 0, "description": "Sheet thickness override in model units; 0 auto-detects thickness from face pairs.", "type": "number", "minimum": 0 }, "outputs": { "description": "Output formats for the flattened patterns. Every solid's flat is combined into one compound output per format. Defaults to glTF.", "$ref": "#/components/schemas/OutputOptions" } }, "required": [ "stepFileId" ], "additionalProperties": false, "description": "Flatten every constant-thickness sheet-metal solid in an uploaded STEP file AND return the per-solid metrics report - both in one call." }, "FileUploadBody": { "type": "object", "properties": { "filename": { "type": "string", "minLength": 1, "maxLength": 255, "description": "Original filename including extension (e.g. 'part.step', 'model.obj'). Used for display and format detection." }, "contentType": { "type": "string", "minLength": 1, "maxLength": 255, "description": "MIME type of the file (e.g. 'application/step', 'model/gltf-binary'). Must match the actual file content." }, "bytes": { "type": "integer", "exclusiveMinimum": 0, "maximum": 1073741824, "description": "Exact file size in bytes. Must match the Content-Length of the subsequent PUT to the upload URL. Maximum: 1 GB." }, "sha256": { "description": "SHA-256 hex digest of the file content. When provided, enables server-side deduplication - if an identical file was previously uploaded under this API key, the existing file is reused and no upload is needed.", "type": "string", "minLength": 1, "maxLength": 128 } }, "required": [ "filename", "contentType", "bytes" ], "additionalProperties": false, "description": "Request a pre-signed upload URL. After receiving the URL, PUT the raw file bytes to it within the expiration window." }, "UnfoldReportError": { "type": "object", "properties": { "ok": { "type": "boolean", "const": false }, "error": { "type": "string" } }, "required": [ "ok", "error" ], "description": "Returned when a shape/face cannot be processed by the unfold." }, "UnfoldSolidReportItem": { "anyOf": [ { "type": "object", "properties": { "ok": { "type": "boolean", "const": true }, "thickness": { "type": "number" }, "kFactor": { "type": "number" }, "warning": { "type": "string" }, "bends": { "type": "array", "items": { "$ref": "#/components/schemas/UnfoldBend" } }, "flatBBox": { "type": "array", "prefixItems": [ { "type": "number" }, { "type": "number" }, { "type": "number" }, { "type": "number" } ] }, "flatArea": { "type": "number" }, "referenceArea": { "type": "number" }, "totalArea": { "type": "number" }, "faces": { "type": "array", "items": { "$ref": "#/components/schemas/UnfoldFaceEntry" } }, "placed": { "type": "array", "items": { "$ref": "#/components/schemas/UnfoldPlaced" } } }, "required": [ "ok", "thickness", "kFactor", "warning", "bends", "flatBBox", "flatArea", "referenceArea", "totalArea", "faces", "placed" ] }, { "$ref": "#/components/schemas/UnfoldSolidReportError" } ], "description": "Sheet-metal unfold metrics for ONE solid (bend table + face roles + original->flat map). On failure, the ok:false branch still carries the partial diagnostics gathered before the failure." }, "UnfoldBend": { "type": "object", "properties": { "faceIndex": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "flatA": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "flatB": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "lineStart": { "type": "array", "prefixItems": [ { "type": "number" }, { "type": "number" }, { "type": "number" } ] }, "lineEnd": { "type": "array", "prefixItems": [ { "type": "number" }, { "type": "number" }, { "type": "number" } ] }, "lineMid": { "type": "array", "prefixItems": [ { "type": "number" }, { "type": "number" }, { "type": "number" } ] }, "bendLineLength": { "type": "number" }, "angleDeg": { "type": "number" }, "innerRadius": { "type": "number" }, "outerRadius": { "type": "number" }, "neutralRadius": { "type": "number" }, "innerRadiusStart": { "type": "number" }, "innerRadiusEnd": { "type": "number" }, "outerRadiusStart": { "type": "number" }, "outerRadiusEnd": { "type": "number" }, "T": { "type": "number" }, "K": { "type": "number" }, "allowance": { "type": "number" }, "bendDeduction": { "type": "number" }, "outsideSetback": { "type": "number" }, "innerArcLength": { "type": "number" }, "outerArcLength": { "type": "number" }, "direction": { "type": "string", "enum": [ "up", "down" ] }, "kind": { "type": "string", "enum": [ "cyl", "cone" ] }, "layoutApprox": { "type": "boolean" } }, "required": [ "faceIndex", "flatA", "flatB", "lineStart", "lineEnd", "lineMid", "bendLineLength", "angleDeg", "innerRadius", "outerRadius", "neutralRadius", "innerRadiusStart", "innerRadiusEnd", "outerRadiusStart", "outerRadiusEnd", "T", "K", "allowance", "bendDeduction", "outsideSetback", "innerArcLength", "outerArcLength", "direction", "kind", "layoutApprox" ], "description": "One bend: line, angle, radii (inner/outer/neutral and per-end for cones), and developed lengths." }, "UnfoldFaceEntry": { "type": "object", "properties": { "index": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "uid": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "surfaceType": { "type": "string", "enum": [ "Plane", "Cylinder", "Cone", "Sphere", "Torus", "Other" ] }, "role": { "type": "string", "enum": [ "referenceFlat", "otherSideFlat", "rim", "flat", "bend", "coneBend", "cutout", "ignored" ] }, "reference": { "type": "boolean" }, "opposite": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "area": { "type": "number" }, "centroid": { "type": "array", "prefixItems": [ { "type": "number" }, { "type": "number" }, { "type": "number" } ] }, "labelPoint": { "type": "array", "prefixItems": [ { "type": "number" }, { "type": "number" }, { "type": "number" } ] }, "tangentDot": { "description": "Bend candidates (cylinder/cone) only: best |flange normal · cylinder radial| over the flanges. ~1 = tangent fold, ~0 = cutout/hole wall.", "type": "number" }, "bendOutcome": { "description": "How the fold filter classified a bend candidate: 'fold' (kept), 'cutout' (rejected - not tangent / <2 flanges), 'duplicate' (dropped - one fold per flat pair), or '' (a bend face not on the reference side, never evaluated by the filter).", "type": "string", "enum": [ "fold", "cutout", "duplicate", "" ] } }, "required": [ "index", "uid", "surfaceType", "role", "reference", "opposite", "area", "centroid", "labelPoint" ], "description": "A classified source face: stable key (index + BRepGraph uid), role, and label anchors." }, "UnfoldPlaced": { "type": "object", "properties": { "kind": { "type": "string", "enum": [ "flat", "bendStrip" ] }, "sourceFaceIndex": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "role": { "anyOf": [ { "type": "string", "enum": [ "referenceFlat", "otherSideFlat", "rim", "flat", "bend", "coneBend", "cutout", "ignored" ] }, { "type": "string", "const": "unknown" } ] }, "flatCentroid": { "type": "array", "prefixItems": [ { "type": "number" }, { "type": "number" }, { "type": "number" } ] } }, "required": [ "kind", "sourceFaceIndex", "role", "flatCentroid" ], "description": "A sub-shape laid into the flat compound, mapped back to its source face (compound order)." }, "UnfoldSolidReportError": { "type": "object", "properties": { "ok": { "type": "boolean", "const": false }, "error": { "type": "string" }, "thickness": { "type": "number" }, "kFactor": { "type": "number" }, "warning": { "type": "string" }, "bends": { "type": "array", "items": { "$ref": "#/components/schemas/UnfoldBend" } }, "flatBBox": { "type": "array", "prefixItems": [ { "type": "number" }, { "type": "number" }, { "type": "number" }, { "type": "number" } ] }, "flatArea": { "type": "number" }, "referenceArea": { "type": "number" }, "totalArea": { "type": "number" }, "faces": { "type": "array", "items": { "$ref": "#/components/schemas/UnfoldFaceEntry" } }, "placed": { "type": "array", "items": { "$ref": "#/components/schemas/UnfoldPlaced" } } }, "required": [ "ok", "error" ], "description": "Returned when a solid cannot be fully unfolded; carries the partial diagnostics gathered before the failure (classified faces with roles, detected thickness, warnings) so the reason can be inspected." }, "HealthResponse": { "type": "object", "properties": { "ok": { "type": "boolean", "const": true }, "data": { "$ref": "#/components/schemas/HealthStatus" } }, "required": [ "ok", "data" ], "additionalProperties": false, "description": "Success envelope for health check" }, "HealthStatus": { "type": "object", "properties": { "status": { "type": "string", "enum": [ "ok", "degraded" ], "description": "Overall health status" }, "timestamp": { "type": "string", "description": "ISO 8601 timestamp" } }, "required": [ "status", "timestamp" ], "additionalProperties": false, "description": "API health check result indicating overall system status" }, "TaskAcceptedResponse": { "type": "object", "properties": { "ok": { "type": "boolean", "const": true }, "data": { "$ref": "#/components/schemas/TaskCreatedResult" } }, "required": [ "ok", "data" ], "additionalProperties": false, "description": "HTTP 202 response when a task is accepted for async processing" }, "TaskCreatedResult": { "type": "object", "properties": { "taskId": { "type": "string", "description": "Unique task identifier - use this to poll for status and retrieve results", "format": "uuid" }, "status": { "type": "string", "const": "queued", "description": "Initial task status (always 'queued' upon creation)" }, "statusUrl": { "type": "string", "description": "Relative URL to poll for task status updates", "example": "/api/v1/tasks/{taskId}" } }, "required": [ "taskId", "status", "statusUrl" ], "additionalProperties": false, "description": "Returned when a CAD task is accepted. Poll the statusUrl to track progress." }, "ErrorResponse": { "type": "object", "properties": { "ok": { "type": "boolean", "const": false }, "error": { "$ref": "#/components/schemas/ErrorDetail" } }, "required": [ "ok", "error" ], "additionalProperties": false, "description": "Standard error envelope" }, "ErrorDetail": { "type": "object", "properties": { "code": { "type": "string", "description": "Machine-readable error code", "example": "VALIDATION_ERROR" }, "message": { "type": "string", "description": "Human-readable error message" }, "details": { "description": "Optional structured error context" }, "requestId": { "description": "Request ID for tracing", "type": "string" } }, "required": [ "code", "message" ], "additionalProperties": false, "description": "Structured error information with machine-readable code and optional debugging context" }, "CompoundTaskAcceptedResponse": { "type": "object", "properties": { "ok": { "type": "boolean", "const": true }, "data": { "$ref": "#/components/schemas/CompoundTaskCreatedResult" } }, "required": [ "ok", "data" ], "additionalProperties": false, "description": "HTTP 202 response when a compound (parallel) task is accepted" }, "CompoundTaskCreatedResult": { "type": "object", "properties": { "taskId": { "type": "string", "description": "Parent compound task ID for tracking overall progress" }, "kind": { "type": "string", "const": "compound" }, "subTaskCount": { "type": "integer", "exclusiveMinimum": 0, "maximum": 9007199254740991, "description": "Total number of sub-tasks created (one per item in the request)" }, "statusUrl": { "type": "string", "description": "Relative URL to poll the parent task status", "example": "/api/v1/tasks/{taskId}" }, "subTasks": { "type": "array", "items": { "$ref": "#/components/schemas/SubTaskSummary" } } }, "required": [ "taskId", "kind", "subTaskCount", "statusUrl", "subTasks" ], "additionalProperties": false, "description": "Returned when a compound (parallel) task is accepted. Contains initial status for all sub-tasks." }, "SubTaskSummary": { "type": "object", "properties": { "taskId": { "type": "string", "description": "Unique identifier for this sub-task (can be polled individually)" }, "index": { "type": "integer", "minimum": 0, "maximum": 9007199254740991, "description": "Zero-based position of this sub-task within the compound" }, "status": { "$ref": "#/components/schemas/TaskStatus" }, "progress": { "anyOf": [ { "type": "number" }, { "type": "null" } ], "description": "Completion percentage (0–100) or null if not yet started" }, "computeMs": { "anyOf": [ { "type": "number" }, { "type": "null" } ], "description": "Actual compute time in milliseconds (null until completed)" }, "error": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Error message if sub-task failed, null otherwise" }, "downloadFormats": { "type": "array", "items": { "type": "string" }, "description": "Available output format keys (e.g. ['glb', 'stpz']) for downloading results" } }, "required": [ "taskId", "index", "status", "progress", "computeMs", "error", "downloadFormats" ], "additionalProperties": false, "description": "Status summary for one sub-task within a compound (parallel) task" }, "TaskStatus": { "type": "string", "enum": [ "waiting", "queued", "processing", "completed", "failed", "cancelled", "expired" ], "description": "Task lifecycle state: waiting (pending dependencies), queued (in queue), processing (actively computing), completed (result available), failed (error occurred), cancelled (user-cancelled), expired (result TTL exceeded)" }, "ModelListResponse": { "type": "object", "properties": { "ok": { "type": "boolean", "const": true }, "data": { "$ref": "#/components/schemas/ModelList" } }, "required": [ "ok", "data" ], "additionalProperties": false, "description": "Success envelope containing the list of available models" }, "ModelList": { "type": "object", "properties": { "models": { "type": "array", "items": { "type": "string" }, "description": "Available model slugs that can be used with the /models/{name} endpoints" } }, "required": [ "models" ], "additionalProperties": false, "description": "List of all available parametric models" }, "ModelBatchDefinitionsResponse": { "type": "object", "properties": { "ok": { "type": "boolean", "const": true }, "data": { "$ref": "#/components/schemas/ModelBatchDefinitions" } }, "required": [ "ok", "data" ], "additionalProperties": false, "description": "Success envelope containing multiple model definitions" }, "ModelBatchDefinitions": { "type": "object", "properties": { "definitions": { "type": "object", "propertyNames": { "type": "string" }, "additionalProperties": { "$ref": "#/components/schemas/ModelDefinition" }, "description": "Model definitions keyed by slug. Each contains parameter schemas and defaults." } }, "required": [ "definitions" ], "additionalProperties": false, "description": "Definitions for multiple models in a single response" }, "ModelDefinition": { "type": "object", "properties": { "name": { "type": "string", "description": "Model slug used in API paths (e.g. 'dragon-cup')" }, "displayName": { "type": "string", "description": "Human-friendly model name for UI display" }, "description": { "type": "string", "description": "What this model creates and its key characteristics" }, "params": { "type": "array", "items": { "$ref": "#/components/schemas/ModelParamDefinition" }, "description": "All accepted parameters with types, descriptions, and defaults" }, "defaults": { "type": "object", "propertyNames": { "type": "string" }, "additionalProperties": {}, "description": "Complete default parameter values map" } }, "required": [ "name", "displayName", "description", "params", "defaults" ], "additionalProperties": false, "description": "Full definition of a parametric model including all parameters and their constraints" }, "ModelParamDefinition": { "type": "object", "properties": { "name": { "type": "string", "description": "Parameter name as used in the request body" }, "type": { "description": "Expected data type for this parameter", "$ref": "#/components/schemas/ModelParamApiType" }, "description": { "type": "string", "description": "Human-readable explanation of what this parameter controls" }, "default": { "description": "Default value used when the parameter is omitted" }, "items": { "description": "Element type descriptor (only present for array parameters)", "type": "object", "properties": { "type": { "type": "string" } }, "required": [ "type" ], "additionalProperties": false } }, "required": [ "name", "type", "description", "default" ], "additionalProperties": false, "description": "Schema definition for a single model parameter" }, "ModelParamApiType": { "type": "string", "enum": [ "number", "integer", "boolean", "array" ], "description": "Data type of a model parameter: 'number' (float), 'integer' (whole number), 'boolean' (true/false), 'array' (list of values)" }, "ModelDefinitionResponse": { "type": "object", "properties": { "ok": { "type": "boolean", "const": true }, "data": { "$ref": "#/components/schemas/ModelDefinition" } }, "required": [ "ok", "data" ], "additionalProperties": false, "description": "Success envelope containing a single model's definition" }, "UploadResponse": { "type": "object", "properties": { "ok": { "type": "boolean", "const": true }, "data": { "$ref": "#/components/schemas/UploadResult" } }, "required": [ "ok", "data" ], "additionalProperties": false, "description": "Success envelope containing the pre-signed upload URL and file metadata" }, "UploadResult": { "type": "object", "properties": { "fileId": { "type": "string", "description": "Assigned file identifier - use this to reference the file in subsequent API calls", "format": "uuid" }, "uploadUrl": { "type": "string", "description": "Pre-signed URL to PUT the raw file bytes to. Send the file content with Content-Type and Content-Length headers matching the request.", "format": "uri" }, "expiresIn": { "type": "integer", "exclusiveMinimum": 0, "maximum": 9007199254740991, "description": "Seconds until the upload URL expires. You must complete the PUT within this window." }, "maxBytes": { "type": "integer", "exclusiveMinimum": 0, "maximum": 9007199254740991, "description": "Maximum allowed file size in bytes for this upload. Determined by your plan tier." }, "status": { "type": "string", "const": "pending" } }, "required": [ "fileId", "uploadUrl", "expiresIn", "maxBytes", "status" ], "additionalProperties": false, "description": "Response after requesting a file upload. Contains the pre-signed URL to PUT your file to." }, "FileListResponse": { "type": "object", "properties": { "ok": { "type": "boolean", "const": true }, "data": { "$ref": "#/components/schemas/FileList" } }, "required": [ "ok", "data" ], "additionalProperties": false, "description": "Success envelope containing a paginated file list" }, "FileList": { "type": "object", "properties": { "files": { "type": "array", "items": { "$ref": "#/components/schemas/FileDetail" } }, "page": { "type": "integer", "exclusiveMinimum": 0, "maximum": 1000 }, "limit": { "type": "integer", "exclusiveMinimum": 0, "maximum": 50 }, "total": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 } }, "required": [ "files", "page", "limit", "total" ], "additionalProperties": false, "description": "Paginated list of uploaded files with total count" }, "FileDetail": { "type": "object", "properties": { "fileId": { "type": "string", "description": "Unique file identifier used to reference this file in CAD operations", "format": "uuid" }, "filename": { "type": "string", "description": "Original filename as provided during upload request" }, "contentType": { "type": "string", "description": "MIME type of the file content" }, "bytes": { "anyOf": [ { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, { "type": "null" } ], "description": "File size in bytes. Null while status is 'pending' (not yet uploaded)." }, "sha256": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "SHA-256 hex digest of the file content. Null if not provided during upload. Used for deduplication." }, "status": { "$ref": "#/components/schemas/FileStatus" }, "createdAt": { "type": "string", "description": "ISO 8601 timestamp when the upload was initiated" }, "confirmedAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ISO 8601 timestamp when the upload was confirmed. Null if not yet confirmed." }, "downloadUrl": { "description": "Pre-signed download URL. Only present for confirmed files. Expires after 1 hour.", "type": "string" } }, "required": [ "fileId", "filename", "contentType", "bytes", "sha256", "status", "createdAt", "confirmedAt" ], "additionalProperties": false, "description": "Full metadata for an uploaded file" }, "FileStatus": { "type": "string", "enum": [ "pending", "confirmed", "expired" ], "description": "File lifecycle state: 'pending' (upload URL issued, awaiting PUT), 'confirmed' (upload verified and file is usable), 'expired' (upload URL expired before completion)" }, "FileDetailResponse": { "type": "object", "properties": { "ok": { "type": "boolean", "const": true }, "data": { "$ref": "#/components/schemas/FileDetail" } }, "required": [ "ok", "data" ], "additionalProperties": false, "description": "Success envelope containing a single file's metadata" }, "DeleteFileResponse": { "type": "object", "properties": { "ok": { "type": "boolean", "const": true }, "data": { "$ref": "#/components/schemas/DeleteResult" } }, "required": [ "ok", "data" ], "additionalProperties": false, "description": "Success response for file deletion" }, "DeleteResult": { "type": "object", "properties": { "deleted": { "type": "boolean", "const": true } }, "required": [ "deleted" ], "additionalProperties": false, "description": "Confirmation that a resource was successfully deleted" }, "ConfirmResponse": { "type": "object", "properties": { "ok": { "type": "boolean", "const": true }, "data": { "$ref": "#/components/schemas/ConfirmResult" } }, "required": [ "ok", "data" ], "additionalProperties": false, "description": "Success envelope confirming a file upload was verified" }, "ConfirmResult": { "type": "object", "properties": { "fileId": { "type": "string", "description": "File identifier that was confirmed", "format": "uuid" }, "status": { "type": "string", "const": "confirmed" }, "bytes": { "type": "integer", "minimum": 0, "maximum": 9007199254740991, "description": "Actual file size in bytes as stored on the server" }, "contentType": { "type": "string", "description": "MIME type of the confirmed file" } }, "required": [ "fileId", "status", "bytes", "contentType" ], "additionalProperties": false, "description": "Returned after a file upload is verified. The file is now ready to be used in CAD operations." }, "TaskListResponse": { "type": "object", "properties": { "ok": { "type": "boolean", "const": true }, "data": { "$ref": "#/components/schemas/TaskList" } }, "required": [ "ok", "data" ], "additionalProperties": false, "description": "Success envelope containing a paginated task list" }, "TaskList": { "type": "object", "properties": { "tasks": { "type": "array", "items": { "$ref": "#/components/schemas/TaskDetail" } }, "page": { "type": "integer", "exclusiveMinimum": 0, "maximum": 1000 }, "limit": { "type": "integer", "exclusiveMinimum": 0, "maximum": 50 }, "total": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 } }, "required": [ "tasks", "page", "limit", "total" ], "additionalProperties": false, "description": "Paginated list of tasks with total count" }, "TaskDetail": { "type": "object", "properties": { "taskId": { "type": "string", "description": "Unique task identifier for polling and result retrieval", "format": "uuid" }, "kind": { "$ref": "#/components/schemas/TaskKind" }, "label": { "type": "string", "description": "Human-readable task label", "example": "Model: dragon-cup" }, "status": { "$ref": "#/components/schemas/TaskStatus" }, "progress": { "anyOf": [ { "type": "number" }, { "type": "null" } ], "description": "Completion percentage (0–100) or null if progress is not tracked for this task kind" }, "error": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Error message when status is 'failed'. Null for all other statuses." }, "resultParts": { "anyOf": [ { "type": "object", "propertyNames": { "type": "string" }, "additionalProperties": { "$ref": "#/components/schemas/ResultPartMeta" } }, { "type": "null" } ], "description": "Available result files keyed by format (e.g. 'glb', 'step'). Null until task completes." }, "metadata": { "anyOf": [ { "type": "object", "propertyNames": { "type": "string" }, "additionalProperties": {} }, { "type": "null" } ], "description": "Additional task metadata (e.g. resolved parameters, model name). Shape varies by task kind." }, "createdAt": { "type": "string", "description": "ISO 8601 timestamp when the task was created" }, "startedAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ISO 8601 timestamp when processing began. Null if still queued." }, "finishedAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "ISO 8601 timestamp when the task completed (success or failure). Null if still running." }, "expiresAt": { "type": "string", "description": "ISO 8601 timestamp when task results will be automatically deleted" } }, "required": [ "taskId", "kind", "label", "status", "progress", "error", "resultParts", "metadata", "createdAt", "startedAt", "finishedAt", "expiresAt" ], "additionalProperties": false, "description": "Complete task status including lifecycle timestamps, progress, and result metadata" }, "TaskKind": { "type": "string", "enum": [ "cad", "model", "convert-simple", "convert-advanced", "pipeline", "compound", "tenant" ], "description": "Type of work: 'cad' (single operation), 'model' (parametric model), 'convert-simple'/'convert-advanced' (file conversion), 'pipeline' (sequential chain), 'compound' (parallel batch), 'tenant' (tenant-scoped)" }, "ResultPartMeta": { "type": "object", "properties": { "mime": { "type": "string", "description": "MIME type of the result file (e.g. 'model/gltf-binary', 'application/step')" }, "bytes": { "type": "integer", "minimum": 0, "maximum": 9007199254740991, "description": "Size of the result file in bytes" } }, "required": [ "mime", "bytes" ], "additionalProperties": false, "description": "Metadata about a single downloadable result part" }, "TaskDetailResponse": { "type": "object", "properties": { "ok": { "type": "boolean", "const": true }, "data": { "$ref": "#/components/schemas/TaskDetail" } }, "required": [ "ok", "data" ], "additionalProperties": false, "description": "Success envelope containing a single task's full details" }, "CancelTaskResponse": { "type": "object", "properties": { "ok": { "type": "boolean", "const": true }, "data": { "$ref": "#/components/schemas/CancelResult" } }, "required": [ "ok", "data" ], "additionalProperties": false, "description": "Success response for task cancellation" }, "CancelResult": { "type": "object", "properties": { "cancelled": { "type": "boolean", "const": true }, "previousStatus": { "type": "string", "description": "Status before cancellation" } }, "required": [ "cancelled", "previousStatus" ], "additionalProperties": false, "description": "Confirmation that a task was successfully cancelled" }, "TaskOrCompoundResultResponse": { "anyOf": [ { "$ref": "#/components/schemas/TaskResultResponse" }, { "$ref": "#/components/schemas/CompoundResultManifestResponse" } ], "description": "Result download link for standard tasks, or a compound manifest with per-sub-task download links" }, "TaskResultResponse": { "type": "object", "properties": { "ok": { "type": "boolean", "const": true }, "data": { "$ref": "#/components/schemas/TaskResultDownload" } }, "required": [ "ok", "data" ], "additionalProperties": false, "description": "Success envelope containing a download link for a task result" }, "TaskResultDownload": { "type": "object", "properties": { "downloadUrl": { "type": "string", "description": "Pre-signed URL to download the result file. Expires after 1 hour.", "format": "uri" }, "filename": { "type": "string", "description": "Suggested filename for the download", "example": "result.glb" } }, "required": [ "downloadUrl", "filename" ], "additionalProperties": false, "description": "Download information for a completed task result" }, "CompoundResultManifestResponse": { "type": "object", "properties": { "ok": { "type": "boolean", "const": true }, "data": { "$ref": "#/components/schemas/CompoundResultManifest" } }, "required": [ "ok", "data" ], "additionalProperties": false, "description": "Success envelope containing the compound task result manifest with per-sub-task download links" }, "CompoundResultManifest": { "type": "object", "properties": { "manifest": { "type": "array", "items": { "$ref": "#/components/schemas/CompoundResultEntry" }, "description": "Per-sub-task status and download links" } }, "required": [ "manifest" ], "additionalProperties": false, "description": "Result manifest for a completed compound task" }, "CompoundResultEntry": { "type": "object", "properties": { "taskId": { "type": "string", "description": "Sub-task ID" }, "index": { "type": "integer", "minimum": 0, "maximum": 9007199254740991, "description": "Position in the compound task" }, "status": { "$ref": "#/components/schemas/TaskStatus" }, "downloadUrls": { "description": "Download URLs keyed by format (only if completed)", "type": "object", "propertyNames": { "type": "string" }, "additionalProperties": { "type": "string" } } }, "required": [ "taskId", "index", "status" ], "additionalProperties": false, "description": "Status/result info for one sub-task in a compound manifest" }, "TaskResultsResponse": { "type": "object", "properties": { "ok": { "type": "boolean", "const": true }, "data": { "$ref": "#/components/schemas/TaskResultsDownload" } }, "required": [ "ok", "data" ], "additionalProperties": false, "description": "Success envelope containing download links for all result formats" }, "TaskResultsDownload": { "type": "object", "properties": { "downloads": { "type": "array", "items": { "type": "object", "properties": { "format": { "type": "string", "description": "Result format key (e.g. 'glb', 'step', 'metadata')" }, "downloadUrl": { "type": "string", "description": "Pre-signed URL to download the result file. Expires after 1 hour.", "format": "uri" }, "filename": { "type": "string", "description": "Suggested filename for the download", "example": "result.glb" } }, "required": [ "format", "downloadUrl", "filename" ], "additionalProperties": false }, "description": "Download links for all available result formats" } }, "required": [ "downloads" ], "additionalProperties": false, "description": "Download information for all available result formats of a completed task" }, "UnfoldReportErrorOutput": { "type": "object", "properties": { "ok": { "type": "boolean", "const": false }, "error": { "type": "string" } }, "required": [ "ok", "error" ], "additionalProperties": false, "description": "Returned when a shape/face cannot be processed by the unfold." }, "UnfoldSolidReportItemOutput": { "anyOf": [ { "type": "object", "properties": { "ok": { "type": "boolean", "const": true }, "thickness": { "type": "number" }, "kFactor": { "type": "number" }, "warning": { "type": "string" }, "bends": { "type": "array", "items": { "$ref": "#/components/schemas/UnfoldBendOutput" } }, "flatBBox": { "type": "array", "prefixItems": [ { "type": "number" }, { "type": "number" }, { "type": "number" }, { "type": "number" } ] }, "flatArea": { "type": "number" }, "referenceArea": { "type": "number" }, "totalArea": { "type": "number" }, "faces": { "type": "array", "items": { "$ref": "#/components/schemas/UnfoldFaceEntryOutput" } }, "placed": { "type": "array", "items": { "$ref": "#/components/schemas/UnfoldPlacedOutput" } } }, "required": [ "ok", "thickness", "kFactor", "warning", "bends", "flatBBox", "flatArea", "referenceArea", "totalArea", "faces", "placed" ], "additionalProperties": false }, { "$ref": "#/components/schemas/UnfoldSolidReportErrorOutput" } ], "description": "Sheet-metal unfold metrics for ONE solid (bend table + face roles + original->flat map). On failure, the ok:false branch still carries the partial diagnostics gathered before the failure." }, "UnfoldBendOutput": { "type": "object", "properties": { "faceIndex": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "flatA": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "flatB": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "lineStart": { "type": "array", "prefixItems": [ { "type": "number" }, { "type": "number" }, { "type": "number" } ] }, "lineEnd": { "type": "array", "prefixItems": [ { "type": "number" }, { "type": "number" }, { "type": "number" } ] }, "lineMid": { "type": "array", "prefixItems": [ { "type": "number" }, { "type": "number" }, { "type": "number" } ] }, "bendLineLength": { "type": "number" }, "angleDeg": { "type": "number" }, "innerRadius": { "type": "number" }, "outerRadius": { "type": "number" }, "neutralRadius": { "type": "number" }, "innerRadiusStart": { "type": "number" }, "innerRadiusEnd": { "type": "number" }, "outerRadiusStart": { "type": "number" }, "outerRadiusEnd": { "type": "number" }, "T": { "type": "number" }, "K": { "type": "number" }, "allowance": { "type": "number" }, "bendDeduction": { "type": "number" }, "outsideSetback": { "type": "number" }, "innerArcLength": { "type": "number" }, "outerArcLength": { "type": "number" }, "direction": { "type": "string", "enum": [ "up", "down" ] }, "kind": { "type": "string", "enum": [ "cyl", "cone" ] }, "layoutApprox": { "type": "boolean" } }, "required": [ "faceIndex", "flatA", "flatB", "lineStart", "lineEnd", "lineMid", "bendLineLength", "angleDeg", "innerRadius", "outerRadius", "neutralRadius", "innerRadiusStart", "innerRadiusEnd", "outerRadiusStart", "outerRadiusEnd", "T", "K", "allowance", "bendDeduction", "outsideSetback", "innerArcLength", "outerArcLength", "direction", "kind", "layoutApprox" ], "additionalProperties": false, "description": "One bend: line, angle, radii (inner/outer/neutral and per-end for cones), and developed lengths." }, "UnfoldFaceEntryOutput": { "type": "object", "properties": { "index": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "uid": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "surfaceType": { "type": "string", "enum": [ "Plane", "Cylinder", "Cone", "Sphere", "Torus", "Other" ] }, "role": { "type": "string", "enum": [ "referenceFlat", "otherSideFlat", "rim", "flat", "bend", "coneBend", "cutout", "ignored" ] }, "reference": { "type": "boolean" }, "opposite": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "area": { "type": "number" }, "centroid": { "type": "array", "prefixItems": [ { "type": "number" }, { "type": "number" }, { "type": "number" } ] }, "labelPoint": { "type": "array", "prefixItems": [ { "type": "number" }, { "type": "number" }, { "type": "number" } ] }, "tangentDot": { "description": "Bend candidates (cylinder/cone) only: best |flange normal · cylinder radial| over the flanges. ~1 = tangent fold, ~0 = cutout/hole wall.", "type": "number" }, "bendOutcome": { "description": "How the fold filter classified a bend candidate: 'fold' (kept), 'cutout' (rejected - not tangent / <2 flanges), 'duplicate' (dropped - one fold per flat pair), or '' (a bend face not on the reference side, never evaluated by the filter).", "type": "string", "enum": [ "fold", "cutout", "duplicate", "" ] } }, "required": [ "index", "uid", "surfaceType", "role", "reference", "opposite", "area", "centroid", "labelPoint" ], "additionalProperties": false, "description": "A classified source face: stable key (index + BRepGraph uid), role, and label anchors." }, "UnfoldPlacedOutput": { "type": "object", "properties": { "kind": { "type": "string", "enum": [ "flat", "bendStrip" ] }, "sourceFaceIndex": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "role": { "anyOf": [ { "type": "string", "enum": [ "referenceFlat", "otherSideFlat", "rim", "flat", "bend", "coneBend", "cutout", "ignored" ] }, { "type": "string", "const": "unknown" } ] }, "flatCentroid": { "type": "array", "prefixItems": [ { "type": "number" }, { "type": "number" }, { "type": "number" } ] } }, "required": [ "kind", "sourceFaceIndex", "role", "flatCentroid" ], "additionalProperties": false, "description": "A sub-shape laid into the flat compound, mapped back to its source face (compound order)." }, "UnfoldSolidReportErrorOutput": { "type": "object", "properties": { "ok": { "type": "boolean", "const": false }, "error": { "type": "string" }, "thickness": { "type": "number" }, "kFactor": { "type": "number" }, "warning": { "type": "string" }, "bends": { "type": "array", "items": { "$ref": "#/components/schemas/UnfoldBendOutput" } }, "flatBBox": { "type": "array", "prefixItems": [ { "type": "number" }, { "type": "number" }, { "type": "number" }, { "type": "number" } ] }, "flatArea": { "type": "number" }, "referenceArea": { "type": "number" }, "totalArea": { "type": "number" }, "faces": { "type": "array", "items": { "$ref": "#/components/schemas/UnfoldFaceEntryOutput" } }, "placed": { "type": "array", "items": { "$ref": "#/components/schemas/UnfoldPlacedOutput" } } }, "required": [ "ok", "error" ], "additionalProperties": false, "description": "Returned when a solid cannot be fully unfolded; carries the partial diagnostics gathered before the failure (classified faces with roles, detected thickness, warnings) so the reason can be inspected." }, "UnfoldFaceReport": { "anyOf": [ { "type": "object", "properties": { "ok": { "type": "boolean", "const": true }, "faceIndex": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "surfaceType": { "type": "string", "enum": [ "Plane", "Cylinder", "Cone", "Sphere", "Torus", "Other" ] }, "developable": { "type": "boolean" }, "unfolded": { "type": "boolean" }, "area": { "type": "number" }, "flatArea": { "type": "number" }, "areaError": { "type": "number" } }, "required": [ "ok", "faceIndex", "surfaceType", "developable", "unfolded", "area", "flatArea", "areaError" ], "additionalProperties": false }, { "$ref": "#/components/schemas/UnfoldReportErrorOutput" } ], "description": "Sheet-metal unfold metrics for a single face (surface type, developability, area before/after)." }, "UnfoldSolidReport": { "type": "array", "items": { "allOf": [ { "$ref": "#/components/schemas/UnfoldSolidReportItemOutput" }, { "type": "object", "properties": { "solidIndex": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 } }, "required": [ "solidIndex" ], "additionalProperties": false } ] }, "description": "Per-solid sheet-metal unfold metrics - one entry per solid in the STEP file (each carries its solidIndex)." } }, "securitySchemes": { "ApiKeyAuth": { "type": "apiKey", "in": "header", "name": "X-API-Key", "description": "Scoped API key. Scopes: models, cad, convert, * (wildcard). A key without the required scope receives 403 INSUFFICIENT_SCOPE." } } } }