SmartCut API V3 Openapi API

Cutting optimisation for sheet, linear and roll stock.

Operations 17

POST /v3/calculate Submit calculation
POST /v3/validate Validate inputs without calculating
POST /v3/model/analysis Analyse a 3D model into parts
GET /v3/result/ready Check if calculation is complete
GET /v3/result Retrieve calculation result
GET /v3/export/pdf Export result as PDF
GET /v3/export/csv Export result as CSV
GET /v3/export/ptx Export result as PTX
GET /v3/export/dxf Export result as DXF
GET /v3/export/svg Export result as SVG
GET /v3/export/mayer Export result as Mayer .may
GET /v3/export/biesse Export result as Biesse XML CutList
GET /v3/export/cadmatic Export result as a Homag CADmatic .saw file
GET /v3/saws List saws and the export formats each offers
POST /v3/labels Generate printable part labels
POST /webhooks/result Calculation result delivery
GET /v3/calls Get API usage statistics

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/smartcut-dev:smartcut-api-v3-openapi-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

smartcut-dev-openapi-openapi.json Raw ↑
{
  "openapi": "3.0.3",
  "info": {
    "termsOfService": "https://smartcut.dev/terms",
    "license": {
      "name": "MIT (specification document only — API use governed by the Terms)",
      "url": "https://github.com/jgmedialtd/smartcut-api/blob/main/LICENSE"
    },
    "x-logo": {
      "url": "https://smartcut.dev/images/logo.svg",
      "altText": "SmartCut"
    },
    "title": "SmartCut API V3",
    "version": "3.1.0",
    "description": "Cutting optimisation for sheet, linear and roll stock.\n\nSend a list of parts and the stock you have; get back an optimised cutting layout. Supports guillotine cutting for panel saws and true-shape nesting for CNC, honouring grain direction, edge banding, blade kerf and per-edge trim. Results export to PDF, CSV, DXF, SVG and saw formats including PTX, Biesse XML and Mayer.\n\nCalculations are asynchronous: submit to `/v3/calculate`, then poll `/v3/result/ready` and collect from `/v3/result`. Authentication is your API key in the `Authorization` header, with **no `Bearer` prefix**.\n\n**Beta surfaces:**\n- `parts[].labels` + top-level `labels.customer` — typed saw label-printer fields. Emitted by PTX (named PARTS_INF columns) and Mayer .MAY (part-level fields → MA010 text slots); Biesse XML to follow. `labels.customer` is PTX-only. Schema may change; see `/v3/export/ptx` and `/v3/export/mayer`.",
    "contact": {
      "name": "SmartCut",
      "url": "https://api.smartcut.dev"
    }
  },
  "externalDocs": {
    "description": "Specification, runnable examples and MCP configuration",
    "url": "https://github.com/jgmedialtd/smartcut-api"
  },
  "paths": {
    "/v3/calculate": {
      "post": {
        "tags": [
          "Calculations"
        ],
        "summary": "Submit calculation",
        "description": "Submit a calculation request using V3 format.\n\nThe response contains a job ID. Results are delivered to your webhook when the job completes — the recommended path, see [Result webhooks](https://smartcut.dev/docs/webhooks). Polling `/v3/result/ready` is the fallback.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CalculateRequest"
              },
              "examples": {
                "guillotine": {
                  "summary": "Guillotine (sheet cutting)",
                  "description": "Two-dimensional sheet cutting with nested rectangular cuts",
                  "value": {
                    "saw": {
                      "cutType": "guillotine",
                      "cutPreference": "l",
                      "bladeWidth": 3,
                      "stockType": "sheet"
                    },
                    "stock": [
                      {
                        "l": 2400,
                        "w": 1200,
                        "t": 18,
                        "material": "Plywood",
                        "trim": {
                          "l1": 0,
                          "l2": 0,
                          "w1": 0,
                          "w2": 0
                        },
                        "grain": "l",
                        "autoAdd": false
                      }
                    ],
                    "parts": [
                      {
                        "l": 400,
                        "w": 300,
                        "t": 18,
                        "material": "Plywood",
                        "q": 5,
                        "extras": {
                          "banding": {
                            "sides": {
                              "l1": "Oak",
                              "l2": true
                            }
                          },
                          "finish": {
                            "faces": {
                              "a": "Gloss"
                            }
                          }
                        }
                      }
                    ]
                  }
                },
                "efficiency": {
                  "summary": "Efficiency (sheet optimization)",
                  "description": "Optimized sheet cutting with automatic stock selection",
                  "value": {
                    "saw": {
                      "cutType": "efficiency",
                      "cutPreference": "l",
                      "bladeWidth": 3,
                      "stockType": "sheet"
                    },
                    "stock": [
                      {
                        "l": 2440,
                        "w": 1220,
                        "t": 18,
                        "material": "MDF",
                        "q": 10,
                        "autoAdd": true,
                        "cost": 45.5
                      }
                    ],
                    "parts": [
                      {
                        "l": 800,
                        "w": 600,
                        "t": 18,
                        "material": "MDF",
                        "q": 12,
                        "grain": "l",
                        "orientationLock": ""
                      },
                      {
                        "l": 400,
                        "w": 300,
                        "t": 18,
                        "material": "MDF",
                        "q": 8,
                        "grain": "",
                        "extras": {
                          "banding": {
                            "sides": {
                              "l1": "White",
                              "l2": "White",
                              "w1": "White",
                              "w2": "White"
                            }
                          }
                        }
                      }
                    ]
                  }
                },
                "linear": {
                  "summary": "Linear (bar cutting)",
                  "description": "One-dimensional cutting for bars, tube, or trim. Linear stock is cut to length, so `cutType` and `cutPreference` are omitted — the optimiser selects the linear calculation from `stockType` alone.",
                  "value": {
                    "saw": {
                      "bladeWidth": 3,
                      "stockType": "linear"
                    },
                    "stock": [
                      {
                        "l": 3000,
                        "w": 100,
                        "t": 50,
                        "material": "Pine",
                        "q": 5,
                        "autoAdd": true,
                        "cost": 12.5
                      }
                    ],
                    "parts": [
                      {
                        "l": 1200,
                        "w": 100,
                        "t": 50,
                        "material": "Pine",
                        "q": 3
                      },
                      {
                        "l": 800,
                        "w": 100,
                        "t": 50,
                        "material": "Pine",
                        "q": 5
                      },
                      {
                        "l": 450,
                        "w": 100,
                        "t": 50,
                        "material": "Pine",
                        "q": 10
                      }
                    ]
                  }
                },
                "withLabels": {
                  "summary": "Beam saw with label-printer fields (BETA)",
                  "description": "Same as guillotine, but populates the beta `labels` surface so the PTX export drives the saw's on-board label printer / barcode machine. Unsupported fields for the chosen saw return as `labelWarnings`; the job still runs.",
                  "value": {
                    "saw": {
                      "cutType": "beam",
                      "cutPreference": "l",
                      "bladeWidth": 4.8,
                      "stockType": "sheet",
                      "vendor": "Homag",
                      "model": "homag-ptx"
                    },
                    "stock": [
                      {
                        "l": 2440,
                        "w": 1220,
                        "t": 18,
                        "material": "MDF",
                        "q": 10,
                        "autoAdd": true
                      }
                    ],
                    "parts": [
                      {
                        "name": "Side Panel",
                        "l": 600,
                        "w": 400,
                        "t": 18,
                        "material": "MDF",
                        "q": 5,
                        "code": "ART-1234",
                        "labels": {
                          "barcode1": "CNC-SIDE-A",
                          "barcode2": "CNC-SIDE-B",
                          "room": "Kitchen",
                          "order": "PO-2024-042",
                          "pallet": "PAL-7",
                          "colour": "Walnut"
                        }
                      }
                    ],
                    "labels": {
                      "customer": "Acme Joinery"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Calculation accepted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "jobId": {
                      "type": "number",
                      "description": "Job identifier. Identifies the job in the webhook delivery (the recommended way to receive results), or when polling `/v3/result/ready`."
                    },
                    "warnings": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Saw settings the saw-rules registry resolved differently from what was sent — the job runs; the caller is told. Each entry names the rule that fired, e.g. `[strategy.time-ignored-for-beam] …`; on a mixed job it is prefixed `Saw '<id>': `. Present only when at least one rule rewrote something. Every rule is listed at https://smartcut.dev/api-docs/saw-settings",
                      "example": [
                        "[strategy.time-ignored-for-beam] guillotineOptions.strategy 'time' is the fence-consistency knob for a manual table saw; a beam saw positions the fence per cut, so it is ignored — set to 'efficiency'."
                      ]
                    },
                    "labelWarnings": {
                      "type": "array",
                      "description": "**BETA** — Non-fatal warnings: label fields the request set that the chosen saw's post-processor format(s) will not surface. The job still runs; the unsupported fields are dropped at emit time. Shape may change before the `labels` surface stabilises.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "category": {
                            "type": "string",
                            "enum": [
                              "label"
                            ]
                          },
                          "field": {
                            "type": "string",
                            "description": "Name of the label field that was unsupported."
                          },
                          "partIndex": {
                            "type": "integer",
                            "nullable": true,
                            "description": "Index in parts[] for part-level fields; null for job-level (top-level labels.customer)."
                          },
                          "partId": {
                            "type": "string",
                            "description": "Part id when available."
                          },
                          "supportedFormats": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Formats that DO surface this field. Migrate the saw choice if a value is required."
                          },
                          "sawFormats": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Formats the chosen saw actually supports."
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  },
                  "required": [
                    "jobId"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid V3 format - see error details for migration help",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Not authorized"
          },
          "429": {
            "description": "Rate limit exceeded, or too many concurrent jobs — wait before retrying"
          },
          "500": {
            "description": "Server error"
          },
          "503": {
            "description": "Service unavailable"
          }
        }
      }
    },
    "/v3/validate": {
      "post": {
        "tags": [
          "Calculations"
        ],
        "summary": "Validate inputs without calculating",
        "description": "Run the same input validation and stock-matching a calculation would, but return the\nissues immediately — no job is created, nothing is persisted, no usage is counted.\nUse it for instant pre-submit feedback (e.g. \"will not fit on any relevant stock\",\n\"no matching stock material found\", or being over a plan limit).\n\nThe request body is identical to `/v3/calculate`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CalculateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Validation result. `valid` is true only when there are no issues.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "valid": {
                      "type": "boolean",
                      "description": "True when the inputs produced no issues."
                    },
                    "stage": {
                      "type": "string",
                      "enum": [
                        "input",
                        "match"
                      ],
                      "description": "`input` = failed the basic validation pipeline (missing dimensions, plan limits); `match` = structurally valid, the issues are stock-fit reasons from the matcher."
                    },
                    "issues": {
                      "type": "array",
                      "description": "Validation issues. At stage `match`, each issue points at the offending part via `index`/`field`.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "message": {
                            "type": "string",
                            "description": "The reason — an i18n key (e.g. `errors.validation.will_not_fit`) or a message."
                          },
                          "type": {
                            "type": "string",
                            "enum": [
                              "error",
                              "warning"
                            ]
                          },
                          "category": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "field": {
                            "type": "array",
                            "items": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "description": "Field paths the issue points at, e.g. [[\"material\"],[\"t\"]]."
                          },
                          "index": {
                            "type": "array",
                            "items": {
                              "type": "integer"
                            },
                            "description": "0-based indices of the affected parts."
                          },
                          "identifier": {
                            "type": "string",
                            "description": "Human-readable source (part name or 1-based row)."
                          }
                        }
                      }
                    },
                    "warnings": {
                      "type": "array",
                      "description": "Saw settings the saw-rules registry resolved differently from what was sent — the job runs; the caller is told. Each `message` names the rule that fired, e.g. `[min-spacing.efficiency-only] …`; on a mixed job it is prefixed `Saw '<id>': `. Present only when at least one rule rewrote something, and never affects `valid`. Every rule is listed at https://smartcut.dev/api-docs/saw-settings",
                      "items": {
                        "type": "object",
                        "properties": {
                          "message": {
                            "type": "string",
                            "description": "What was resolved and why, prefixed with the rule id in square brackets."
                          },
                          "type": {
                            "type": "string",
                            "enum": [
                              "warning"
                            ]
                          }
                        },
                        "required": [
                          "message",
                          "type"
                        ]
                      }
                    }
                  },
                  "required": [
                    "valid",
                    "issues"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid V3 format - see error details for migration help",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - wait before retry"
          },
          "500": {
            "description": "Server error"
          }
        }
      }
    },
    "/v3/model/analysis": {
      "post": {
        "tags": [
          "Calculations"
        ],
        "summary": "Analyse a 3D model into parts",
        "description": "Upload a 3D model and get back a parts list. The `parts` array is `/v3/calculate`'s\n`parts` array — same field names, same units — so you can submit it verbatim.\n\n**The body is the file itself**, not a multipart form: POST the raw bytes with\n`Content-Type: application/octet-stream`. Everything else is a query parameter.\n\n**Formats.** `step` (best — exact solids and a real declared unit), `stl`, `obj`,\n`ply` and `gltf`/`glb` are read server-side. Collada (`dae`) and `3mf` are **not**:\nboth need a browser DOM to parse, so they return `415` with advice to convert. Format\nis detected from the file's magic bytes; OBJ and ASCII STL carry none, so send\n`filename` or `format` for those or the request is refused rather than guessed at.\n\n**Units.** Only STEP, 3MF and Collada declare a unit. For everything else, say what\nthe model was drawn in with `sourceUnits`, or the numbers are taken to be already in\n`units`. Getting this wrong is silent — every part stays consistent with every other\n— so it is worth being explicit.\n\n**What is in `advice`.** Everything the analysis knows that a calculation does not:\nwhether a part is a rectangle or a shape, what squaring it off would waste, why\nsomething was judged a fitting rather than sheet goods, which two parts share space\nin the assembly. Entries point back at `parts` by index.\n\n**Cost.** Billed on the same compute-time meter as a calculation, and counted against\nyour monthly call allowance. A refused format or an over-size model costs nothing.\nMaximum upload 32MB; models above 2,000,000 triangles are refused — decimate first.",
        "parameters": [
          {
            "name": "filename",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "The file's name, e.g. `kitchen.step`. Used as a tiebreak when the bytes carry no magic — required for OBJ and ASCII STL unless `format` is sent."
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "step",
                "stl",
                "obj",
                "ply",
                "gltf",
                "glb"
              ]
            },
            "description": "Force the format instead of inferring it from `filename`. Magic bytes still win where the file has them."
          },
          {
            "name": "units",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "mm",
                "cm",
                "m",
                "in",
                "ft"
              ],
              "default": "mm"
            },
            "description": "The unit every number in the response is in."
          },
          {
            "name": "sourceUnits",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "mm",
                "cm",
                "m",
                "in",
                "ft"
              ]
            },
            "description": "The unit the model was drawn in. Overrides whatever the file declares. Defaults to the file's own declaration, then to `units`."
          },
          {
            "name": "dedupe",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": true
            },
            "description": "Collapse identical parts into one row with a quantity — what a cut list wants."
          },
          {
            "name": "mirrorDedupe",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "Treat a part and its mirror image as the same part. Off by default: a mirrored panel is genuinely different once the sheet has a face, a grain direction or machining on one side."
          },
          {
            "name": "bladeWidth",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "Your saw's kerf, in `units`. Supply it and the response can tell you when the model is too small to be measured in the unit you chose (`model.suggestedUnits`). Without it no unit suggestion is made."
          },
          {
            "name": "holes",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "drill",
                "cut"
              ],
              "default": "drill"
            },
            "description": "Which form a ROUND hole comes back in. `drill` (default) returns it as a `machining.holes` operation — a drilled shelf stays a plain rectangle. `cut` returns it as a polygon ring in `holes`, which is the only form a nesting model reads. Holes that are not round are shape either way; there is no drilled equivalent of a slot."
          }
        ],
        "requestBody": {
          "required": true,
          "description": "The model file, as raw bytes.",
          "content": {
            "application/octet-stream": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The model was analysed. `parts` is submittable to `/v3/calculate` as-is.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModelAnalysisResponse"
                }
              }
            }
          },
          "400": {
            "description": "The body is not a file, the format could not be determined, or the units are not ones we convert.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Over the monthly call limit, or the account is on hold"
          },
          "413": {
            "description": "Body larger than 32MB"
          },
          "415": {
            "description": "A format this server cannot read (Collada and 3MF need a browser). `details.supported` lists the formats that do work.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Too many triangles, or the analysis did not finish inside its budget. Decimate the mesh and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - wait before retry"
          },
          "500": {
            "description": "Server error"
          }
        }
      }
    },
    "/v3/result/ready": {
      "get": {
        "tags": [
          "Results"
        ],
        "summary": "Check if calculation is complete",
        "description": "**Webhooks are the recommended way to receive results** — SmartCut posts the finished result to your URL as soon as the job completes, so there is nothing to poll and no delay. See [Result webhooks](https://smartcut.dev/docs/webhooks) to set one up.\n\nUse this endpoint as a fallback when your client cannot receive inbound HTTP. Poll every 2-3 seconds, stop on `200` (then fetch `/v3/result`) or on `404`/`410`, and back off on `429`.",
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Job identifier from /v3/calculate"
          }
        ],
        "responses": {
          "200": {
            "description": "Result is ready - fetch via /v3/result"
          },
          "404": {
            "description": "Job not found or not ready yet"
          },
          "410": {
            "description": "Job expired or failed"
          },
          "429": {
            "description": "Rate limit exceeded - wait before retry"
          }
        }
      }
    },
    "/v3/result": {
      "get": {
        "tags": [
          "Results"
        ],
        "summary": "Retrieve calculation result",
        "description": "Fetch the complete optimization result in V3 format.\n\nIf you use a webhook (recommended), this exact payload is delivered to your URL and you do not need to call this endpoint at all.\n\n**V3 Response Format:**\n- All fields use l1/l2/w1/w2 coordinates\n- Extras in structured format (extras.banding.sides, etc.)\n- Complete metadata with all analysis fields\n- Stock, parts, cuts, segments, offcuts all included",
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Job identifier"
          }
        ],
        "responses": {
          "200": {
            "description": "Result retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResultResponse"
                }
              }
            }
          },
          "404": {
            "description": "Result not found"
          },
          "410": {
            "description": "Result expired"
          },
          "500": {
            "description": "Server error"
          }
        }
      }
    },
    "/v3/export/pdf": {
      "get": {
        "tags": [
          "Exports"
        ],
        "summary": "Export result as PDF",
        "description": "Generate a PDF file with optimization layouts, cut lists, and part details. V3 format always uses CSV version 2.",
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Job ID to export"
          },
          {
            "name": "option",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "layout",
                "parts",
                "machining"
              ]
            },
            "description": "Export variant: layout (default, full optimization), parts (parts list only), machining (machining details)"
          },
          {
            "name": "numberFormat",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "decimal",
                "fraction"
              ]
            },
            "description": "Number format (also accepts unitType or units as aliases). Default: decimal"
          },
          {
            "name": "credit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Custom credit text (requires whiteLabel plan option)"
          },
          {
            "name": "cropLength",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "y",
                "n"
              ]
            },
            "description": "Crop stock length to fit parts. Default: n"
          },
          {
            "name": "tables",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "y",
                "n"
              ]
            },
            "description": "Show tables in output. Default: y"
          },
          {
            "name": "showDiagram",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
              

# --- truncated at 32 KB (167 KB total) ---
# Full source: https://artifacts.apis.io/smartcut-dev/openapi/_original/smartcut-dev-openapi-openapi.json