{
  "openapi": "3.1.0",
  "info": {
    "title": "Toolpath Engine API",
    "version": "1.0.3",
    "description": "Public REST API for Toolpath engine operations.\n\n**Units.** All dimensional values — in parts and in feature details — are in\nmillimetres; all angles are in degrees. Each part response also states this in its `units` field.\n\n**Browser use.** CORS is per API key: a request only receives an\n`Access-Control-Allow-Origin` header when its `Origin` is in the allowlist configured on the\nkey used (set when creating or editing the key in the portal). A key with no allowed origins\nis server-to-server only. A Bearer API key placed in client-side JavaScript is readable by\nanyone — restrict its origins, prefer a `read_only` key (read_only keys may call GET\noperations only; writes are rejected with 403), or proxy requests through your own server."
  },
  "tags": [
    {
      "name": "Service",
      "description": "Service-discovery and health operations."
    },
    {
      "name": "Keys",
      "description": "API key validation operations."
    },
    {
      "name": "Parts",
      "description": "Part upload and processing operations."
    },
    {
      "name": "Features",
      "description": "Part feature operations."
    },
    {
      "name": "Jobs",
      "description": "Asynchronous job operations."
    }
  ],
  "servers": [
    {
      "url": "https://api.toolpath.com",
      "description": "Toolpath Engine API"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "A Toolpath API key supplied as a Bearer credential."
      }
    },
    "schemas": {
      "HealthResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "ok",
              "error"
            ],
            "description": "Overall Engine API health state."
          },
          "db": {
            "type": "string",
            "enum": [
              "up",
              "down"
            ],
            "description": "PostgreSQL connectivity state."
          }
        },
        "required": [
          "status",
          "db"
        ]
      },
      "OpenApiDocument": {
        "type": "object",
        "properties": {
          "openapi": {
            "type": "string",
            "description": "OpenAPI specification version used by this document.",
            "example": "3.1.0"
          }
        },
        "required": [
          "openapi"
        ],
        "additionalProperties": {}
      },
      "KeyValidationResponse": {
        "type": "object",
        "properties": {
          "valid": {
            "type": "boolean",
            "description": "Whether the key is usable right now.",
            "example": true
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "revoked",
              "expired",
              "invalid"
            ],
            "description": "The derived key status: active (usable), revoked (disabled), expired (past expiry), or invalid (unknown key).",
            "example": "active"
          }
        },
        "required": [
          "valid",
          "status"
        ]
      },
      "ProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "format": "uri",
            "description": "A URI identifying the problem type.",
            "example": "https://api.toolpath.com/problems/invalid-api-key"
          },
          "title": {
            "type": "string",
            "description": "A short, human-readable summary of the problem.",
            "example": "Invalid API key"
          },
          "status": {
            "type": "integer",
            "minimum": 400,
            "maximum": 599,
            "description": "The HTTP status code for this occurrence.",
            "example": 401
          },
          "detail": {
            "type": "string",
            "description": "A human-readable explanation specific to this occurrence."
          },
          "instance": {
            "type": "string",
            "description": "A URI reference identifying this occurrence."
          },
          "code": {
            "type": "string",
            "description": "A stable, machine-readable Toolpath error code.",
            "example": "invalid_api_key"
          }
        },
        "required": [
          "type",
          "title",
          "status",
          "code"
        ]
      },
      "CreatePartResponse": {
        "type": "object",
        "properties": {
          "partId": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of the newly created part."
          },
          "uploadUrl": {
            "type": "string",
            "format": "uri",
            "description": "Short-lived URL that accepts a direct upload of the CAD source."
          },
          "sourceBucket": {
            "type": "string",
            "description": "Object-storage bucket receiving the CAD source."
          },
          "sourceS3Key": {
            "type": "string",
            "description": "Object-storage key assigned to the CAD source."
          }
        },
        "required": [
          "partId",
          "uploadUrl",
          "sourceBucket",
          "sourceS3Key"
        ]
      },
      "UpdatePartResponse": {
        "type": "object",
        "properties": {
          "jobId": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of the queued processing job."
          },
          "partId": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of the part submitted for processing."
          },
          "status": {
            "type": "string",
            "enum": [
              "queued"
            ],
            "description": "Initial state of the accepted processing job."
          }
        },
        "required": [
          "jobId",
          "partId",
          "status"
        ]
      },
      "PartResponse": {
        "type": "object",
        "properties": {
          "partId": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of this part."
          },
          "reportId": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of this immutable part result."
          },
          "jobId": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of the processing job that produced this part result."
          },
          "kernelVersion": {
            "type": "string",
            "description": "Version of the Toolpath kernel that produced this part result."
          },
          "units": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ReportUnits"
              },
              {
                "type": "object",
                "properties": {}
              }
            ],
            "description": "Units used by all dimensional values in this part response."
          },
          "regions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Region"
            },
            "description": "Recognized B-rep regions, ordered by region index."
          },
          "features": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PartFeature"
            },
            "description": "Features recognized during this processing run."
          },
          "candidateDirections": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Vec3"
            },
            "description": "Directions from which the part can be machined."
          },
          "directionZBounds": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/DirectionZBounds"
            },
            "description": "Part z extents for each candidate direction, or null when detail enrichment did not run."
          },
          "meshPointCount": {
            "type": "integer",
            "minimum": 0,
            "description": "Number of points in the generated mesh."
          },
          "meshTriangleCount": {
            "type": "integer",
            "minimum": 0,
            "description": "Number of triangles in the generated mesh."
          },
          "thumbnailUrl": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "description": "15-minute URL for the rendered PNG thumbnail, or null when absent."
          },
          "meshStlUrl": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "description": "15-minute URL for the generated STL mesh, or null when absent."
          },
          "meshGlbUrl": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "description": "15-minute URL for the generated GLB mesh, or null when absent."
          },
          "downloadMs": {
            "type": "integer",
            "minimum": 0,
            "description": "Worker time spent downloading the source CAD file, in milliseconds."
          },
          "recognitionMs": {
            "type": "integer",
            "minimum": 0,
            "description": "Kernel time spent on initial part processing, in milliseconds."
          },
          "enrichmentMs": {
            "type": "integer",
            "minimum": 0,
            "description": "Kernel time spent building per-feature details, in milliseconds."
          },
          "totalMs": {
            "type": "integer",
            "minimum": 0,
            "description": "Total worker processing time for this part, in milliseconds."
          }
        },
        "required": [
          "partId",
          "reportId",
          "jobId",
          "kernelVersion",
          "units",
          "regions",
          "features",
          "candidateDirections",
          "directionZBounds",
          "meshPointCount",
          "meshTriangleCount",
          "thumbnailUrl",
          "meshStlUrl",
          "meshGlbUrl",
          "downloadMs",
          "recognitionMs",
          "enrichmentMs",
          "totalMs"
        ]
      },
      "ReportUnits": {
        "type": "object",
        "properties": {
          "length": {
            "type": "string",
            "enum": [
              "mm"
            ],
            "description": "Unit used by every length and area measurement."
          },
          "angle": {
            "type": "string",
            "enum": [
              "deg"
            ],
            "description": "Unit used by every angular measurement."
          }
        },
        "required": [
          "length",
          "angle"
        ]
      },
      "Region": {
        "type": "object",
        "properties": {
          "idx": {
            "type": "integer",
            "minimum": 0,
            "description": "Stable region index referenced by `features[].regionIdxs`."
          },
          "splitOrigin": {
            "type": "integer",
            "minimum": 0,
            "description": "Part-local source-face group; equal values identify regions split from one B-rep face."
          },
          "shapeKind": {
            "type": "string",
            "description": "Recognized surface kind, such as Plane, Cylinder, Cone, Sphere, Torus, or Freeform."
          },
          "area": {
            "type": "number",
            "description": "Surface area of the region, in mm²."
          },
          "triangleStart": {
            "type": "integer",
            "minimum": 0,
            "description": "Inclusive start of this region’s triangle range in the returned mesh ordering."
          },
          "triangleEnd": {
            "type": "integer",
            "minimum": 0,
            "description": "Exclusive end of this region’s triangle range in the returned mesh ordering."
          }
        },
        "required": [
          "idx",
          "splitOrigin",
          "shapeKind",
          "area",
          "triangleStart",
          "triangleEnd"
        ]
      },
      "PartFeature": {
        "type": "object",
        "properties": {
          "featureId": {
            "type": "string",
            "format": "uuid",
            "description": "Globally unique identifier of this feature record within its part result."
          },
          "featureTag": {
            "type": "string",
            "description": "Stable kernel feature tag, encoded as a lowercase hexadecimal string."
          },
          "regionIdxs": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 0
            },
            "description": "Indexes of regions this feature covers; join each value to `regions[].idx`."
          },
          "featureType": {
            "type": "string",
            "description": "Kernel-recognized feature type. This vocabulary is open-ended as the kernel evolves."
          },
          "machiningDirection": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Vec3"
              },
              {
                "type": "object",
                "properties": {}
              }
            ],
            "description": "Access direction from which the kernel extracted this feature."
          },
          "axis": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Vec3"
              },
              {
                "type": [
                  "object",
                  "null"
                ],
                "properties": {}
              }
            ],
            "description": "Feature-local machining axis, such as a face normal; null for older part results."
          }
        },
        "required": [
          "featureId",
          "featureTag",
          "regionIdxs",
          "featureType",
          "machiningDirection",
          "axis"
        ]
      },
      "Vec3": {
        "type": "object",
        "properties": {
          "x": {
            "type": "number",
            "description": "X coordinate or direction component."
          },
          "y": {
            "type": "number",
            "description": "Y coordinate or direction component."
          },
          "z": {
            "type": "number",
            "description": "Z coordinate or direction component."
          }
        },
        "required": [
          "x",
          "y",
          "z"
        ]
      },
      "DirectionZBounds": {
        "type": "object",
        "properties": {
          "direction": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Vec3"
              },
              {
                "type": "object",
                "properties": {}
              }
            ],
            "description": "Candidate machining direction whose tool-axis frame defines these bounds."
          },
          "zMin": {
            "type": "number",
            "description": "Lowest part extent in this direction’s tool-axis frame, in mm."
          },
          "zMax": {
            "type": "number",
            "description": "Highest part extent in this direction’s tool-axis frame, in mm."
          }
        },
        "required": [
          "direction",
          "zMin",
          "zMax"
        ]
      },
      "UpdatePartFeaturesResponse": {
        "type": "object",
        "properties": {
          "jobId": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of the queued enrichment job."
          },
          "partId": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of the part owning the requested features."
          },
          "status": {
            "type": "string",
            "enum": [
              "queued"
            ],
            "description": "Initial state of the accepted enrichment job."
          }
        },
        "required": [
          "jobId",
          "partId",
          "status"
        ]
      },
      "UpdatePartFeaturesRequest": {
        "type": "object",
        "properties": {
          "featureIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "minItems": 1,
            "description": "Identifiers of features from one part whose detailed machining data should be generated."
          }
        },
        "required": [
          "featureIds"
        ]
      },
      "PartFeaturesResponse": {
        "type": "object",
        "properties": {
          "datasheets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PartFeatureEntry"
            },
            "description": "Detailed machining data for requested features."
          },
          "notFound": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Requested feature identifiers that were unknown."
          }
        },
        "required": [
          "datasheets",
          "notFound"
        ]
      },
      "PartFeatureEntry": {
        "type": "object",
        "properties": {
          "featureId": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of the resolved feature."
          },
          "featureTag": {
            "type": "string",
            "description": "Stable kernel feature tag, encoded as a lowercase hexadecimal string."
          },
          "featureType": {
            "type": "string",
            "description": "Kernel-recognized feature type; the vocabulary is open-ended."
          },
          "datasheet": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/FeatureDatasheet"
              },
              {
                "type": "null"
              }
            ],
            "description": "Generated machining detail, or null when this feature has no detail yet."
          }
        },
        "required": [
          "featureId",
          "featureTag",
          "featureType"
        ]
      },
      "FeatureDatasheet": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "featureType": {
            "$ref": "#/components/schemas/FeatureType",
            "description": "Kernel-recognized feature type that this datasheet measures."
          },
          "zMin": {
            "type": "number",
            "description": "Bottom of the feature along the tool axis, in mm."
          },
          "zMax": {
            "type": "number",
            "description": "Top of the feature along the tool axis, in mm."
          },
          "extendedZMin": {
            "type": "number",
            "description": "The z range extended by adjacent geometry the tool passes over reaching the\nfeature."
          },
          "extendedZMax": {
            "type": "number",
            "description": "Highest z the tool passes over while reaching the feature, in mm."
          },
          "radialStockToLeave": {
            "type": "number",
            "description": "Material intentionally left radially for a later operation, in mm."
          },
          "axialStockToLeave": {
            "type": "number",
            "description": "Material intentionally left along the tool axis for a later operation, in mm."
          },
          "toleranceBand": {
            "$ref": "#/components/schemas/ToleranceBand",
            "description": "Permitted deviation bands for the machined feature."
          },
          "hasFloor": {
            "type": "boolean",
            "description": "Whether the feature has a floor machined perpendicular to the tool axis."
          },
          "hasWall": {
            "type": "boolean",
            "description": "Whether the feature has a wall machined parallel to the tool axis."
          },
          "floorishArea": {
            "type": "number",
            "description": "Projected area machined floor-wise (perpendicular to the tool axis)."
          },
          "wallishArea": {
            "type": "number",
            "description": "Area machined wall-wise (parallel to the tool axis)."
          },
          "facts": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/HoleFacts"
              },
              {
                "$ref": "#/components/schemas/PocketFacts"
              },
              {
                "$ref": "#/components/schemas/BossFacts"
              },
              {
                "$ref": "#/components/schemas/WallFacts"
              },
              {
                "$ref": "#/components/schemas/FaceFacts"
              },
              {
                "$ref": "#/components/schemas/SurfaceFacts"
              },
              {
                "$ref": "#/components/schemas/ChamferFacts"
              },
              {
                "$ref": "#/components/schemas/ProfileFacts"
              },
              {
                "$ref": "#/components/schemas/DovetailFacts"
              },
              {
                "$ref": "#/components/schemas/TslotFacts"
              }
            ],
            "discriminator": {
              "propertyName": "kind",
              "mapping": {
                "Hole": "#/components/schemas/HoleFacts",
                "Pocket": "#/components/schemas/PocketFacts",
                "Boss": "#/components/schemas/BossFacts",
                "Wall": "#/components/schemas/WallFacts",
                "Face": "#/components/schemas/FaceFacts",
                "Three": "#/components/schemas/SurfaceFacts",
                "Chamfer": "#/components/schemas/ChamferFacts",
                "Profile": "#/components/schemas/ProfileFacts",
                "Dovetail": "#/components/schemas/DovetailFacts",
                "Tslot": "#/components/schemas/TslotFacts"
              }
            },
            "description": "The per-kind facts; narrow on `facts.kind`."
          }
        },
        "required": [
          "featureType",
          "zMin",
          "zMax",
          "extendedZMin",
          "extendedZMax",
          "radialStockToLeave",
          "axialStockToLeave",
          "toleranceBand",
          "hasFloor",
          "hasWall",
          "floorishArea",
          "wallishArea",
          "facts"
        ],
        "description": "One feature as machining sees it: static, self-contained, and enough to choose a\ntool against without having the part in hand. All lengths mm and angles degrees;\nz runs up the tool axis, so `zMin` is the bottom of the feature and `zMax` its top."
      },
      "ListJobsResponse": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JobSummary"
            },
            "description": "Jobs in this page, newest first."
          },
          "page": {
            "type": "integer",
            "minimum": 1,
            "description": "One-based page number returned."
          },
          "pageSize": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100,
            "description": "Maximum number of jobs returned in this page."
          },
          "total": {
            "type": "integer",
            "minimum": 0,
            "description": "Total number of jobs matching the query."
          }
        },
        "required": [
          "items",
          "page",
          "pageSize",
          "total"
        ]
      },
      "JobSummary": {
        "type": "object",
        "properties": {
          "partUuid": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of the part this job processes."
          },
          "jobUuid": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of this job."
          },
          "productType": {
            "type": "string",
            "description": "Product operation performed by the job, such as part processing or feature-detail processing."
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "running",
              "succeeded",
              "failed"
            ],
            "description": "Current durable state of the job."
          },
          "progress": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "maximum": 100,
            "description": "Worker-reported completion percentage, or null before progress is available."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Time at which the job was created, in ISO 8601 format."
          }
        },
        "required": [
          "partUuid",
          "jobUuid",
          "productType",
          "status",
          "progress",
          "createdAt"
        ]
      },
      "JobDetail": {
        "type": "object",
        "properties": {
          "partUuid": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of the part this job processes."
          },
          "jobUuid": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of this job."
          },
          "productType": {
            "type": "string",
            "description": "Product operation performed by the job, such as part processing or feature-detail processing."
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "running",
              "succeeded",
              "failed"
            ],
            "description": "Current durable state of the job."
          },
          "progress": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "maximum": 100,
            "description": "Worker-reported completion percentage, or null before progress is available."
          },
          "error": {
            "type": [
              "string",
              "null"
            ],
            "description": "Failure reason when the job status is failed; otherwise null."
          },
          "reportId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Identifier of the part result produced by successful processing, or null until available."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Time at which the job was created, in ISO 8601 format."
          }
        },
        "required": [
          "partUuid",
          "jobUuid",
          "productType",
          "status",
          "progress",
          "error",
          "reportId",
          "createdAt"
        ]
      },
      "BevelFacts": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "angleDeg": {
            "type": "number",
            "description": "Between the bevel's surface and the tool axis, degrees: zero for a wall, a right\nangle for a floor. A matching tool's cone half angle is this."
          },
          "slant": {
            "type": "number",
            "description": "How far the bevel runs along its own slope — the length of cutting edge a tool\nneeds to span it in one pass."
          },
          "lowerAdjacentZMin": {
            "type": "number",
            "description": "The highest bottom among the features the bevel stands on — how far down there\nis room under it before a tool would meet something. z grows up the tool axis,\nso this is *below* the bevel's own `zMin` by the room there is."
          },
          "isOpenPocketBottom": {
            "type": "boolean",
            "description": "The bevel breaks the edge along an open pocket's floor."
          },
          "countersink": {
            "$ref": "#/components/schemas/SinkFacts",
            "description": "Present only when the bevel is a countersink of revolution."
          }
        },
        "required": [
          "angleDeg",
          "slant",
          "lowerAdjacentZMin",
          "isOpenPocketBottom"
        ],
        "description": "The bevel itself: how it leans, how far it runs, and what its surroundings allow a\ncone to overshoot."
      },
      "BossFacts": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "kind": {
            "type": "string",
            "const": "Boss",
            "description": "Discriminator for this facts variant."
          },
          "cd": {
            "$ref": "#/components/schemas/CdData",
            "description": "Clearance-diameter limits for tools sweeping around the boss."
          },
          "maxBottomDiameter": {
            "type": "number",
            "description": "Largest bottom diameter a terminal tool may have, in mm."
          },
          "filletRadius": {
            "type": "number",
            "description": "Radius of the floor blend, in mm; zero when sharp."
          },
          "filletHeight": {
            "type": "number",
            "description": "Height of the floor blend, in mm; zero when sharp."
          }
        },
        "required": [
          "kind",
          "cd",
          "maxBottomDiameter",
          "filletRadius",
          "filletHeight"
        ],
        "description": "A boss: a pocket turned inside out — material with void around it."
      },
      "CdBounds": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "min": {
            "type": "number",
            "description": "Largest tool diameter that reaches every point of the feature, in mm."
          },
          "max": {
            "type": "number",
            "description": "Largest tool diameter that fits somewhere in the feature, in mm."
          }
        },
        "required": [
          "min",
          "max"
        ],
        "description": "How wide a tool a feature admits — two upper bounds, differing in how much of the\nfeature the tool has to reach. `min` is the largest tool that reaches every part of\nthe feature, `max` the largest that fits somewhere; `min <= max`. Infinities are\nmeaningful — see `CdBounds` in the `api` crate for the three sentinel states."
      },
      "CdData": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "ignore": {
            "$ref": "#/components/schemas/CdBounds",
            "description": "Clearance-diameter bounds while deviations in the ignored tolerance band are allowed."
          },
          "deviate": {
            "$ref": "#/components/schemas/CdBounds",
            "description": "Clearance-diameter bounds while deviations in the reported tolerance band are allowed."
          },
          "effectiveAdaptive": {
            "$ref": "#/components/schemas/CdBounds",
            "description": "Clearance-diameter bounds after adaptive-cutting allowances are applied."
          },
          "terminalCornerRadius": {
            "type": "number",
            "description": "The corner radius a terminal tool must not exceed; negative infinity when\nunconstrained."
          }
        },
        "required": [
          "ignore",
          "deviate",
          "effectiveAdaptive",
          "terminalCornerRadius"
        ],
        "description": "Clearance-diameter bounds per tolerance regime, plus the flags derived with them."
      },
      "ChamferFacts": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "kind": {
            "type": "string",
            "const": "Chamfer",
            "description": "Discriminator for this facts variant."
          },
          "bevel": {
            "$ref": "#/components/schemas/BevelFacts",
            "description": "Measurements for machining the chamfer with a conical tool flank."
          },
          "three": {
            "$ref": "#/components/schemas/SurfaceFacts",
            "description": "Measurements for machining the chamfer as a followable surface."
          }
        },
        "required": [
          "kind",
          "bevel",
          "three"
        ],
        "description": "A chamfer, which is two things at once and carries a measurement of each: a bevel\ncut by a cone's flank, and a surface a ball can follow. Which one a given tool\nanswers to is settled by the tool's own shape."
      },
      "DovetailFacts": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "kind": {
            "type": "string",
            "const": "Dovetail",
            "description": "Discriminator for this facts variant."
          },
          "taperDeg": {
            "type": "number",
            "description": "Between the overhanging wall and the tool axis, degrees, positive however the\nwall leans."
          },
          "filletRadius": {
            "type": "number",
            "description": "Radius of the blend between wall and floor; 0.0 for the sharp kind."
          },
          "floorWidth": {
            "type": "number",
            "description": "The widest clearance over the floor — the width the groove cuts at."
          },
          "topOpeningWidth": {
            "type": "number",
            "description": "The clearance through the opening at the top of the groove."
          },
          "bottomOpeningWidth": {
            "type": "number",
            "description": "The clearance just above the floor, under the overhangs."
          },
          "isExternal": {
            "type": "boolean",
            "description": "The groove's inner clearances vary from place to place — it runs out somewhere —\nrather than being the one constant width a closed internal dovetail has."
          },
          "cd": {
            "$ref": "#/components/schemas/CdData",
            "description": "Derived from the widths and the taper, not measured off an axis, so the three\nregimes hold one answer."
          },
          "isInvalidGeometry": {
            "type": "boolean",
            "description": "A width could not be measured at all, so `cd` is arithmetic over a zero and no\ntool should be offered on its strength."
          }
        },
        "required": [
          "kind",
          "taperDeg",
          "filletRadius",
          "floorWidth",
          "topOpeningWidth",
          "bottomOpeningWidth",
          "isExternal",
          "cd",
          "isInvalidGeometry"
        ],
        "description": "A dovetail groove: overhanging walls leaning back at one angle over a floor, so the\nspace widens with depth and a tool has to enter through an opening narrower than where\nit cuts.\n\nThat inversion is why this carries widths rather than a medial-axis measurement. All\nthree are clearance diameters read at their own heights, with `0.0` standing for a\nmeasurement that failed — which is what `isInvalidGeometry` reports."
      },
      "FaceFacts": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "kind": {
            "type": "string",
            "const": "Face",
            "description": "Discriminator for this facts variant."
          },
          "isTopFace": {
            "type": "boolean",
            "description": "The face is the highest surface of the part along the tool axis."
          },
          "isFacing": {
            "type": "boolean",
            "description": "The face is to be faced off: a top face the fixture does not rule out."
          },
          "needsSidemill": {
            "type": "boolean",
            "description": "Sweeping the floor does not clear the face on its own — a wall pass must follow."
          },
          "cd": {
            "$ref": "#/components/schemas/CdData",
            "description": "Clearance-diameter limits for tools sweeping the face."
          },
          "maxBottomDiameter": {
            "type": "number",
            "description": "Largest bottom diameter a terminal tool may have, in mm."
          }
        },
        "required": [
          "kind",
          "isTopFace",
          "isFacing",
          "needsSidemill",
          "cd",
          "maxBottomDiameter"
        ],
        "description": "A face: a plane square to the tool axis, cleared by sweeping across it."
      },
      "FeatureType": {
        "type": "string",
        "enum": [
          "ThroughHole",
          "BlindHole",
          "ThroughPocket",
          "Pocket",
          "OpenPocket",
          "Profile",
          "Boss",
          "Face",
          "Sink",
          "Chamfer",
          "Fillet",
          "ContourSurface",
          "FilletedPocket",
          "Thread",
          "FilletedOpenPocket",
          "FilletedBlindHole",
          "Wall",
          "SlantedFace",
          "InnerFillet",
          "OuterFillet",
          "SyntheticHole",
          "FilletedBoss",
          "UndercutTslot",
          "UndercutDovetail",
          "UndercutFilletedTslot",
          "BackSink",
          "BackChamfer",
          "UndercutWall",
          "USlot",
          "UndercutFilletedDovetail",
          "TaperedThroughHole",
          "ThreadedBlindHole",
          "ThreadedThroughHole"
        ],
        "description": "What kind of thing a feature is, and so how it gets machined. The names are the\ncontract at this boundary (the shared numeric wire format stays inside the binary\nAPI)."
      },
      "HoleFacts": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "kind": {
            "type": "string",
            "const": "Hole",
            "description": "Discriminator for this facts variant."
          },
          "diameter": {
            "type": "number",
            "description": "What the hole is actually drilled to — narrower than modelled for a threaded\nhole."
          },
          "fullConeDeg": {
            "type": "number",
            "description": "Full apex angle of the cone at the hole bottom, degrees; 180 for a flat bottom."
          },
          "isCounterbore": {
            "type": "boolean",
            "description": "Whether the hole includes a larger counterbore above its bore."
          },
          "holeProcess": {
            "$ref": "#/components/schemas/HoleProcess",
            "description": "The requested machining process for this hole."
          },
          "threading": {
            "$ref": "#/components/schemas/Threading",
            "description": "The thread this hole is to receive and how it is cut; absent for a plain hole."
          },
          "cd": {
            "$ref": "#/components/schemas/CdData",
            "description": "Clearance-diameter limits for tools entering the hole."
          },
          "maxSpotDiameter": {
            "type": "number",
            "description": "Largest spot-drill diameter that reaches the hole without collision, in mm."
          },
          "maxDrillDiameter": {
            "type": "number",
            "description": "Largest drill diameter that leaves the hole within its permitted oversize, in mm."
          },
          "maxEndmillDiameter": {
            "type": "number",
            "description": "Largest end-mill diameter that can machine the hole, in mm."
          },
          "filletRadius": {
            "type": "number",
            "description": "Radius of the blend at the hole bottom, in mm; zero when sharp."
          },
          "filletHeight": {
            "type": "number",
            "description": "Height of the bottom blend, in mm; zero when sharp."
          }
        },
        "required": [
          "kind",
          "diameter",
          "fullConeDeg",
          "isCounterbore",
          "holeProcess",
          "cd",
          "maxSpotDiameter",
          "maxDrillDiameter",
          "maxEndmillDiameter",
          "filletRadius",
          "filletHeight"
        ],
        "description": "A hole's facts. See `HoleFacts` in the `api` crate for what each figure means."
      },
      "HoleProcess": {
        "type": "string",
        "enum": [
          "Automatic",
          "Drill",
          "Mill"
        ],
        "description": "How the user wants a hole machined."
      },
      "PocketFacts": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "kind": {
            "type": "string",
            "const": "Pocket",
            "description": "Discriminator for this facts variant."
          },
          "cd": {
            "$ref": "#/components/schemas/CdData",
            "description": "Clearance-diameter limits for tools sweeping the pocket."
          },
          "maxBottomDiameter": {
            "type": "number",
            "description": "The bottom diameter a terminal tool must not exceed; negative infinity when\nunconstrained."
          },
          "filletRadius": {
            "type": "number",
            "description": "Radius of the floor fillet; 0.0 when unfilleted."
          },
          "filletHeight": {
            "type": "number",
            "description": "Height of the floor fillet; 0.0 when unfilleted."
          }
        },
        "required": [
          "kind",
          "cd",
          "maxBottomDiameter",
          "filletRadius",
          "filletHeight"
        ],
        "description": "A pocket: a walled space with a floor, and the blend where the two meet."
      },
      "ProfileFacts": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "kind": {
            "type": "string",
            "const": "Profile",
            "description": "Discriminator for this facts variant."
          },
          "cd": {
            "$ref": "#/components/schemas/CdData",
            "description": "Clearance-diameter limits for tools following the profile."
          },
          "length": {
            "type": "number",
            "description": "How far the pass travels, mm — the outline's own length."
          },
          "isModified": {
            "type": "boolean",
            "description": "Whether the outline is the part's silhouette or the bridged reading of it."
          }
        },
        "required": [
          "kind",
          "cd",
          "length",
          "isModified"
        ],
        "description": "A profile: one pass around the part's outline."
      },
      "SinkFacts": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "center": {
            "$ref": "#/components/schemas/Vec2",
            "description": "Where the cone's axis crosses the plane the contours are read in (the tool\nframe's) — the sink's position across the part, not along the tool."
          },
          "innerRadius": {
            "type": "number",
            "description": "Radius of the circle the bevel starts from, at its lower edge — the pilot hole."
          },
          "outerRadius": {
            "type": "number",
            "description": "Radius it has opened to at the upper edge."
          }
        },
        "required": [
          "center",
          "innerRadius",
          "outerRadius"
        ],
        "description": "A countersink read as a cone of revolution: the circle its bevel starts from and the\none it opens to."
      },
      "SurfaceFacts": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "kind": {
            "type": "string",
            "const": "Three",
            "description": "Discriminator for this facts variant."
          },
          "filletRadius": {
            "type": "number",
            "description": "The blend radius, signed by which way the surface turns: positive rolling over\nan edge, negative running into a corner, zero for no blend at all."
          },
          "maxStepdown": {
            "type": "number",
            "description": "The deepest cut taken in one pass down the surface, mm."
          },
          "surfaceFinishCuspHeight": {
            "type": "number",
            "description": "How much scallop the finishing pass may leave between neighbouring passes, mm."
          },
          "isUShapedFillet": {
            "type": "boolean",
            "description": "Whether the fillet has a U-shaped cross section."
          },
          "hasSharpCorner": {
            "type": "boolean",
            "description": "Whether the surface includes a sharp corner a tool must respect."
          },
          "useOnlyBallToolsForFinish": {
            "type": "boolean",
            "description": "Whether only ball tools are suitable for the finishing pass."
          },
          "maxBottomDiameter": {
            "type": "number",
            "description": "Largest bottom diameter a terminal tool may have, in mm."
          },
          "cd": {
            "$ref": "#/components/schemas/CdData",
            "description": "Clearance-diameter limits for tools reaching the surface."
          },
          "toolFit": {
            "$ref": "#/components/schemas/ToolFitResult",
            "description": "Geometry limits imposed by the surface shape itself."
          }
        },
        "required": [
          "kind",
          "filletRadius",
          "maxStepdown",
          "surfaceFinishCuspHeight",
          "isUShapedFillet",
          "hasSharpCorner",
          "useOnlyBallToolsForFinish",
          "maxBottomDiameter",
          "cd",
          "toolFit"
        ],
        "description": "A three-dimensional surface a tool has to follow rather than sweep; also the surface\nhalf of a chamfer."
      },
      "Threading": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "spec": {
            "$ref": "#/components/schemas/ThreadSpec",
            "description": "The dimensional definition of the thread."
          },
          "process": {
            "$ref": "#/components/schemas/ThreadProcess",
            "description": "The process used to cut the thread."
          }
        },
        "required": [
          "spec",
          "process"
        ],
        "description": "A thread a hole is to receive, and how it is to be cut."
      },
      "ThreadProcess": {
        "type": "string",
        "enum": [
          "ThreadMill",
          "CutTap",
          "FormTap"
        ],
        "description": "How a thread is to be cut: the three ways there are."
      },
      "ThreadSpec": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "basicDiameter": {
            "type": "number",
            "description": "Nominal major diameter of the thread, in mm."
          },
          "threadPitch": {
            "type": "number",
            "description": "Distance between thread crests, in mm."
          },
          "minMinorDiameter": {
            "type": "number",
            "description": "Smallest allowed minor diameter, in mm."
          },
          "maxMinorDiameter": {
            "type": "number",
            "description": "Largest allowed minor diameter, in mm."
          },
          "minMajorDiameter": {
            "type": "number",
            "description": "Smallest allowed major diameter, in mm."
          },
          "threadPercentage": {
            "type": "number",
            "description": "How much of the theoretical thread depth is to be formed, as a percentage."
          }
        },
        "required": [
          "basicDiameter",
          "threadPitch",
          "minMinorDiameter",
          "maxMinorDiameter",
          "minMajorDiameter",
          "threadPercentage"
        ],
        "description": "The thread a hole is to receive."
      },
      "ToleranceBand": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "atolIgnore": {
            "type": "number",
            "description": "Deviation at or below this value is ignored, in mm."
          },
          "atolDeviate": {
            "type": "number",
            "description": "Deviation above the ignored band but at or below this value is reported, in mm."
          },
          "atolMax": {
            "type": "number",
            "description": "Maximum allowed deviation from the model, in mm."
          }
        },
        "required": [
          "atolIgnore",
          "atolDeviate",
          "atolMax"
        ],
        "description": "How far a machined surface may deviate from the model, in three escalating bands\n(`0 <= ignore <= deviate <= max`)."
      },
      "ToolFitResult": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "cornerRadius": {
            "type": "number",
            "description": "Corner radius the surface shape admits, in mm."
          },
          "toolDiameter": {
            "type": "number",
            "description": "Largest full-diameter tool the surface shape admits, in mm."
          },
          "toolBottomDiameter": {
            "type": "number",
            "description": "Largest bottom diameter the surface shape admits, in mm."
          }
        },
        "required": [
          "cornerRadius",
          "toolDiameter",
          "toolBottomDiameter"
        ],
        "description": "The tool geometry a surface's own shape admits, before the layers are consulted."
      },
      "TslotFacts": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "kind": {
            "type": "string",
            "const": "Tslot",
            "description": "Discriminator for this facts variant."
          },
          "isExternal": {
            "type": "boolean",
            "description": "The slot runs around material standing in it rather than into the material\naround a void."
          },
          "isClosed": {
            "type": "boolean",
            "description": "The slot's walls close on themselves in plan view."
          },
          "undercutDepth": {
            "type": "number",
            "description": "How far the groove runs back from its opening, radially; infinite when the slot\ncould not be measured."
          },
          "maxEntryCd": {
            "type": "number",
            "description": "The widest tool that can come down through the opening above the slot to reach\nit; infinite when nothing above constrains one, zero when nothing fits at all."
          },
          "cd": {
            "$ref": "#/components/schemas/CdData",
            "description": "Clearance-diameter limits for tools machining inside the slot."
          },
          "filletRadius": {
            "type": "number",
            "description": "Radius of the blend where the slot's walls meet its floor and ceiling; 0.0 when\nsharp."
          }
        },
        "required": [
          "kind",
          "isExternal",
          "isClosed",
          "undercutDepth",
          "maxEntryCd",
          "cd",
          "filletRadius"
        ],
        "description": "A t-slot: a groove cut sideways into a wall or around a post, under a ceiling the\nmachining direction cannot see past."
      },
      "Vec2": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "x": {
            "type": "number",
            "description": "Horizontal x coordinate in the current frame."
          },
          "y": {
            "type": "number",
            "description": "Horizontal y coordinate in the current frame."
          }
        },
        "required": [
          "x",
          "y"
        ],
        "description": "A 2D vector (a plain `{ x, y }` object)."
      },
      "WallFacts": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "kind": {
            "type": "string",
            "const": "Wall",
            "description": "Discriminator for this facts variant."
          },
          "cd": {
            "$ref": "#/components/schemas/CdData",
            "description": "Clearance-diameter limits for tools machining the wall."
          }
        },
        "required": [
          "kind",
          "cd"
        ],
        "description": "A wall: a run of surface square to the tool axis, with no floor of its own."
      }
    },
    "parameters": {}
  },
  "paths": {
    "/health": {
      "get": {
        "operationId": "getHealth",
        "tags": [
          "Service"
        ],
        "summary": "Check Engine API health",
        "security": [],
        "responses": {
          "200": {
            "description": "The Engine API is available.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                }
              }
            }
          },
          "503": {
            "description": "The Engine API is unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/openapi.json": {
      "get": {
        "operationId": "getOpenApiDocument",
        "tags": [
          "Service"
        ],
        "summary": "Get the Engine API OpenAPI document",
        "security": [],
        "responses": {
          "200": {
            "description": "The exact OpenAPI document served by the Engine API.",
            "headers": {
              "ETag": {
                "description": "An identifier derived from the document bytes.",
                "schema": {
                  "type": "string"
                }
              },
              "Cache-Control": {
                "description": "Cache revalidation policy for the mutable v1 document URL.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenApiDocument"
                }
              }
            }
          }
        }
      }
    },
    "/v1/keys/validate": {
      "post": {
        "operationId": "validateKey",
        "tags": [
          "Keys"
        ],
        "summary": "Validate an API key",
        "description": "Reports the status of the API key supplied in the Authorization header. A usable key returns 200; a missing, revoked, expired, or unknown key returns 401 — both with the same status body (never problem+json) — so bring-your-own-key integrations can confirm a key and show why it failed.",
        "responses": {
          "200": {
            "description": "The key is active and usable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KeyValidationResponse"
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, revoked, expired, or unknown.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KeyValidationResponse"
                }
              }
            }
          },
          "503": {
            "description": "Key validation is temporarily unavailable.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/v1/parts": {
      "post": {
        "operationId": "createPart",
        "tags": [
          "Parts"
        ],
        "summary": "Create a part upload",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "example": "part.step"
            },
            "required": false,
            "name": "filename",
            "in": "query"
          }
        ],
        "responses": {
          "201": {
            "description": "The part was created and is ready for direct upload.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatePartResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The part could not be created.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Authentication is temporarily unavailable.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/v1/parts/{id}": {
      "patch": {
        "operationId": "updatePart",
        "tags": [
          "Parts"
        ],
        "summary": "Queue part processing",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "example": "0195f02c-4b4a-7b5d-9b6e-8f139d5e2820"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ],
              "default": "false",
              "example": "true",
              "description": "When true, generate detailed machining data for recognized features. Defaults to false."
            },
            "required": false,
            "description": "When true, generate detailed machining data for recognized features. Defaults to false.",
            "name": "featureDetails",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "example": "analysis-request-123"
            },
            "required": false,
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "responses": {
          "202": {
            "description": "The processing job was accepted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdatePartResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "The part does not exist.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "The part source has not been uploaded.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The processing job could not be submitted.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Authentication is temporarily unavailable.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getPart",
        "tags": [
          "Parts"
        ],
        "summary": "Get the part",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "example": "0195f02c-4b4a-7b5d-9b6e-8f139d5e2820"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "example": "0195f02c-4b4a-7b5d-9b6e-8f139d5e2820",
              "description": "Return the part result for this specific processing run instead of the latest result."
            },
            "required": false,
            "description": "Return the part result for this specific processing run instead of the latest result.",
            "name": "jobId",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "The part result for the latest or requested processing run.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "The part or its result was not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The part could not be retrieved.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Authentication is temporarily unavailable.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/v1/parts/{id}/features": {
      "patch": {
        "operationId": "updatePartFeatures",
        "tags": [
          "Features"
        ],
        "summary": "Queue processing for selected part features",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "example": "0195f02c-4b4a-7b5d-9b6e-8f139d5e2820"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdatePartFeaturesRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "The enrichment job was accepted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdatePartFeaturesResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "The part or selected features do not exist.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "The part source has not been uploaded.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The enrichment job could not be submitted.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Authentication is temporarily unavailable.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getPartFeatures",
        "tags": [
          "Features"
        ],
        "summary": "Get selected features for a part",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "example": "0195f02c-4b4a-7b5d-9b6e-8f139d5e2820"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "example": "0195f02c-4b4a-7b5d-9b6e-8f139d5e2820,0195f02c-4b4a-7b5d-9b6e-8f139d5e2821",
              "description": "Comma-separated feature ids from the part to fetch detailed machining data for."
            },
            "required": true,
            "description": "Comma-separated feature ids from the part to fetch detailed machining data for.",
            "name": "ids",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Detailed machining data for resolved features, plus any ids that were not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartFeaturesResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "The part does not exist.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The part features could not be retrieved.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Authentication is temporarily unavailable.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/v1/jobs": {
      "get": {
        "operationId": "listJobs",
        "tags": [
          "Jobs"
        ],
        "summary": "List jobs",
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1,
              "example": 1
            },
            "required": false,
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 20,
              "example": 20,
              "description": "Requested page size. Values above 100 are capped at 100."
            },
            "required": false,
            "description": "Requested page size. Values above 100 are capped at 100.",
            "name": "pageSize",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "example": "0195f02c-4b4a-7b5d-9b6e-8f139d5e2820",
              "description": "Return only jobs for this part."
            },
            "required": false,
            "description": "Return only jobs for this part.",
            "name": "partId",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "queued",
                "running",
                "succeeded",
                "failed"
              ],
              "example": "succeeded",
              "description": "Return only jobs in this state."
            },
            "required": false,
            "description": "Return only jobs in this state.",
            "name": "status",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of jobs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListJobsResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The jobs could not be listed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Authentication is temporarily unavailable.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/v1/jobs/{id}": {
      "get": {
        "operationId": "getJob",
        "tags": [
          "Jobs"
        ],
        "summary": "Get a job",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "example": "0195f02c-4b4a-7b5d-9b6e-8f139d5e2820"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "The job to get.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobDetail"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "The job was not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The job could not be retrieved.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Authentication is temporarily unavailable.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/v1/jobs/{id}/events": {
      "get": {
        "operationId": "streamJobEvents",
        "tags": [
          "Jobs"
        ],
        "summary": "Stream job updates",
        "description": "Sends the current job immediately, then sends every subsequent persisted status, progress, or error change as a `job` server-sent event while the connection remains open. If the connection closes, reconnect to receive the latest job snapshot before continuing with future updates.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "example": "0195f02c-4b4a-7b5d-9b6e-8f139d5e2820"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "A stream of job snapshots.",
            "content": {
              "text/event-stream": {
                "schema": {
                  "type": "string",
                  "description": "Each `job` event has a JSON `data` field matching JobDetail.",
                  "example": "event: job\ndata: {\"partUuid\":\"0195f02c-4b4a-7b5d-9b6e-8f139d5e2820\",\"jobUuid\":\"0195f02c-4b4a-7b5d-9b6e-8f139d5e2821\",\"productType\":\"analyze-part\",\"status\":\"running\",\"progress\":null,\"error\":null,\"reportId\":null,\"createdAt\":\"2026-08-05T12:00:00.000Z\"}\n\n"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "The job was not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The job event stream could not be opened.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Authentication is temporarily unavailable.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    }
  },
  "webhooks": {}
}
