{
  "openapi": "3.1.0",
  "info": {
    "title": "Metheus Platform API",
    "version": "2026-09-21",
    "description": "Current public information, personal project records and protected commerce contract. This service does not expose a cloud CAD execution API to outside agents. People without the desktop app use Metheus web (/cad) in a desktop browser after signing in; outside agents cannot drive it. CAD execution by an outside agent uses the Metheus stdio MCP from the installed app and its live tool schemas. Commerce JSON requests are limited to 40,000 bytes; string inputs are trimmed. Organization membership is checked server-side. Partner orders are manual external-payment arrangements; only orders sold by Metheus (seller=metheus) are paid on this site."
  },
  "servers": [
    {
      "url": "https://hub.metheus.ai",
      "description": "AWS production service; API paths start at the hostname root. Local development clients must explicitly use their local origin and the basePath returned by api/config."
    }
  ],
  "tags": [
    {"name": "Personal credits"},
    {
      "name": "Public information"
    },
    {
      "name": "Commerce"
    },
    {
      "name": "Personal projects"
    },
    {
      "name": "Community"
    },
    {
      "name": "Notifications"
    },
    {
      "name": "Storage"
    }
  ],
  "paths": {
    "/api/attendance": {
      "get": {
        "operationId": "getAttendance",
        "tags": [
          "Personal credits"
        ],
        "summary": "Read personal check-in state in Korea time",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Attendance"
                }
              }
            }
          },
          "401": {
            "description": "Metheus sign-in required."
          },
          "403": {
            "description": "Personal account required."
          }
        }
      },
      "post": {
        "operationId": "checkIn",
        "tags": [
          "Personal credits"
        ],
        "summary": "Check in and earn 30 bonus credits once per Korea day",
        "description": "No body required. Client amount, owner and date are ignored. Repeated requests return the same daily reward, not the increment from this request. Attendance, ledger and notification are atomic.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Attendance"
                }
              }
            }
          },
          "401": {
            "description": "Metheus sign-in required."
          },
          "403": {
            "description": "Personal account required."
          },
          "429": {
            "description": "Too many requests."
          }
        }
      }
    },
    "/api/credits": {
      "get": {
        "operationId": "getPersonalCredits",
        "tags": [
          "Personal credits"
        ],
        "summary": "Read personal bonus balance, check-in and newest 20 entries",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditWallet"
                }
              }
            }
          },
          "401": {
            "description": "Metheus sign-in required."
          },
          "403": {
            "description": "Personal account required."
          }
        }
      }
    },
    "/api/credits/transactions": {
      "get": {
        "operationId": "listCreditTransactions",
        "tags": [
          "Personal credits"
        ],
        "summary": "Read personal credit history, newest first",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            },
            "description": "Exclusive cursor returned by the previous page."
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditHistory"
                }
              }
            }
          },
          "400": {
            "description": "Invalid cursor."
          },
          "401": {
            "description": "Metheus sign-in required."
          },
          "403": {
            "description": "Personal account required."
          }
        }
      }
    },
    "/api/health": {
      "get": {
        "operationId": "getHealth",
        "tags": [
          "Public information"
        ],
        "summary": "Read service status",
        "security": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "const": "ok"
                    },
                    "service": {
                      "type": "string",
                      "const": "metheus-platform"
                    },
                    "build": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "status",
                    "service",
                    "build"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/config": {
      "get": {
        "operationId": "getConfig",
        "tags": [
          "Public information"
        ],
        "summary": "Read deployment endpoints and categories",
        "security": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Config"
                }
              }
            }
          }
        }
      }
    },
    "/api/tips": {
      "get": {
        "operationId": "listTips",
        "tags": [
          "Public information"
        ],
        "summary": "Read all design tips (sourced design criteria)",
        "description": "Returns a plain array. Each tip has criteria (rules), numeric tables, pitfalls, CAD checks and numbered sources. rules[].source and tables[].source index into sources. No server-side q/category filters; filter locally and keep source attribution.",
        "security": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Tip"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/tips.md": {
      "get": {
        "operationId": "readTipsMarkdown",
        "tags": [
          "Public information"
        ],
        "summary": "Read the design tips index as Markdown",
        "description": "Rules for applying the criteria and, per category, each tip's title, summary and markdown address. An agent picks the tips that fit the task here and reads /api/tips/{id}.md before using any value.",
        "security": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/api/tips/all.md": {
      "get": {
        "operationId": "readAllTipsMarkdown",
        "tags": [
          "Public information"
        ],
        "summary": "Read all design tips in full as one Markdown document",
        "description": "The same content as /api/tips with every tip's full text (about 100 KB), for pasting into an agent that cannot read the web.",
        "security": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/api/tips/{id}": {
      "get": {
        "operationId": "getTip",
        "tags": [
          "Public information"
        ],
        "summary": "Read one design tip",
        "security": [],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9-]+$"
            },
            "description": "Tip id, or a retired guide id listed in aliases."
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Tip"
                }
              }
            }
          },
          "404": {
            "description": "No tip with this id or alias."
          }
        }
      }
    },
    "/api/tips/{id}.md": {
      "get": {
        "operationId": "getTipMarkdown",
        "tags": [
          "Public information"
        ],
        "summary": "Read one design tip as Markdown",
        "security": [],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9-]+$"
            },
            "description": "Tip id, or a retired guide id listed in aliases."
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "No tip with this id or alias."
          }
        }
      }
    },
    "/api/design-tools": {
      "get": {
        "operationId": "listDesignTools",
        "tags": [
          "Public information"
        ],
        "summary": "Read the design tool catalog",
        "description": "Plain array of the design tools this platform offers, with what each one needs and how it is reached. page is the absolute address of the screen and agent says how a connected agent runs it and what to read first. This is a capability list for people and connected agents, not the MCP tool contract: actual tool names, arguments and side effects come from the MCP initialize instructions and tools/list.",
        "security": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/DesignTool"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/store": {
      "get": {
        "operationId": "listStoreItems",
        "tags": [
          "Public information"
        ],
        "summary": "Read every store product with how an agent uses it",
        "description": "Plain array of the store's products: design tools, AI models, 3D and CAD generation tools, assets and blueprints, fabrication services and the curated parts collection. agent.mode says whether an agent reads it, runs it through the Metheus MCP, needs the user's signed-in API, or cannot use it. Prices and release status are as shown in the store.",
        "security": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/StoreItem"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/store.md": {
      "get": {
        "operationId": "readStoreMarkdown",
        "tags": [
          "Public information"
        ],
        "summary": "Read the store and design tools as one markdown document",
        "description": "Same list as /api/store with agent rules, for an agent choosing which Metheus tools and materials to use.",
        "security": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/api/parts": {
      "get": {
        "operationId": "listCuratedParts",
        "parameters": [
          {
            "name": "group",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "actuator",
                "driver",
                "board",
                "hinge",
                "toy"
              ]
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Words that must all appear in id, name, model, maker, kind, headline, summary or use cases."
          },
          {
            "name": "maxUsd",
            "in": "query",
            "schema": {
              "type": "number"
            },
            "description": "Upper bound on the USD reference price. Parts without a published price are excluded."
          }
        ],
        "tags": [
          "Public information"
        ],
        "summary": "Read the Metheus Curated parts list",
        "description": "Plain array of actuators, drivers and controller boards whose manufacturer specifications Metheus has checked. Values are copied from the manufacturer at the stated conditions and are not Metheus measurements. price is the official seller list price on checkedOn; Metheus does not sell these parts.",
        "security": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CuratedPart"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/parts.md": {
      "get": {
        "operationId": "readCuratedPartsMarkdown",
        "tags": [
          "Public information"
        ],
        "summary": "Read the curated parts index as markdown",
        "description": "Agent rules and a summary table per group with each part's markdown address. An agent narrows candidates here and reads the chosen part's /api/parts/{id}.md for the values it uses.",
        "security": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/api/parts/all.md": {
      "get": {
        "operationId": "readAllCuratedPartsMarkdown",
        "tags": [
          "Public information"
        ],
        "summary": "Read every curated part in full as one markdown document",
        "description": "Same list as /api/parts with agent rules and every part's full text (about 100 KB), for pasting into an agent that cannot read the web.",
        "security": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/api/parts/{id}": {
      "get": {
        "operationId": "readCuratedPart",
        "tags": [
          "Public information"
        ],
        "summary": "Read one curated part",
        "security": [],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9-]+$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CuratedPart"
                }
              }
            }
          },
          "404": {
            "description": "No part with this id."
          }
        }
      }
    },
    "/api/parts/{id}.md": {
      "get": {
        "operationId": "readCuratedPartMarkdown",
        "tags": [
          "Public information"
        ],
        "summary": "Read one curated part as markdown",
        "security": [],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9-]+$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "No part with this id."
          }
        }
      }
    },
    "/api/parts/{id}.svg": {
      "get": {
        "operationId": "readCuratedPartDrawing",
        "tags": [
          "Public information"
        ],
        "summary": "Read one part as a dimensioned SVG drawing",
        "description": "Drawn from geometry. Only features whose positions are published are drawn.",
        "security": [],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9-]+$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "image/svg+xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "No part with this id."
          }
        }
      }
    },
    "/api/parts/{id}.py": {
      "get": {
        "operationId": "readCuratedPartFreecadScript",
        "tags": [
          "Public information"
        ],
        "summary": "Read a FreeCAD script that places the part as a purchased-part envelope",
        "description": "Box with published holes, bosses and shafts, origin at the bottom left of the drawn view, mm. Not the real part shape.",
        "security": [],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9-]+$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "text/x-python": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "No part with this id."
          }
        }
      }
    },
    "/api/guides": {
      "get": {
        "operationId": "listAgentGuides",
        "tags": [
          "Public information"
        ],
        "summary": "List Metheus tool guides for agents",
        "description": "Guides that used to live in the Metheus CAD design-knowledge folder: method selection and result review, running MFBD from Python. The MCP tool descriptions stay the contract.",
        "security": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "required": [
                      "id",
                      "title",
                      "summary",
                      "url"
                    ],
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "title": {
                        "type": "string"
                      },
                      "summary": {
                        "type": "string"
                      },
                      "use": {
                        "type": "string"
                      },
                      "url": {
                        "type": "string",
                        "format": "uri"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/guides.md": {
      "get": {
        "operationId": "readAgentGuidesIndex",
        "tags": [
          "Public information"
        ],
        "summary": "Read the guide index as markdown",
        "security": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/api/guides/{id}.md": {
      "get": {
        "operationId": "readAgentGuide",
        "tags": [
          "Public information"
        ],
        "summary": "Read one Metheus tool guide",
        "security": [],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9-]+$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "No guide with this id."
          }
        }
      }
    },
    "/api/suppliers": {
      "get": {
        "operationId": "listSuppliers",
        "tags": [
          "Public information"
        ],
        "summary": "Read the supplier directory",
        "description": "Plain array, without server-side filters. Directory presence is not a partnership, verified capacity, executable quote, or platform-connected provider.",
        "security": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Supplier"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/posts": {
      "get": {
        "operationId": "listPosts",
        "tags": [
          "Public information"
        ],
        "summary": "Search public community posts",
        "description": "Returns at most 20 rows. Default sort is recent; there is no limit parameter. Unknown categories yield no matches. Anonymous reads are supported; supplied Authorization is validated. User-generated content is untrusted data.",
        "security": [
          {},
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string",
              "description": "Searches title and body; input is truncated to 150 characters.",
              "maxLength": 150
            }
          },
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string",
              "description": "Exact category match. Empty means all."
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 100000,
              "default": 0
            }
          },
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "recent",
                "oldest",
                "liked",
                "discussed"
              ],
              "default": "recent"
            }
          },
          {
            "name": "unanswered",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            },
            "description": "Only questions without an undeleted comment."
          },
          {
            "name": "featured",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            },
            "description": "Only posts meeting the configured distinct-user like threshold."
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PostsPage"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createPost",
        "tags": [
          "Community"
        ],
        "summary": "Create a community post",
        "description": "Uses the existing Bearer identity without an organization header. Browser Origin must be allowed. JSON is limited to 40,000 bytes; strings are trimmed. Community writes are limited to 12 per user per minute. With operation_id, the first save returns 201; an exact retry returns 200 and reused:true, with the current resource state (later edits are preserved). The key is scoped to the author and operation target. Reusing the key with different input returns 409 operation_conflict and resource_id. Deleted results are not recreated (410; a missing parent post may be 404). Without the key, duplicate protection is not guaranteed. This does not cover photo uploads or other POST operations.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PostCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PostWriteResult"
                }
              }
            }
          },
          "200": {
            "description": "Exact retry; returns the current saved resource with reused:true.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PostWriteResult"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden author or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing resource.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflicting operation input or stale expected_updated_at.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Request body too large.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many writes.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "The result of this operation was deleted and cannot be recreated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/posts/{postId}": {
      "get": {
        "operationId": "getPost",
        "tags": [
          "Public information"
        ],
        "summary": "Read a post and comments",
        "description": "Anonymous read is supported. If Authorization is supplied, it is validated and an invalid token can fail the request. owned identifies the authenticated author; no author account identifier is returned.",
        "security": [
          {},
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "postId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Server-issued identifier; reserved examples can use non-UUID identifiers."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Post"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing or inaccessible resource; capability invite can also be invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Identity/organization service or attachment storage unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "editPost",
        "tags": [
          "Community"
        ],
        "summary": "Edit a community post",
        "description": "Uses the existing Bearer identity without an organization header. Browser Origin must be allowed. JSON is limited to 40,000 bytes; strings are trimmed. Community writes are limited to 12 per user per minute. Send expected_updated_at from the latest read. A stale value returns the corresponding edit-conflict code without changing text or attachments. Post authors or administrators can edit posts; only comment authors can edit comments.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "postId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Server-issued identifier; reserved examples can use non-UUID identifiers."
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PostEdit"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PostWriteResult"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden author or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing resource.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflicting operation input or stale expected_updated_at.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Request body too large.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many writes.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/commerce/context": {
      "get": {
        "operationId": "getCommerceContext",
        "tags": [
          "Commerce"
        ],
        "summary": "Read authorized organizations and file availability",
        "description": "Select an organization returned here and use its exact id in X-Metheus-Org. Membership is checked on every protected commerce request.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CommerceContext"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Identity/organization service or attachment storage unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/commerce/requests": {
      "get": {
        "operationId": "listRequests",
        "tags": [
          "Commerce"
        ],
        "summary": "List requests for the selected buyer organization",
        "description": "Paginated, newest created_at/id first. Cursor is scoped to organization, role and filters. Keep q/status/role unchanged for the next page; next_cursor null means the end. Unknown or duplicate parameters are rejected.",
        "security": [
          {
            "BearerAuth": [],
            "OrgHeader": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/RequestSummary"
                      }
                    },
                    "next_cursor": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "items",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or missing organization header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing or inaccessible resource; capability invite can also be invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Identity/organization service or attachment storage unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Opaque next_cursor from the prior response."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 100
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 150
            },
            "description": "Literal title substring."
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Exact request, offer or order status."
          }
        ]
      },
      "post": {
        "operationId": "createRequest",
        "tags": [
          "Commerce"
        ],
        "summary": "Create a private manufacturing request",
        "description": "Owner and organization come from verified identity/headers. Requires authorization to create/share project data. No supplier notification is sent automatically.",
        "security": [
          {
            "BearerAuth": [],
            "OrgHeader": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RequestInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Request"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or missing organization header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing or inaccessible resource; capability invite can also be invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Stale revision, invalid state, stale/expired offer, or already-submitted offer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Body or file exceeds the size limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Unsupported Content-Type.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many write requests.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Identity/organization service or attachment storage unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/commerce/requests/{requestId}": {
      "get": {
        "operationId": "getRequest",
        "tags": [
          "Commerce"
        ],
        "summary": "Read request, offers and file metadata",
        "description": "Buyer organization reads all offers; a supplier organization that submitted an offer sees only its own. Unselected suppliers do not see the order id. Privileged operational read access may exist.",
        "security": [
          {
            "BearerAuth": [],
            "OrgHeader": []
          }
        ],
        "parameters": [
          {
            "name": "requestId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Server-issued identifier.",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Request"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or missing organization header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing or inaccessible resource; capability invite can also be invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Identity/organization service or attachment storage unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateRequest",
        "tags": [
          "Commerce"
        ],
        "summary": "Replace editable request fields at current revision",
        "description": "Buyer organization, open requests only. Increments request revision and makes older offers stale. Supply all required fields; PATCH is not a sparse merge.",
        "security": [
          {
            "BearerAuth": [],
            "OrgHeader": []
          }
        ],
        "parameters": [
          {
            "name": "requestId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Server-issued identifier.",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RequestUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Request"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or missing organization header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing or inaccessible resource; capability invite can also be invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Stale revision, invalid state, stale/expired offer, or already-submitted offer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Body or file exceeds the size limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Unsupported Content-Type.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many write requests.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Identity/organization service or attachment storage unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/commerce/requests/{requestId}/invites": {
      "post": {
        "operationId": "createInvite",
        "tags": [
          "Commerce"
        ],
        "summary": "Create a revocable request capability",
        "description": "Buyer organization, open request and current revision. Does not change the request revision. Returned token is secret; sharing it requires user authorization and is not performed by this endpoint.",
        "security": [
          {
            "BearerAuth": [],
            "OrgHeader": []
          }
        ],
        "parameters": [
          {
            "name": "requestId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Server-issued identifier.",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InviteInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InviteCreated"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or missing organization header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing or inaccessible resource; capability invite can also be invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Stale revision, invalid state, stale/expired offer, or already-submitted offer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Body or file exceeds the size limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Unsupported Content-Type.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many write requests.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Identity/organization service or attachment storage unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/commerce/requests/{requestId}/invites/{inviteId}": {
      "delete": {
        "operationId": "revokeInvite",
        "tags": [
          "Commerce"
        ],
        "summary": "Revoke an invitation",
        "description": "Buyer organization only. No request body and no revision parameter. Does not change request revision.",
        "security": [
          {
            "BearerAuth": [],
            "OrgHeader": []
          }
        ],
        "parameters": [
          {
            "name": "requestId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Server-issued identifier.",
              "format": "uuid"
            }
          },
          {
            "name": "inviteId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Server-issued identifier.",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "revoked": {
                      "const": true
                    }
                  },
                  "required": [
                    "revoked"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or missing organization header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing or inaccessible resource; capability invite can also be invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many write requests.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Identity/organization service or attachment storage unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/commerce/invite": {
      "get": {
        "operationId": "readInvite",
        "tags": [
          "Commerce"
        ],
        "summary": "Read the request shared by an invite",
        "description": "Invite capability only; no Bearer/organization required. Exposes request and file metadata, not offers, buyer identity, or file bytes. Request must still be open.",
        "security": [
          {
            "InviteHeader": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InviteRequest"
                }
              }
            }
          },
          "404": {
            "description": "Missing or inaccessible resource; capability invite can also be invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Stale revision, invalid state, stale/expired offer, or already-submitted offer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/commerce/invite/offers": {
      "post": {
        "operationId": "submitOffer",
        "tags": [
          "Commerce"
        ],
        "summary": "Submit the supplier organization's first quote",
        "description": "Requires an active invite, authenticated organization distinct from buyer, and current request_revision. One offer per supplier organization per request. Supplier must approve real prices/terms before submission; do not invent quotes.",
        "security": [
          {
            "BearerAuth": [],
            "OrgHeader": [],
            "InviteHeader": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OfferInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Offer"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or missing organization header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing or inaccessible resource; capability invite can also be invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Stale revision, invalid state, stale/expired offer, or already-submitted offer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Body or file exceeds the size limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Unsupported Content-Type.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many write requests.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Identity/organization service or attachment storage unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/commerce/offers": {
      "get": {
        "operationId": "listOwnOffers",
        "tags": [
          "Commerce"
        ],
        "summary": "List the selected supplier organization's offers",
        "description": "Paginated, newest created_at/id first. Cursor is scoped to organization, role and filters. Keep q/status/role unchanged for the next page; next_cursor null means the end. Unknown or duplicate parameters are rejected.",
        "security": [
          {
            "BearerAuth": [],
            "OrgHeader": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/OfferListItem"
                      }
                    },
                    "next_cursor": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "items",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or missing organization header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing or inaccessible resource; capability invite can also be invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Identity/organization service or attachment storage unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Opaque next_cursor from the prior response."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 100
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 150
            },
            "description": "Literal title substring."
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Exact request, offer or order status."
          }
        ]
      }
    },
    "/api/commerce/offers/{offerId}": {
      "patch": {
        "operationId": "updateOffer",
        "tags": [
          "Commerce"
        ],
        "summary": "Replace a supplier quote at current revisions",
        "description": "Submitting supplier organization only; parent request must be open. Supply current offer revision, current request_revision and all quote fields. Increments offer revision. Updating a withdrawn offer with the full current fields resubmits it as active.",
        "security": [
          {
            "BearerAuth": [],
            "OrgHeader": []
          }
        ],
        "parameters": [
          {
            "name": "offerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Server-issued identifier.",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OfferUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Offer"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or missing organization header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing or inaccessible resource; capability invite can also be invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Stale revision, invalid state, stale/expired offer, or already-submitted offer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Body or file exceeds the size limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Unsupported Content-Type.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many write requests.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Identity/organization service or attachment storage unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/commerce/requests/{requestId}/accept": {
      "post": {
        "operationId": "requestOrder",
        "tags": [
          "Commerce"
        ],
        "summary": "Approve the selected quote and request an order",
        "description": "Buyer organization only. Obtain the user's explicit approval of exact price, quantity, taxes, shipping, terms, revisions and delivery information before calling. Freezes an immutable snapshot and sets order_requested; it is not supplier confirmation or payment. Current request and offer revisions must match. The same offer_id/offer_revision/request_revision tuple returns the existing order (201), preserving the original delivery snapshot. A different tuple conflicts. No general Idempotency-Key support.",
        "security": [
          {
            "BearerAuth": [],
            "OrgHeader": []
          }
        ],
        "parameters": [
          {
            "name": "requestId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Server-issued identifier.",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AcceptOfferInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Order"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or missing organization header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing or inaccessible resource; capability invite can also be invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Stale revision, invalid state, stale/expired offer, or already-submitted offer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Body or file exceeds the size limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Unsupported Content-Type.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many write requests.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Identity/organization service or attachment storage unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/commerce/orders": {
      "get": {
        "operationId": "listOrders",
        "tags": [
          "Commerce"
        ],
        "summary": "List buyer or supplier orders",
        "description": "Paginated, newest created_at/id first. Cursor is scoped to organization, role and filters. Keep q/status/role unchanged for the next page; next_cursor null means the end. Unknown or duplicate parameters are rejected.",
        "security": [
          {
            "BearerAuth": [],
            "OrgHeader": []
          }
        ],
        "parameters": [
          {
            "name": "role",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "buyer",
                "supplier"
              ],
              "default": "buyer"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Opaque next_cursor from the prior response."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 100
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 150
            },
            "description": "Literal title substring."
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Exact request, offer or order status."
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Order"
                      }
                    },
                    "next_cursor": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "items",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or missing organization header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing or inaccessible resource; capability invite can also be invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Identity/organization service or attachment storage unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/commerce/orders/{orderId}": {
      "get": {
        "operationId": "getOrder",
        "tags": [
          "Commerce"
        ],
        "summary": "Read an order snapshot and event history",
        "security": [
          {
            "BearerAuth": [],
            "OrgHeader": []
          }
        ],
        "parameters": [
          {
            "name": "orderId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Server-issued identifier.",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Order"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or missing organization header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing or inaccessible resource; capability invite can also be invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Identity/organization service or attachment storage unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/commerce/orders/{orderId}/actions": {
      "post": {
        "operationId": "changeOrderState",
        "tags": [
          "Commerce"
        ],
        "summary": "Record an authorized order action or shipping correction",
        "description": "All actions require the current order revision and increment it. Supplier: confirm/decline from order_requested; start_production from accepted; ship from production. Buyer: receive from shipped; request_cancel from order_requested/accepted/production. While cancellation is pending, supplier must accept_cancel or reject_cancel; other transitions are blocked. States are party-entered, not machine-verified. Re-read after an uncertain write; do not blindly retry. Supplier correct_shipping requires shipped status, the current revision, carrier/tracking_number/HTTPS tracking_url and reason (3–1000 characters); unchanged values are 400. It preserves shipped_at and the fixed snapshot, adds corrected_at and a previous/current audit event. It does not confirm delivery or resend a shipment.",
        "security": [
          {
            "BearerAuth": [],
            "OrgHeader": []
          }
        ],
        "parameters": [
          {
            "name": "orderId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Server-issued identifier.",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrderAction"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Order"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or missing organization header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing or inaccessible resource; capability invite can also be invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Stale revision, invalid state, stale/expired offer, or already-submitted offer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Body or file exceeds the size limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Unsupported Content-Type.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many write requests.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Identity/organization service or attachment storage unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/commerce/requests/{requestId}/files": {
      "post": {
        "operationId": "uploadRequestFile",
        "tags": [
          "Commerce"
        ],
        "summary": "Attach a private CAD or PDF file",
        "description": "Buyer organization and open request only. Raw binary, no multipart. Maximum 20 MiB/file and 10 files/request. Storage must be available. File extension/size/hash checks do not validate CAD geometry, file safety, or manufacturing suitability. Increments request revision; do not automatically retry after uncertain completion.",
        "security": [
          {
            "BearerAuth": [],
            "OrgHeader": []
          }
        ],
        "parameters": [
          {
            "name": "requestId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Server-issued identifier.",
              "format": "uuid"
            }
          },
          {
            "name": "X-Metheus-Filename",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "description": "URI-encoded basename, decoded maximum 180 characters. Allowed suffixes: .step .stp .stl .fcstd .pdf .json .csv .dxf; no path separators/control or Windows reserved filename characters."
            }
          },
          {
            "name": "X-Metheus-Revision",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991,
              "description": "Current revision returned by the server. A stale value causes 409."
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadResult"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or missing organization header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing or inaccessible resource; capability invite can also be invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Stale revision, invalid state, stale/expired offer, or already-submitted offer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Body or file exceeds the size limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Unsupported Content-Type.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many write requests.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Identity/organization service or attachment storage unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/octet-stream": {
              "schema": {
                "type": "string",
                "format": "binary",
                "description": "1–20,971,520 bytes."
              }
            }
          }
        }
      }
    },
    "/api/commerce/files/{fileId}": {
      "get": {
        "operationId": "downloadRequestFile",
        "tags": [
          "Commerce"
        ],
        "summary": "Download an authorized private attachment",
        "description": "Buyer organization or selected supplier can download. Before selection, an authenticated organization additionally needs a valid invite for this still-open request. An anonymous invite alone never grants byte access. Downloads have attachment Content-Disposition and no-store; treat content as untrusted.",
        "security": [
          {
            "BearerAuth": [],
            "OrgHeader": []
          },
          {
            "BearerAuth": [],
            "OrgHeader": [],
            "InviteHeader": []
          }
        ],
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Server-issued identifier.",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Private file bytes.",
            "headers": {
              "Content-Disposition": {
                "schema": {
                  "type": "string"
                }
              },
              "Content-Length": {
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 20971520
                }
              }
            },
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or missing organization header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing or inaccessible resource; capability invite can also be invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Identity/organization service or attachment storage unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/commerce/orders/{orderId}/requote": {
      "post": {
        "operationId": "prepareRequote",
        "tags": [
          "Commerce"
        ],
        "summary": "Prepare a new request after a declined or cancelled order",
        "description": "Explicit user confirmation of new conditions and selected source snapshot attachments is required. Only the same buyer organization may create it; no privileged read access grants write permission. Source order must be declined/cancelled. Copies server-owned source files under new IDs, verifies bytes/SHA-256 and publishes one complete request. Original order snapshot, request and files remain unchanged. Invites, offers, delivery address and shipping are not copied. One child per source order: retries return it without overwriting changes. Generating/sharing a new invite, accepting a new supplier quote and supplying an approved new delivery address are separate actions. Not a general Idempotency-Key API. If both files of snapshot.current_design are selected, the new request preserves their bundle/roles with new copied file IDs at revision 1. Partial or legacy selections remain ordinary attachments without inferred relationships.",
        "security": [
          {
            "BearerAuth": [],
            "OrgHeader": []
          }
        ],
        "parameters": [
          {
            "name": "orderId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Server-issued identifier.",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RequoteInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returned the existing follow-up request unchanged. reused is true; submitted replacement fields/file selections are not applied.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RequoteResult"
                }
              }
            }
          },
          "201": {
            "description": "Created one new open request and all selected attachment copies. reused is false.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RequoteResult"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or missing organization header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing or inaccessible resource; capability invite can also be invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Stale revision, invalid state, stale/expired offer, or already-submitted offer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Body or file exceeds the size limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Unsupported Content-Type.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many write requests.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Identity, organization service or required attachment storage/copy unavailable. No partial new request/file metadata is published on a copy failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/projects": {
      "get": {
        "operationId": "listPersonalProjects",
        "tags": [
          "Personal projects"
        ],
        "summary": "List personal projects",
        "security": [
          {
            "BearerAuth": [],
            "OrgHeader": [],
            "ProjectOwner": []
          }
        ],
        "responses": {
          "400": {
            "description": "Invalid project request, missing org header, invalid decision or missing captured owner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Project, file or fixed revision unavailable; org_not_found requires organization selection.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Account changed, record filename exists, or storage revision conflict. Re-read before retrying a write.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Body or file exceeds the size limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Upstream request limit; wait before an explicit retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Invalid, oversized, interrupted or redirected project upstream response."
          },
          "504": {
            "description": "Project request timeout. Verify an uncertain save before retrying."
          },
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PersonalProject"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createPersonalProject",
        "tags": [
          "Personal projects"
        ],
        "summary": "Explicitly create a personal project",
        "security": [
          {
            "BearerAuth": [],
            "OrgHeader": [],
            "ProjectOwner": []
          }
        ],
        "responses": {
          "400": {
            "description": "Invalid project request, missing org header, invalid decision or missing captured owner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Project, file or fixed revision unavailable; org_not_found requires organization selection.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Account changed, record filename exists, or storage revision conflict. Re-read before retrying a write.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Body or file exceeds the size limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Unsupported Content-Type.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Upstream request limit; wait before an explicit retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Invalid, oversized, interrupted or redirected project upstream response."
          },
          "504": {
            "description": "Project request timeout. Verify an uncertain save before retrying."
          },
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PersonalProject"
                }
              }
            }
          }
        },
        "description": "On uncertain creation, GET the same ID before repeating. Do not generate a second ID automatically. Creation JSON is at most 4096 bytes; metadata/list responses are bounded to 2 MiB.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "id",
                  "name"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 128,
                    "pattern": "^[a-zA-Z0-9_.-]+$",
                    "description": "Cannot be . or ..; UUID v4 recommended."
                  },
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80,
                    "description": "Must contain non-whitespace."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/projects/{projectId}": {
      "get": {
        "operationId": "getPersonalProject",
        "tags": [
          "Personal projects"
        ],
        "summary": "Read current project metadata",
        "security": [
          {
            "BearerAuth": [],
            "OrgHeader": [],
            "ProjectOwner": []
          }
        ],
        "responses": {
          "400": {
            "description": "Invalid project request, missing org header, invalid decision or missing captured owner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Project, file or fixed revision unavailable; org_not_found requires organization selection.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Account changed, record filename exists, or storage revision conflict. Re-read before retrying a write.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Body or file exceeds the size limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Upstream request limit; wait before an explicit retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Invalid, oversized, interrupted or redirected project upstream response."
          },
          "504": {
            "description": "Project request timeout. Verify an uncertain save before retrying."
          },
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PersonalProject"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "projectId",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "description": "URL-encoded personal project ID."
          }
        ]
      }
    },
    "/api/projects/{projectId}/files": {
      "get": {
        "operationId": "readProjectFileRevision",
        "tags": [
          "Personal projects"
        ],
        "summary": "Read fixed revision file bytes",
        "security": [
          {
            "BearerAuth": [],
            "OrgHeader": [],
            "ProjectOwner": []
          }
        ],
        "responses": {
          "400": {
            "description": "Invalid project request, missing org header, invalid decision or missing captured owner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Project, file or fixed revision unavailable; org_not_found requires organization selection.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Account changed, record filename exists, or storage revision conflict. Re-read before retrying a write.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Body or file exceeds the size limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Upstream request limit; wait before an explicit retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Invalid, oversized, interrupted or redirected project upstream response."
          },
          "504": {
            "description": "Project request timeout. Verify an uncertain save before retrying."
          },
          "200": {
            "description": "At most 50 MiB, no-store. Verify size and SHA-256 against captured manifest.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "projectId",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "description": "URL-encoded personal project ID."
          },
          {
            "in": "query",
            "name": "name",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 240
            }
          },
          {
            "in": "query",
            "name": "revision",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            },
            "description": "Fixed revision for GET, expected current revision for PUT. Not a CAD revision."
          }
        ]
      },
      "put": {
        "operationId": "storeDesignDecision",
        "tags": [
          "Personal projects"
        ],
        "summary": "Store a new design decision file",
        "security": [
          {
            "BearerAuth": [],
            "OrgHeader": [],
            "ProjectOwner": []
          }
        ],
        "responses": {
          "400": {
            "description": "Invalid project request, missing org header, invalid decision or missing captured owner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Project, file or fixed revision unavailable; org_not_found requires organization selection.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Account changed, record filename exists, or storage revision conflict. Re-read before retrying a write.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Body or file exceeds the size limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Upstream request limit; wait before an explicit retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Invalid, oversized, interrupted or redirected project upstream response."
          },
          "504": {
            "description": "Project request timeout. Verify an uncertain save before retrying."
          },
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PersonalProject"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "projectId",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "description": "URL-encoded personal project ID."
          },
          {
            "in": "query",
            "name": "name",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 150
            }
          },
          {
            "in": "query",
            "name": "revision",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            },
            "description": "Fixed revision for GET, expected current revision for PUT. Not a CAD revision."
          }
        ],
        "description": "Raw UTF-8 metheus.design-decision/1, at most 50 MiB. Filename metheus-decision-<UUID-v4>[--title].json must match envelope ID; total <=150 characters, NFC; optional title 1-60 letters/numbers/spaces/underscores/hyphens with no outer whitespace. No case-insensitive overwrite. Exact v2 comparison bytes, original A/B report hashes, selected parts/view and chosen report hash must pass codec validation. Read api.md for the envelope contract. After 409 or lost response, re-read the same filename at a fixed revision and verify size/hash before another write. Does not change CAD, chat, memory.md or approval.",
        "requestBody": {
          "required": true,
          "content": {
            "application/octet-stream": {
              "schema": {
                "type": "string",
                "format": "binary",
                "description": "UTF-8 JSON metheus.design-decision/1 with id, created, title, decision(choice/reportSha256/reason/nextStep) and comparison(encoding/byteLength/sha256/data)."
              }
            }
          }
        }
      }
    },
    "/api/commerce/requests/design-bundle": {
      "post": {
        "operationId": "createManufacturingDesign",
        "tags": [
          "Commerce"
        ],
        "summary": "Save manufacturing conditions with the selected report and BOM",
        "description": "Create a request and both files together. Omit header revision. Requires explicit user save. Body: uint32 big-endian UTF-8 JSON header byte length (1..65536), ManufacturingBundleHeader JSON, report bytes, BOM bytes. Each file is 1..20MiB; exact lengths/SHA256 must match. No multipart/base64. DB publication is atomic. Same verified user/org/operation_id, target and exact body return the original saved receipt with reused:true, even after subsequent edits. Different target/body with that key is 409. Fetch the request before any subsequent action. No supplier notification is sent.",
        "security": [
          {
            "BearerAuth": [],
            "OrgHeader": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/vnd.metheus.design-bundle": {
              "schema": {
                "type": "string",
                "format": "binary"
              },
              "description": "See ManufacturingBundleHeader and the framing description."
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Request"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "reused": {
                          "type": "boolean"
                        },
                        "operation_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "saved_design_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "saved_request_revision": {
                          "type": "integer",
                          "minimum": 1
                        }
                      },
                      "required": [
                        "reused",
                        "operation_id",
                        "saved_design_id",
                        "saved_request_revision"
                      ]
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or missing organization header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing or inaccessible resource; capability invite can also be invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Stale revision, invalid state, stale/expired offer, or already-submitted offer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Body or file exceeds the size limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Unsupported Content-Type.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many write requests.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Identity/organization service or attachment storage unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Request"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "reused": {
                          "type": "boolean"
                        },
                        "operation_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "saved_design_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "saved_request_revision": {
                          "type": "integer",
                          "minimum": 1
                        }
                      },
                      "required": [
                        "reused",
                        "operation_id",
                        "saved_design_id",
                        "saved_request_revision"
                      ]
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/commerce/requests/{requestId}/design-bundle": {
      "post": {
        "operationId": "updateManufacturingDesign",
        "tags": [
          "Commerce"
        ],
        "summary": "Save manufacturing conditions with the selected report and BOM",
        "description": "Update an explicitly selected open buyer request. Header revision is required; one successful bundle increments it once. Requires explicit user save. Body: uint32 big-endian UTF-8 JSON header byte length (1..65536), ManufacturingBundleHeader JSON, report bytes, BOM bytes. Each file is 1..20MiB; exact lengths/SHA256 must match. No multipart/base64. DB publication is atomic. Same verified user/org/operation_id, target and exact body return the original saved receipt with reused:true, even after subsequent edits. Different target/body with that key is 409. Fetch the request before any subsequent action. No supplier notification is sent.",
        "security": [
          {
            "BearerAuth": [],
            "OrgHeader": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/vnd.metheus.design-bundle": {
              "schema": {
                "type": "string",
                "format": "binary"
              },
              "description": "See ManufacturingBundleHeader and the framing description."
            }
          }
        },
        "responses": {
          "400": {
            "description": "Invalid input or missing organization header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing or inaccessible resource; capability invite can also be invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Stale revision, invalid state, stale/expired offer, or already-submitted offer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Body or file exceeds the size limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Unsupported Content-Type.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many write requests.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Identity/organization service or attachment storage unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Request"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "reused": {
                          "type": "boolean"
                        },
                        "operation_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "saved_design_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "saved_request_revision": {
                          "type": "integer",
                          "minimum": 1
                        }
                      },
                      "required": [
                        "reused",
                        "operation_id",
                        "saved_design_id",
                        "saved_request_revision"
                      ]
                    }
                  ]
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "requestId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/api/news": {
      "get": {
        "operationId": "listDesignNews",
        "tags": [
          "Public information"
        ],
        "summary": "Read editorially selected official AI engineering announcements",
        "description": "Manually curated items ordered by announcement date. publishedAt is the source publication date, verifiedAt is our source review date, and whyItMatters is an editorial application suggestion. This is not a live news feed.",
        "responses": {
          "200": {
            "description": "Public announcement list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "required": [
                      "id",
                      "title",
                      "publishedAt",
                      "verifiedAt",
                      "sourceUrl",
                      "publisher"
                    ],
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "title": {
                        "type": "string"
                      },
                      "publishedAt": {
                        "type": "string",
                        "format": "date"
                      },
                      "verifiedAt": {
                        "type": "string",
                        "format": "date"
                      },
                      "sourceUrl": {
                        "type": "string",
                        "format": "uri"
                      },
                      "publisher": {
                        "type": "string"
                      },
                      "summary": {
                        "type": "string"
                      },
                      "category": {
                        "type": "string"
                      },
                      "sourceTitle": {
                        "type": "string"
                      },
                      "whyItMatters": {
                        "type": "string"
                      },
                      "guideId": {
                        "type": "string"
                      },
                      "caveat": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/commerce/requests/{requestId}/files/{fileId}": {
      "delete": {
        "operationId": "excludeRequestFile",
        "tags": [
          "Commerce"
        ],
        "summary": "Exclude a general attachment from an open request; preserve its bytes and audit history. Bundled design files cannot be removed individually.",
        "description": "Exclude a general attachment from an open request; preserve its bytes and audit history. Bundled design files cannot be removed individually.",
        "security": [
          {
            "BearerAuth": [],
            "OrgHeader": []
          }
        ],
        "parameters": [
          {
            "name": "requestId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "fileId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "revision": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 9007199254740991,
                    "description": "Current revision returned by the server. A stale value causes 409."
                  }
                },
                "required": [
                  "revision"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Request"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or missing organization header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing or inaccessible resource; capability invite can also be invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Stale revision, invalid state, stale/expired offer, or already-submitted offer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Body or file exceeds the size limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Unsupported Content-Type.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many write requests.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Identity/organization service or attachment storage unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/commerce/requests/{requestId}/actions": {
      "post": {
        "operationId": "changeRequestState",
        "tags": [
          "Commerce"
        ],
        "summary": "Close or reopen a pre-award request. Closing revokes invitations; reopening requires fresh invitations and quotes.",
        "description": "Close or reopen a pre-award request. Closing revokes invitations; reopening requires fresh invitations and quotes.",
        "security": [
          {
            "BearerAuth": [],
            "OrgHeader": []
          }
        ],
        "parameters": [
          {
            "name": "requestId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "revision": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 9007199254740991,
                    "description": "Current revision returned by the server. A stale value causes 409."
                  },
                  "action": {
                    "enum": [
                      "close",
                      "reopen"
                    ]
                  },
                  "note": {
                    "type": "string",
                    "maxLength": 1000
                  }
                },
                "required": [
                  "revision",
                  "action"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Request"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or missing organization header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing or inaccessible resource; capability invite can also be invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Stale revision, invalid state, stale/expired offer, or already-submitted offer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Body or file exceeds the size limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Unsupported Content-Type.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many write requests.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Identity/organization service or attachment storage unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/commerce/offers/{offerId}/actions": {
      "post": {
        "operationId": "withdrawOffer",
        "tags": [
          "Commerce"
        ],
        "summary": "Withdraw your own offer before award. PATCH its full conditions with current revisions to resubmit.",
        "description": "Withdraw your own offer before award. PATCH its full conditions with current revisions to resubmit.",
        "security": [
          {
            "BearerAuth": [],
            "OrgHeader": []
          }
        ],
        "parameters": [
          {
            "name": "offerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "revision": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 9007199254740991,
                    "description": "Current revision returned by the server. A stale value causes 409."
                  },
                  "action": {
                    "const": "withdraw"
                  }
                },
                "required": [
                  "revision",
                  "action"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Offer"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or missing organization header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or expired identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden role or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing or inaccessible resource; capability invite can also be invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Stale revision, invalid state, stale/expired offer, or already-submitted offer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Body or file exceeds the size limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Unsupported Content-Type.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many write requests.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Identity/organization service or attachment storage unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/posts/{postId}/comments": {
      "get": {
        "operationId": "listComments",
        "tags": [
          "Community"
        ],
        "summary": "Read a post comment page",
        "description": "Read 20 root threads with the first 3 live replies per thread. focus selects the root page and a 20-reply page containing the target. Replies always use creation order, including timestamp ties. Deleted roots remain only while live replies exist. view=flat retains a flat timeline of live comments. Supplied Authorization is validated.",
        "security": [
          {},
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "postId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Server-issued identifier; reserved examples can use non-UUID identifiers."
            }
          },
          {
            "name": "view",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "flat"
              ]
            }
          },
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "oldest",
                "newest"
              ],
              "default": "oldest"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 100000,
              "default": 0
            }
          },
          {
            "name": "focus",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Existing comment or reply ID; selects its page in either view."
          }
        ],
        "responses": {
          "200": {
            "description": "Comment page.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CommentsPage"
                }
              }
            }
          },
          "400": {
            "description": "Invalid sort or offset.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid supplied identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing post or focus comment.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createComment",
        "tags": [
          "Community"
        ],
        "summary": "Create a comment in this post",
        "description": "Uses the existing Bearer identity without an organization header. Browser Origin must be allowed. JSON is limited to 40,000 bytes; strings are trimmed. Community writes are limited to 12 per user per minute. With operation_id, the first save returns 201; an exact retry returns 200 and reused:true, with the current resource state (later edits are preserved). The key is scoped to the author and operation target. Reusing the key with different input returns 409 operation_conflict and resource_id. Deleted results are not recreated (410; a missing parent post may be 404). Without the key, duplicate protection is not guaranteed. This does not cover photo uploads or other POST operations.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "postId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Server-issued identifier; reserved examples can use non-UUID identifiers."
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CommentCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Comment"
                }
              }
            }
          },
          "200": {
            "description": "Exact retry; returns the current saved resource with reused:true.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Comment"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden author or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing resource.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflicting operation input or stale expected_updated_at.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Request body too large.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many writes.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "The result of this operation was deleted and cannot be recreated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/posts/{postId}/comments/{commentId}": {
      "patch": {
        "operationId": "editComment",
        "tags": [
          "Community"
        ],
        "summary": "Edit an owned comment",
        "description": "Uses the existing Bearer identity without an organization header. Browser Origin must be allowed. JSON is limited to 40,000 bytes; strings are trimmed. Community writes are limited to 12 per user per minute. Send expected_updated_at from the latest read. A stale value returns the corresponding edit-conflict code without changing text or attachments. Post authors or administrators can edit posts; only comment authors can edit comments.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "postId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Server-issued identifier; reserved examples can use non-UUID identifiers."
            }
          },
          {
            "name": "commentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Server-issued identifier; reserved examples can use non-UUID identifiers."
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CommentEdit"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Comment"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden author or Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing resource.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflicting operation input or stale expected_updated_at.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Request body too large.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many writes.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/posts/{postId}/making-interest": {
      "post": {
        "operationId": "setMakingInterest",
        "summary": "Set group build interest",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "description": "Authenticated per-account demand; no purchase, payment, notification or order. Identical quantities for the current specification revision are idempotent. When my_needs_confirmation is true, show current and previous specifications and obtain explicit confirmation before resubmitting, including for an unchanged quantity. Stale specification or interest versions are 409; do not automatically confirm changed specifications. Withdrawal remains available after recruitment stops.",
        "parameters": [
          {
            "name": "postId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "expected_updated_at": {
                    "type": "string",
                    "description": "Exact making.updated_at from latest read."
                  },
                  "quantity": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 100000,
                    "description": "Absolute quantity. Zero withdraws interest; positive quantities require open recruitment."
                  },
                  "expected_interest_updated_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Exact my_interest_updated_at from latest read; null for first participation."
                  }
                },
                "required": [
                  "expected_updated_at",
                  "quantity",
                  "expected_interest_updated_at"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Current making state",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MakingState"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Origin or ownership denied"
          },
          "404": {
            "description": "Proposal missing"
          },
          "409": {
            "description": "Stale version, fixed specifications, closed recruitment or invalid transition"
          },
          "429": {
            "description": "Community write rate limit exceeded"
          }
        }
      }
    },
    "/api/posts/{postId}/making-stage": {
      "post": {
        "operationId": "setMakingStage",
        "summary": "Set group build stage",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "description": "Post author or administrator only. Closing is terminal; quoting may return to recruiting before the deadline. Transitions lock specifications. Repeated current stage is a no-op.",
        "parameters": [
          {
            "name": "postId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "expected_updated_at": {
                    "type": "string",
                    "description": "Exact making.updated_at from latest read."
                  },
                  "stage": {
                    "type": "string",
                    "enum": [
                      "recruiting",
                      "quoting",
                      "closed"
                    ]
                  }
                },
                "required": [
                  "expected_updated_at",
                  "stage"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Current making state",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MakingState"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Origin or ownership denied"
          },
          "404": {
            "description": "Proposal missing"
          },
          "409": {
            "description": "Stale version, fixed specifications, closed recruitment or invalid transition"
          },
          "429": {
            "description": "Community write rate limit exceeded"
          }
        }
      }
    },
    "/api/notifications": {
      "get": {
        "tags": [
          "Notifications"
        ],
        "summary": "List notifications for the authenticated personal account",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "community",
                "credits"
              ],
              "default": "all"
            }
          },
          {
            "name": "unread",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "0",
                "1"
              ],
              "default": "0"
            }
          },
          {
            "name": "before",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items",
                    "next_cursor",
                    "through",
                    "unread_count"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "maxItems": 20,
                      "items": {
                        "$ref": "#/components/schemas/Notification"
                      }
                    },
                    "next_cursor": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "minimum": 0,
                      "maximum": 9007199254740991
                    },
                    "through": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 9007199254740991
                    },
                    "unread_count": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 9007199254740991
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid filter, cursor or JSON body."
          },
          "401": {
            "description": "Authentication required."
          },
          "403": {
            "description": "Origin or authentication rejected."
          },
          "503": {
            "description": "Identity service unavailable."
          }
        }
      }
    },
    "/api/storage": {
      "get": {
        "tags": [
          "Storage"
        ],
        "summary": "Summarize the signed-in account’s platform-stored data and sizes",
        "description": "Read-only list of posts, comments, unposted photos, bookmarks and canvas boards owned by this account, with stored byte sizes. Workspace data (projects, quote requests, image meshes) is read from its own APIs and is not included. No overall storage quota is enforced. Cache-Control: no-store.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PersonalStorage"
                }
              }
            }
          },
          "401": {
            "description": "Authentication required."
          },
          "503": {
            "description": "Identity service unavailable."
          }
        }
      }
    },
    "/api/notifications/summary": {
      "get": {
        "tags": [
          "Notifications"
        ],
        "summary": "Count all unread notifications for this account",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationSummary"
                }
              }
            }
          },
          "400": {
            "description": "Invalid filter, cursor or JSON body."
          },
          "401": {
            "description": "Authentication required."
          },
          "403": {
            "description": "Origin or authentication rejected."
          },
          "503": {
            "description": "Identity service unavailable."
          }
        }
      }
    },
    "/api/notifications/{notificationId}/read": {
      "post": {
        "tags": [
          "Notifications"
        ],
        "summary": "Mark one owned notification as read",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "notificationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationSummary"
                }
              }
            }
          },
          "400": {
            "description": "Invalid filter, cursor or JSON body."
          },
          "401": {
            "description": "Authentication required."
          },
          "403": {
            "description": "Origin or authentication rejected."
          },
          "404": {
            "description": "Notification not found or not owned by this account."
          },
          "429": {
            "description": "Too many requests."
          },
          "503": {
            "description": "Identity service unavailable."
          }
        }
      }
    },
    "/api/notifications/read-all": {
      "post": {
        "tags": [
          "Notifications"
        ],
        "summary": "Mark every notification through the first-page snapshot as read",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "through"
                ],
                "properties": {
                  "through": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationSummary"
                }
              }
            }
          },
          "400": {
            "description": "Invalid filter, cursor or JSON body."
          },
          "401": {
            "description": "Authentication required."
          },
          "403": {
            "description": "Origin or authentication rejected."
          },
          "429": {
            "description": "Too many requests."
          },
          "503": {
            "description": "Identity service unavailable."
          }
        }
      }
    },
    "/api/posts/{postId}/comments/{commentId}/replies": {
      "get": {
        "operationId": "listCommentReplies",
        "tags": [
          "Community"
        ],
        "summary": "Read live replies in creation order",
        "description": "The commentId must be a root comment in this post. A deleted root remains readable. Deleted replies are excluded. Supplied Authorization is validated.",
        "security": [
          {},
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "postId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Server-issued identifier; reserved examples can use non-UUID identifiers."
            }
          },
          {
            "name": "commentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 100000,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Reply page.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Comment"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "offset": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "limit": {
                      "type": "integer",
                      "const": 20
                    }
                  },
                  "required": [
                    "items",
                    "total",
                    "offset",
                    "limit"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid offset or a non-root comment ID.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid supplied identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing post or root comment.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Existing Metheus access token granted for the authorized user. Do not invent credentials or place tokens in URLs."
      },
      "OrgHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Metheus-Org",
        "description": "Exact organization id returned by GET /api/commerce/context. Not proof of membership by itself."
      },
      "InviteHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Metheus-Invite",
        "description": "Secret 43-character capability issued by a buyer. Send only in this header; protect it from logs and third-party content."
      },
      "ProjectOwner": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Metheus-Project-Owner",
        "description": "Account sub captured when opening the project, compared to verified Bearer. Not an alternate owner selector."
      }
    },
    "schemas": {
      "CreditPolicy": {
        "type": "object",
        "required": [
          "enabled",
          "mode",
          "scope",
          "redemptionEnabled",
          "attendance",
          "featuredReward",
          "featuredMonthlyCap",
          "featuredLikes",
          "timeZone"
        ],
        "properties": {
          "enabled": {
            "const": true
          },
          "mode": {
            "const": "rewards"
          },
          "scope": {
            "const": "personal"
          },
          "redemptionEnabled": {
            "const": false
          },
          "attendance": {
            "type": "object",
            "properties": {
              "daily": {
                "const": 30
              }
            },
            "required": [
              "daily"
            ]
          },
          "featuredReward": {
            "const": 300
          },
          "featuredMonthlyCap": {
            "const": 5
          },
          "featuredLikes": {
            "const": 5
          },
          "timeZone": {
            "const": "Asia/Seoul"
          }
        }
      },
      "Attendance": {
        "type": "object",
        "required": [
          "today",
          "weekday",
          "week",
          "checkedToday",
          "streak",
          "reward"
        ],
        "properties": {
          "today": {
            "type": "string",
            "format": "date"
          },
          "weekday": {
            "type": "integer",
            "minimum": 0,
            "maximum": 6
          },
          "week": {
            "type": "array",
            "minItems": 7,
            "maxItems": 7,
            "items": {
              "type": "boolean"
            }
          },
          "checkedToday": {
            "type": "boolean"
          },
          "streak": {
            "type": "integer",
            "minimum": 0
          },
          "reward": {
            "type": "integer",
            "minimum": 0,
            "description": "Reward recorded for today, not this request’s increment."
          }
        }
      },
      "CreditEntry": {
        "type": "object",
        "required": [
          "id",
          "kind",
          "amount",
          "source_day",
          "created_at",
          "post_id",
          "post_title"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "kind": {
            "enum": [
              "attendance",
              "featured"
            ]
          },
          "amount": {
            "type": "integer",
            "minimum": 1
          },
          "source_day": {
            "type": "string",
            "format": "date"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "post_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "post_title": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "CreditHistory": {
        "type": "object",
        "required": [
          "items",
          "next_cursor"
        ],
        "properties": {
          "items": {
            "type": "array",
            "maxItems": 20,
            "items": {
              "$ref": "#/components/schemas/CreditEntry"
            }
          },
          "next_cursor": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1
          }
        }
      },
      "CreditWallet": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CreditPolicy"
          },
          {
            "$ref": "#/components/schemas/CreditHistory"
          },
          {
            "type": "object",
            "required": [
              "balance",
              "attendance",
              "featured"
            ],
            "properties": {
              "balance": {
                "type": "object",
                "required": [
                  "bonus"
                ],
                "properties": {
                  "bonus": {
                    "type": "integer",
                    "minimum": 0
                  }
                }
              },
              "attendance": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/Attendance"
                  },
                  {
                    "type": "object",
                    "required": [
                      "daily"
                    ],
                    "properties": {
                      "daily": {
                        "const": 30
                      }
                    }
                  }
                ]
              },
              "featured": {
                "type": "object",
                "required": [
                  "month",
                  "awarded",
                  "remaining"
                ],
                "properties": {
                  "month": {
                    "type": "string",
                    "pattern": "^[0-9]{4}-[0-9]{2}$"
                  },
                  "awarded": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "remaining": {
                    "type": "integer",
                    "minimum": 0
                  }
                }
              }
            }
          }
        ]
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Human-readable message; do not branch on its wording."
          },
          "code": {
            "type": "string",
            "description": "Optional machine code, including revision_conflict, org_header_missing, org_not_found, operation_conflict, post_edit_conflict and comment_edit_conflict."
          },
          "resource_id": {
            "type": "string",
            "description": "Saved post or comment ID for operation_conflict. Read it before deciding whether to edit."
          }
        },
        "required": [
          "error"
        ]
      },
      "Source": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "verifiedAt": {
            "type": "string",
            "format": "date"
          },
          "sourcePublishedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          }
        },
        "required": [
          "title",
          "url"
        ]
      },
      "Tip": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "aliases": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Retired guide ids that now resolve to this tip."
          },
          "category": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          },
          "appliesTo": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "keywords": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "body": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "rules": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "text": {
                  "type": "string"
                },
                "source": {
                  "type": "integer",
                  "minimum": 0,
                  "description": "Index into this tip's sources array."
                }
              },
              "required": [
                "text"
              ]
            }
          },
          "tables": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "title": {
                  "type": "string"
                },
                "unit": {
                  "type": "string"
                },
                "columns": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "rows": {
                  "type": "array",
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "note": {
                  "type": "string"
                },
                "source": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "required": [
                "title",
                "columns",
                "rows"
              ]
            }
          },
          "pitfalls": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "checks": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "agent": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "How an agent should apply these criteria and what it must not claim."
          },
          "related": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "starter": {
            "type": "object",
            "properties": {
              "title": {
                "type": "string"
              },
              "description": {
                "type": "string"
              },
              "url": {
                "type": "string"
              },
              "label": {
                "type": "string"
              },
              "verified": {
                "type": "string"
              }
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Source"
            }
          }
        },
        "required": [
          "id",
          "category",
          "title",
          "summary",
          "appliesTo",
          "rules",
          "sources"
        ]
      },
      "CuratedPart": {
        "type": "object",
        "required": [
          "id",
          "name",
          "maker",
          "model",
          "group",
          "kind",
          "headline",
          "summary",
          "price",
          "specs",
          "mechanical",
          "sources"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "maker": {
            "type": "string"
          },
          "model": {
            "type": "string"
          },
          "group": {
            "type": "string",
            "enum": [
              "actuator",
              "driver",
              "board"
            ]
          },
          "geometry": {
            "type": "object",
            "description": "Top (or mounting-face) view in mm, origin at the bottom left. Only features with published positions.",
            "required": [
              "view",
              "w",
              "h",
              "source"
            ],
            "properties": {
              "view": {
                "type": "string"
              },
              "w": {
                "type": "number"
              },
              "h": {
                "type": "number"
              },
              "depth": {
                "type": "number"
              },
              "holes": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "x",
                    "y"
                  ],
                  "properties": {
                    "x": {
                      "type": "number"
                    },
                    "y": {
                      "type": "number"
                    },
                    "d": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "h": {
                      "type": "number",
                      "description": "Height above the top face (bosses, shafts)."
                    },
                    "depth": {
                      "type": "number",
                      "description": "Hole depth from the top face."
                    },
                    "label": {
                      "type": "string"
                    }
                  }
                }
              },
              "circles": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "x",
                    "y"
                  ],
                  "properties": {
                    "x": {
                      "type": "number"
                    },
                    "y": {
                      "type": "number"
                    },
                    "d": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "h": {
                      "type": "number",
                      "description": "Height above the top face (bosses, shafts)."
                    },
                    "depth": {
                      "type": "number",
                      "description": "Hole depth from the top face."
                    },
                    "label": {
                      "type": "string"
                    }
                  }
                }
              },
              "marks": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "axis": {
                      "type": "string"
                    },
                    "at": {
                      "type": "number"
                    },
                    "label": {
                      "type": "string"
                    }
                  }
                }
              },
              "note": {
                "type": "string"
              },
              "source": {
                "type": "integer",
                "minimum": 0
              }
            }
          },
          "tier": {
            "type": "string",
            "enum": [
              "toy"
            ],
            "description": "toy: official specs are published but most units on the market are clones; for toy projects."
          },
          "kind": {
            "type": "string"
          },
          "headline": {
            "type": "string",
            "description": "Key specs on one line."
          },
          "summary": {
            "type": "string"
          },
          "pick": {
            "type": "string",
            "description": "Why Metheus lists it."
          },
          "useFor": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "notFor": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "price": {
            "type": "object",
            "required": [
              "amount",
              "currency",
              "seller",
              "url",
              "checkedOn"
            ],
            "properties": {
              "amount": {
                "type": [
                "number",
                "null"
              ],
              "description": "null when the maker publishes no price; note says why."
              },
              "currency": {
                "type": "string"
              },
              "seller": {
                "type": "string"
              },
              "url": {
                "type": "string",
                "format": "uri"
              },
              "checkedOn": {
                "type": "string",
                "format": "date"
              },
              "note": {
                "type": "string"
              }
            }
          },
          "specs": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "label",
                "value"
              ],
              "properties": {
                "label": {
                  "type": "string"
                },
                "value": {
                  "type": "string"
                },
                "source": {
                  "type": "integer",
                  "minimum": 0,
                  "description": "0-based index into sources."
                }
              }
            }
          },
          "mechanical": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "label",
                "value"
              ],
              "properties": {
                "label": {
                  "type": "string"
                },
                "value": {
                  "type": "string"
                },
                "source": {
                  "type": "integer",
                  "minimum": 0,
                  "description": "0-based index into sources."
                }
              }
            }
          },
          "caveats": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "text"
              ],
              "properties": {
                "text": {
                  "type": "string"
                },
                "source": {
                  "type": "integer",
                  "minimum": 0
                }
              }
            }
          },
          "agent": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "pairsWith": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "tips": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Related design tip ids."
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "title",
                "url",
                "verifiedAt"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string",
                  "format": "uri"
                },
                "verifiedAt": {
                  "type": "string",
                  "format": "date"
                }
              }
            }
          }
        }
      },
      "DesignTool": {
        "type": "object",
        "required": [
          "id",
          "name",
          "provider",
          "access",
          "summary",
          "href",
          "action",
          "tags"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Stable catalog id."
          },
          "name": {
            "type": "string"
          },
          "screen": {
            "type": "string",
            "description": "Screen name inside the Windows app, when the tool is one of its screens."
          },
          "provider": {
            "type": "string"
          },
          "access": {
            "type": "object",
            "required": [
              "mode",
              "label"
            ],
            "description": "How the tool is reached today. Per-run metered pricing is not offered; if it is added it appears here.",
            "properties": {
              "mode": {
                "type": "string",
                "enum": [
                  "free",
                  "login"
                ],
                "description": "free: usable without a Metheus account. login: a Metheus account is required."
              },
              "label": {
                "type": "string",
                "description": "Korean label shown to people."
              }
            }
          },
          "summary": {
            "type": "string"
          },
          "needs": {
            "type": "string",
            "description": "What to have ready before starting."
          },
          "goal": {
            "type": "string",
            "description": "One-line instruction to hand to an AI. Absent when the item is not something an AI runs."
          },
          "note": {
            "type": "string",
            "description": "A limit to keep while running it."
          },
          "href": {
            "type": "string",
            "description": "Page in this site, written for the hash router."
          },
          "action": {
            "type": "string"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "search": {
            "type": "string",
            "description": "Extra search words, including the English screen name."
          },
          "page": {
            "type": "string",
            "description": "Absolute address for people: the store product page when the tool is sold in the store, otherwise href."
          },
          "storeId": {
            "type": "string",
            "description": "Id of the same tool in /api/store, when it is a store product."
          },
          "agent": {
            "$ref": "#/components/schemas/AgentUse"
          }
        }
      },
      "AgentUse": {
        "type": "object",
        "required": ["mode", "meaning", "how", "docs"],
        "description": "How a connected agent reaches an item. It never means the agent may act on the user's behalf beyond what the user allowed.",
        "properties": {
          "mode": {
            "type": "string",
            "enum": ["read", "mcp", "api", "person", "external"],
            "description": "read: public material an agent reads without signing in. mcp: runs through the Metheus MCP connected to the user's desktop app and CAD. api: needs the user's account token and permission. person: only people use it on screen; no agent path. external: a tool outside Metheus installed separately."
          },
          "meaning": {
            "type": "string",
            "description": "Korean explanation of mode."
          },
          "how": {
            "type": "string",
            "description": "Korean instruction for using the item, including its limits."
          },
          "docs": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Absolute addresses to read before using it."
          }
        }
      },
      "StoreItem": {
        "type": "object",
        "required": ["id", "name", "summary", "price", "page", "agent"],
        "properties": {
          "id": {"type": "string"},
          "name": {"type": "string"},
          "category": {
            "type": ["object", "null"],
            "properties": {
              "id": {"type": "string", "enum": ["tools", "assets", "knowledge", "fabrication", "parts"]},
              "name": {"type": "string"}
            }
          },
          "kind": {"type": "string", "description": "Product kind label shown on its card."},
          "provider": {"type": "string"},
          "summary": {"type": "string"},
          "price": {"type": "string", "description": "Price or status as shown in the store. Token prices are provider reference prices, not Metheus prices."},
          "needs": {"type": "string"},
          "availability": {"type": "string"},
          "note": {"type": "string"},
          "page": {"type": "string", "description": "Absolute address of the product page."},
          "toolId": {"type": "string", "description": "Id in /api/design-tools when the product is a design tool."},
          "links": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {"label": {"type": "string"}, "url": {"type": "string"}}
            }
          },
          "agent": {
            "$ref": "#/components/schemas/AgentUse"
          }
        }
      },
      "Supplier": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "kind": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          },
          "processes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "materials": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "materialsNote": {
            "type": "string"
          },
          "inputRequirements": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "fileFormats": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "fileFormatsNote": {
            "type": "string"
          },
          "quoteMethod": {
            "type": "string"
          },
          "website": {
            "type": "string",
            "format": "uri"
          },
          "quoteUrl": {
            "type": "string",
            "format": "uri"
          },
          "sourceUrls": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Source"
            }
          },
          "verifiedAt": {
            "type": "string",
            "format": "date"
          },
          "relationship": {
            "type": "string",
            "const": "directory_listing"
          },
          "integrationStatus": {
            "type": "string",
            "const": "external_website"
          },
          "price": {
            "type": "null",
            "description": "Unknown. Null is not zero, free service, or a validated quote."
          },
          "leadTime": {
            "type": "null",
            "description": "Unknown. Check the provider's actual quote."
          },
          "ctaLabel": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "kind",
          "summary",
          "processes",
          "materials",
          "materialsNote",
          "inputRequirements",
          "fileFormats",
          "quoteMethod",
          "website",
          "quoteUrl",
          "sourceUrls",
          "verifiedAt",
          "relationship",
          "integrationStatus",
          "price",
          "leadTime",
          "ctaLabel"
        ]
      },
      "PostSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Server-issued identifier.",
            "format": "uuid"
          },
          "author_name": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "excerpt": {
            "type": "string",
            "description": "First 180 characters of the body."
          },
          "category": {
            "type": "string",
            "description": "One of categories returned by /api/config."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "comment_count": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "making": {
            "$ref": "#/components/schemas/MakingState",
            "description": "Present only on 공동제작 (shown as 수요 조사 · Interest check) posts."
          }
        },
        "required": [
          "id",
          "author_name",
          "title",
          "excerpt",
          "category",
          "created_at",
          "comment_count"
        ]
      },
      "Comment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Server-issued identifier.",
            "format": "uuid"
          },
          "author_name": {
            "type": "string"
          },
          "body": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "operation_id": {
            "type": "string",
            "format": "uuid",
            "description": "Present for creation with operation_id."
          },
          "reused": {
            "type": "boolean",
            "description": "Present for creation with operation_id. True for an exact retry."
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "parent_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "reply_to_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "owned": {
            "type": "boolean"
          },
          "deleted": {
            "type": "boolean"
          },
          "is_post_author": {
            "type": "boolean"
          },
          "example": {
            "type": "boolean"
          },
          "replies": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Comment"
            },
            "description": "Present on root threads only."
          },
          "reply_count": {
            "type": "integer",
            "minimum": 0,
            "description": "Number of live replies in the root thread."
          },
          "reply_offset": {
            "type": "integer",
            "minimum": 0,
            "description": "Offset of the included replies; may be nonzero with focus."
          }
        },
        "required": [
          "id",
          "author_name",
          "body",
          "created_at",
          "updated_at",
          "parent_id",
          "reply_to_name",
          "owned",
          "deleted",
          "is_post_author",
          "example"
        ]
      },
      "Post": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Server-issued identifier.",
            "format": "uuid"
          },
          "author_name": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "body": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "owned": {
            "type": "boolean",
            "description": "False for anonymous reads; true only for the authenticated author."
          },
          "comments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Comment"
            }
          },
          "making": {
            "$ref": "#/components/schemas/MakingState",
            "description": "Present only on 공동제작 (shown as 수요 조사 · Interest check) posts."
          }
        },
        "required": [
          "id",
          "author_name",
          "title",
          "body",
          "category",
          "created_at",
          "updated_at",
          "owned",
          "comments"
        ]
      },
      "PostsPage": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PostSummary"
            }
          },
          "total": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "offset": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100000
          }
        },
        "required": [
          "items",
          "total",
          "offset"
        ]
      },
      "Config": {
        "type": "object",
        "properties": {
        "credits": {"$ref": "#/components/schemas/CreditPolicy"},
          "gateway": {
            "type": "string",
            "format": "uri"
          },
          "bff": {
            "type": "string",
            "format": "uri"
          },
          "basePath": {
            "type": "string"
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "gateway",
          "bff",
          "basePath",
          "categories"
        ]
      },
      "Organization": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "personal",
              "team"
            ]
          },
          "name": {
            "type": "string"
          },
          "role": {
            "type": "string",
            "enum": [
              "owner",
              "admin",
              "member"
            ]
          }
        },
        "required": [
          "id",
          "kind",
          "role"
        ]
      },
      "CommerceContext": {
        "type": "object",
        "properties": {
          "organizations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Organization"
            }
          },
          "attachments_available": {
            "type": "boolean"
          },
          "design_bundle_supported": {
            "type": "boolean"
          },
          "design_bundle_limits": {
            "type": "object",
            "properties": {
              "header_bytes": {
                "type": "integer",
                "const": 65536
              },
              "file_bytes": {
                "type": "integer",
                "const": 20971520
              },
              "body_bytes": {
                "type": "integer",
                "const": 42008580
              },
              "active_files": {
                "type": "integer",
                "const": 10
              },
              "total_files": {
                "type": "integer",
                "const": 100
              }
            }
          }
        },
        "required": [
          "organizations",
          "attachments_available",
          "design_bundle_supported",
          "design_bundle_limits"
        ]
      },
      "RequestInput": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "minLength": 2,
            "maxLength": 120
          },
          "goal": {
            "type": "string",
            "minLength": 10,
            "maxLength": 8000
          },
          "process": {
            "type": "string",
            "minLength": 2,
            "maxLength": 100
          },
          "material": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "quantity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000
          },
          "budget_krw": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "maximum": 1000000000000,
            "description": "Target budget, not a quoted or enforced price. State whether it is per-unit or total in goal/notes."
          },
          "notes": {
            "type": "string",
            "maxLength": 3000,
            "default": ""
          }
        },
        "required": [
          "title",
          "goal",
          "process",
          "material",
          "quantity"
        ]
      },
      "RequestUpdate": {
        "type": "object",
        "description": "PATCH replaces all required editable fields; it is not a sparse partial update.",
        "properties": {
          "title": {
            "type": "string",
            "minLength": 2,
            "maxLength": 120
          },
          "goal": {
            "type": "string",
            "minLength": 10,
            "maxLength": 8000
          },
          "process": {
            "type": "string",
            "minLength": 2,
            "maxLength": 100
          },
          "material": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "quantity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000
          },
          "budget_krw": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "maximum": 1000000000000,
            "description": "Target budget, not a quoted or enforced price. State whether it is per-unit or total in goal/notes."
          },
          "notes": {
            "type": "string",
            "maxLength": 3000,
            "default": ""
          },
          "revision": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "Current revision returned by the server. A stale value causes 409."
          }
        },
        "required": [
          "title",
          "goal",
          "process",
          "material",
          "quantity",
          "revision"
        ]
      },
      "RequestSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Server-issued identifier.",
            "format": "uuid"
          },
          "revision": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "Current revision returned by the server. A stale value causes 409."
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "closed",
              "order_requested"
            ]
          },
          "title": {
            "type": "string",
            "minLength": 2,
            "maxLength": 120
          },
          "goal": {
            "type": "string",
            "minLength": 10,
            "maxLength": 8000
          },
          "process": {
            "type": "string",
            "minLength": 2,
            "maxLength": 100
          },
          "material": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "quantity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000
          },
          "budget_krw": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "maximum": 1000000000000,
            "description": "Target budget, not a quoted or enforced price. State whether it is per-unit or total in goal/notes."
          },
          "notes": {
            "type": "string",
            "maxLength": 3000,
            "default": ""
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "file_count": {
            "type": "integer",
            "minimum": 0,
            "description": "Stored files for this request, including earlier design revisions and removed files kept for the record."
          },
          "file_bytes": {
            "type": "integer",
            "minimum": 0,
            "description": "Total stored bytes of those files."
          }
        },
        "required": [
          "id",
          "revision",
          "status",
          "title",
          "goal",
          "process",
          "material",
          "quantity",
          "budget_krw",
          "notes",
          "created_at",
          "updated_at"
        ]
      },
      "File": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Server-issued identifier.",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "bytes": {
            "type": "integer",
            "minimum": 1,
            "maximum": 20971520
          },
          "sha256": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "bytes",
          "sha256",
          "created_at"
        ]
      },
      "InviteSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Server-issued identifier.",
            "format": "uuid"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "revoked": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1,
            "description": "SQLite boolean: 0 active, 1 revoked."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "expires_at",
          "revoked",
          "created_at"
        ]
      },
      "Request": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Server-issued identifier.",
            "format": "uuid"
          },
          "revision": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "Current revision returned by the server. A stale value causes 409."
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "closed",
              "order_requested"
            ]
          },
          "title": {
            "type": "string",
            "minLength": 2,
            "maxLength": 120
          },
          "goal": {
            "type": "string",
            "minLength": 10,
            "maxLength": 8000
          },
          "process": {
            "type": "string",
            "minLength": 2,
            "maxLength": 100
          },
          "material": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "quantity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000
          },
          "budget_krw": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "maximum": 1000000000000,
            "description": "Target budget, not a quoted or enforced price. State whether it is per-unit or total in goal/notes."
          },
          "notes": {
            "type": "string",
            "maxLength": 3000,
            "default": ""
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "role": {
            "type": "string",
            "enum": [
              "buyer",
              "supplier"
            ]
          },
          "offers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Offer"
            }
          },
          "files": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/File"
            },
            "description": "Current design report/BOM and ordinary attachments only. Prior design bundles are in design_history."
          },
          "order_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Server-issued identifier.",
            "format": "uuid"
          },
          "invites": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InviteSummary"
            }
          },
          "source_order_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Buyer organization response only: the declined/cancelled order used to prepare this request, or null. Omitted for supplier and anonymous invitation views. Not a field clients may set."
          },
          "current_design": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ManufacturingDesign"
              },
              {
                "type": "null"
              }
            ]
          },
          "design_history": {
            "type": "array",
            "description": "Previous design bundles, newest first; excludes current_design. Historical files remain private and are excluded from new order snapshots.",
            "items": {
              "$ref": "#/components/schemas/ManufacturingDesign"
            }
          },
          "removed_files": {
            "type": "array",
            "description": "Buyer-only excluded general attachment history. These files are absent from new snapshots.",
            "items": {
              "type": "object"
            }
          },
          "events": {
            "type": "array",
            "description": "Lifecycle records visible to this transaction party.",
            "items": {
              "type": "object"
            }
          }
        },
        "required": [
          "id",
          "revision",
          "status",
          "title",
          "goal",
          "process",
          "material",
          "quantity",
          "budget_krw",
          "notes",
          "created_at",
          "updated_at",
          "role",
          "offers",
          "files",
          "order_id",
          "invites",
          "current_design",
          "design_history"
        ]
      },
      "InviteRequest": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Server-issued identifier.",
            "format": "uuid"
          },
          "revision": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "Current revision returned by the server. A stale value causes 409."
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "closed",
              "order_requested"
            ]
          },
          "title": {
            "type": "string",
            "minLength": 2,
            "maxLength": 120
          },
          "goal": {
            "type": "string",
            "minLength": 10,
            "maxLength": 8000
          },
          "process": {
            "type": "string",
            "minLength": 2,
            "maxLength": 100
          },
          "material": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "quantity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000
          },
          "budget_krw": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "maximum": 1000000000000,
            "description": "Target budget, not a quoted or enforced price. State whether it is per-unit or total in goal/notes."
          },
          "notes": {
            "type": "string",
            "maxLength": 3000,
            "default": ""
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "files": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/File"
            },
            "description": "Current design report/BOM and ordinary attachments only. Prior design bundles are in design_history."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "current_design": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ManufacturingDesign"
              },
              {
                "type": "null"
              }
            ]
          },
          "design_history": {
            "type": "array",
            "description": "Previous design bundles, newest first; excludes current_design. Historical files remain private and are excluded from new order snapshots.",
            "items": {
              "$ref": "#/components/schemas/ManufacturingDesign"
            }
          }
        },
        "required": [
          "id",
          "revision",
          "status",
          "title",
          "goal",
          "process",
          "material",
          "quantity",
          "budget_krw",
          "notes",
          "created_at",
          "updated_at",
          "files",
          "expires_at",
          "current_design",
          "design_history"
        ]
      },
      "InviteInput": {
        "type": "object",
        "properties": {
          "revision": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "Current revision returned by the server. A stale value causes 409."
          },
          "expires_in_days": {
            "type": "integer",
            "minimum": 1,
            "maximum": 30,
            "default": 7
          }
        },
        "required": [
          "revision"
        ]
      },
      "InviteCreated": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Server-issued identifier.",
            "format": "uuid"
          },
          "token": {
            "type": "string",
            "description": "Capability secret shown only on creation. Do not publish, log, or send to unauthorized recipients.",
            "pattern": "^[A-Za-z0-9_-]{43}$"
          },
          "request_id": {
            "type": "string",
            "description": "Server-issued identifier.",
            "format": "uuid"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "token",
          "request_id",
          "expires_at"
        ]
      },
      "OfferInput": {
        "type": "object",
        "properties": {
          "supplier_name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 100
          },
          "quantity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000
          },
          "unit_price_krw": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000000
          },
          "shipping_krw": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1000000000
          },
          "tax_krw": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100000000000
          },
          "lead_days": {
            "type": "integer",
            "minimum": 1,
            "maximum": 730
          },
          "valid_until": {
            "type": "string",
            "description": "YYYY-MM-DD; expires at 23:59:59.999 UTC. Must be in the future and no more than 366 days ahead.",
            "format": "date"
          },
          "terms": {
            "type": "string",
            "minLength": 5,
            "maxLength": 5000
          },
          "request_revision": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "Current revision returned by the server. A stale value causes 409."
          }
        },
        "required": [
          "supplier_name",
          "quantity",
          "unit_price_krw",
          "shipping_krw",
          "tax_krw",
          "lead_days",
          "valid_until",
          "terms",
          "request_revision"
        ]
      },
      "OfferUpdate": {
        "type": "object",
        "properties": {
          "supplier_name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 100
          },
          "quantity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000
          },
          "unit_price_krw": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000000
          },
          "shipping_krw": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1000000000
          },
          "tax_krw": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100000000000
          },
          "lead_days": {
            "type": "integer",
            "minimum": 1,
            "maximum": 730
          },
          "valid_until": {
            "type": "string",
            "description": "YYYY-MM-DD; expires at 23:59:59.999 UTC. Must be in the future and no more than 366 days ahead.",
            "format": "date"
          },
          "terms": {
            "type": "string",
            "minLength": 5,
            "maxLength": 5000
          },
          "request_revision": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "Current revision returned by the server. A stale value causes 409."
          },
          "revision": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "Current revision returned by the server. A stale value causes 409."
          }
        },
        "required": [
          "supplier_name",
          "quantity",
          "unit_price_krw",
          "shipping_krw",
          "tax_krw",
          "lead_days",
          "valid_until",
          "terms",
          "request_revision",
          "revision"
        ]
      },
      "Offer": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Server-issued identifier.",
            "format": "uuid"
          },
          "request_id": {
            "type": "string",
            "description": "Server-issued identifier.",
            "format": "uuid"
          },
          "revision": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "Current revision returned by the server. A stale value causes 409."
          },
          "request_revision": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "Current revision returned by the server. A stale value causes 409."
          },
          "supplier_name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 100
          },
          "quantity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000
          },
          "unit_price_krw": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000000
          },
          "shipping_krw": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1000000000
          },
          "tax_krw": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100000000000
          },
          "lead_days": {
            "type": "integer",
            "minimum": 1,
            "maximum": 730
          },
          "valid_until": {
            "type": "string",
            "description": "YYYY-MM-DD; expires at 23:59:59.999 UTC. Must be in the future and no more than 366 days ahead.",
            "format": "date"
          },
          "terms": {
            "type": "string",
            "minLength": 5,
            "maxLength": 5000
          },
          "currency": {
            "type": "string",
            "description": "Server fixed currency.",
            "const": "KRW",
            "readOnly": true
          },
          "total_krw": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000000000,
            "description": "Computed as quantity × unit_price_krw + shipping_krw + tax_krw.",
            "readOnly": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "withdrawn"
            ]
          },
          "withdrawn_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "request_id",
          "revision",
          "request_revision",
          "supplier_name",
          "quantity",
          "unit_price_krw",
          "shipping_krw",
          "tax_krw",
          "lead_days",
          "valid_until",
          "terms",
          "currency",
          "total_krw",
          "created_at",
          "updated_at"
        ]
      },
      "OfferListItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Server-issued identifier.",
            "format": "uuid"
          },
          "request_id": {
            "type": "string",
            "description": "Server-issued identifier.",
            "format": "uuid"
          },
          "revision": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "Current revision returned by the server. A stale value causes 409."
          },
          "request_revision": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "Current revision returned by the server. A stale value causes 409."
          },
          "supplier_name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 100
          },
          "quantity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000
          },
          "unit_price_krw": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000000
          },
          "shipping_krw": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1000000000
          },
          "tax_krw": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100000000000
          },
          "lead_days": {
            "type": "integer",
            "minimum": 1,
            "maximum": 730
          },
          "valid_until": {
            "type": "string",
            "description": "YYYY-MM-DD; expires at 23:59:59.999 UTC. Must be in the future and no more than 366 days ahead.",
            "format": "date"
          },
          "terms": {
            "type": "string",
            "minLength": 5,
            "maxLength": 5000
          },
          "currency": {
            "type": "string",
            "description": "Server fixed currency.",
            "const": "KRW",
            "readOnly": true
          },
          "total_krw": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000000000,
            "description": "Computed as quantity × unit_price_krw + shipping_krw + tax_krw.",
            "readOnly": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "request_title": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "withdrawn"
            ]
          },
          "withdrawn_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "request_id",
          "revision",
          "request_revision",
          "supplier_name",
          "quantity",
          "unit_price_krw",
          "shipping_krw",
          "tax_krw",
          "lead_days",
          "valid_until",
          "terms",
          "currency",
          "total_krw",
          "created_at",
          "updated_at",
          "request_title"
        ]
      },
      "Delivery": {
        "type": "object",
        "properties": {
          "recipient": {
            "type": "string",
            "minLength": 2,
            "maxLength": 100
          },
          "phone": {
            "type": "string",
            "minLength": 5,
            "maxLength": 40,
            "pattern": "^[+0-9 ()-]+$"
          },
          "postal_code": {
            "type": "string",
            "minLength": 0,
            "maxLength": 20
          },
          "address": {
            "type": "string",
            "minLength": 0,
            "maxLength": 300
          },
          "address_detail": {
            "type": "string",
            "maxLength": 200,
            "default": ""
          },
          "mode": {
            "type": "string",
            "enum": [
              "carrier",
              "supplier_delivery",
              "pickup"
            ],
            "default": "carrier"
          }
        },
        "required": [
          "recipient",
          "phone"
        ],
        "allOf": [
          {
            "if": {
              "properties": {
                "mode": {
                  "const": "pickup"
                }
              },
              "required": [
                "mode"
              ]
            },
            "else": {
              "required": [
                "postal_code",
                "address"
              ],
              "properties": {
                "postal_code": {
                  "minLength": 3
                },
                "address": {
                  "minLength": 5
                }
              }
            }
          }
        ]
      },
      "AcceptOfferInput": {
        "type": "object",
        "description": "Creates a real order request and shares delivery details with the selected supplier. Obtain explicit user approval of the exact quote/revisions/delivery before calling.",
        "properties": {
          "offer_id": {
            "type": "string",
            "description": "Server-issued identifier.",
            "format": "uuid"
          },
          "offer_revision": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "Current revision returned by the server. A stale value causes 409."
          },
          "request_revision": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "Current revision returned by the server. A stale value causes 409."
          },
          "delivery": {
            "$ref": "#/components/schemas/Delivery"
          }
        },
        "required": [
          "offer_id",
          "offer_revision",
          "request_revision",
          "delivery"
        ]
      },
      "Shipping": {
        "type": "object",
        "properties": {
          "carrier": {
            "type": "string"
          },
          "tracking_number": {
            "type": "string"
          },
          "tracking_url": {
            "type": "string",
            "format": "uri"
          },
          "source": {
            "type": "string",
            "const": "supplier_entered"
          },
          "shipped_at": {
            "type": "string",
            "format": "date-time"
          },
          "corrected_at": {
            "type": "string",
            "format": "date-time",
            "description": "Time of the latest supplier-entered correction. Optional; the original shipped_at is preserved."
          },
          "mode": {
            "type": "string",
            "enum": [
              "carrier",
              "supplier_delivery",
              "pickup"
            ],
            "default": "carrier"
          },
          "handoff_note": {
            "type": "string",
            "minLength": 3,
            "maxLength": 1000
          }
        },
        "required": [
          "source",
          "shipped_at"
        ],
        "allOf": [
          {
            "if": {
              "properties": {
                "mode": {
                  "enum": [
                    "supplier_delivery",
                    "pickup"
                  ]
                }
              },
              "required": [
                "mode"
              ]
            },
            "then": {
              "required": [
                "handoff_note"
              ]
            },
            "else": {
              "required": [
                "carrier",
                "tracking_number",
                "tracking_url"
              ]
            }
          }
        ]
      },
      "OrderSnapshot": {
        "type": "object",
        "properties": {
          "request": {
            "$ref": "#/components/schemas/RequestSummary"
          },
          "files": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/File"
            }
          },
          "offer": {
            "type": "object",
            "properties": {
              "supplier_name": {
                "type": "string",
                "minLength": 2,
                "maxLength": 100
              },
              "quantity": {
                "type": "integer",
                "minimum": 1,
                "maximum": 1000000
              },
              "unit_price_krw": {
                "type": "integer",
                "minimum": 1,
                "maximum": 1000000000
              },
              "shipping_krw": {
                "type": "integer",
                "minimum": 0,
                "maximum": 1000000000
              },
              "tax_krw": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100000000000
              },
              "lead_days": {
                "type": "integer",
                "minimum": 1,
                "maximum": 730
              },
              "valid_until": {
                "type": "string",
                "description": "YYYY-MM-DD; expires at 23:59:59.999 UTC. Must be in the future and no more than 366 days ahead.",
                "format": "date"
              },
              "terms": {
                "type": "string",
                "minLength": 5,
                "maxLength": 5000
              },
              "currency": {
                "type": "string",
                "const": "KRW"
              },
              "total_krw": {
                "type": "integer",
                "minimum": 1,
                "maximum": 1000000000000
              }
            },
            "required": [
              "supplier_name",
              "quantity",
              "unit_price_krw",
              "shipping_krw",
              "tax_krw",
              "lead_days",
              "valid_until",
              "terms",
              "currency",
              "total_krw"
            ]
          },
          "delivery": {
            "$ref": "#/components/schemas/Delivery"
          },
          "offer_revision": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "Current revision returned by the server. A stale value causes 409."
          },
          "request_revision": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "Current revision returned by the server. A stale value causes 409."
          },
          "current_design": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ManufacturingDesign"
              },
              {
                "type": "null"
              }
            ],
            "description": "Design bundle frozen with this order, when available. Legacy orders may omit this field."
          }
        },
        "required": [
          "request",
          "files",
          "offer",
          "delivery",
          "offer_revision",
          "request_revision"
        ]
      },
      "OrderEvent": {
        "type": "object",
        "properties": {
          "action": {
            "type": "string",
            "enum": [
              "order_requested",
              "confirm",
              "decline",
              "start_production",
              "ship",
              "receive",
              "request_cancel",
              "accept_cancel",
              "reject_cancel",
              "correct_shipping"
            ]
          },
          "note": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "details": {
            "$ref": "#/components/schemas/ShippingCorrectionDetails",
            "description": "Present for correct_shipping events; legacy events can omit this field."
          }
        },
        "required": [
          "action",
          "note",
          "created_at"
        ]
      },
      "Order": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Server-issued identifier.",
            "format": "uuid"
          },
          "request_id": {
            "type": "string",
            "description": "Server-issued identifier.",
            "format": "uuid"
          },
          "offer_id": {
            "type": "string",
            "description": "Server-issued identifier.",
            "format": "uuid"
          },
          "revision": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "Current revision returned by the server. A stale value causes 409."
          },
          "status": {
            "type": "string",
            "enum": [
              "order_requested",
              "accepted",
              "declined",
              "production",
              "shipped",
              "received",
              "cancelled"
            ]
          },
          "cancel_requested": {
            "type": "boolean"
          },
          "cancel_reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "snapshot": {
            "$ref": "#/components/schemas/OrderSnapshot"
          },
          "shipping": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Shipping"
              },
              {
                "type": "null"
              }
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "role": {
            "type": "string",
            "enum": [
              "buyer",
              "supplier",
              "admin"
            ]
          },
          "seller": {
            "type": "string",
            "enum": [
              "partner",
              "metheus"
            ],
            "description": "partner: the buyer pays the supplier directly. metheus: Metheus is the seller and the order is paid on this site."
          },
          "payment_status": {
            "type": "string",
            "enum": [
              "external_arrangement",
              "awaiting_confirmation",
              "awaiting_payment",
              "paid",
              "refund_pending",
              "refunded",
              "partially_refunded",
              "not_required"
            ],
            "description": "external_arrangement for partner orders; never infer paid, refunded, escrowed, or guaranteed from it. The other values apply only to seller=metheus orders."
          },
          "paid_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "seller=metheus only."
          },
          "payment": {
            "type": [
              "object",
              "null"
            ],
            "description": "seller=metheus only: the latest site payment.",
            "properties": {
              "amount": {
                "type": "integer"
              },
              "status": {
                "type": "string"
              },
              "method": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "easy_pay": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "receipt_url": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "canceled_amount": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "approved_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              }
            }
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrderEvent"
            }
          },
          "requote_request_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Buyer organization response only: the one follow-up request prepared from this order, or null. Omitted for supplier/admin views. Creating a follow-up never changes the fixed order snapshot."
          }
        },
        "required": [
          "id",
          "request_id",
          "offer_id",
          "revision",
          "status",
          "cancel_requested",
          "cancel_reason",
          "snapshot",
          "shipping",
          "created_at",
          "updated_at",
          "role",
          "payment_status",
          "events"
        ]
      },
      "OrderAction": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "action": {
                "type": "string",
                "enum": [
                  "confirm",
                  "decline",
                  "start_production",
                  "receive",
                  "accept_cancel",
                  "reject_cancel"
                ]
              },
              "revision": {
                "type": "integer",
                "minimum": 1,
                "maximum": 9007199254740991,
                "description": "Current revision returned by the server. A stale value causes 409."
              },
              "note": {
                "type": "string",
                "maxLength": 1000,
                "default": ""
              }
            },
            "required": [
              "action",
              "revision"
            ]
          },
          {
            "type": "object",
            "properties": {
              "action": {
                "type": "string",
                "const": "request_cancel"
              },
              "revision": {
                "type": "integer",
                "minimum": 1,
                "maximum": 9007199254740991,
                "description": "Current revision returned by the server. A stale value causes 409."
              },
              "reason": {
                "type": "string",
                "minLength": 3,
                "maxLength": 1000
              },
              "note": {
                "type": "string",
                "maxLength": 1000
              }
            },
            "required": [
              "action",
              "revision",
              "reason"
            ]
          },
          {
            "type": "object",
            "properties": {
              "action": {
                "type": "string",
                "const": "ship"
              },
              "revision": {
                "type": "integer",
                "minimum": 1,
                "maximum": 9007199254740991,
                "description": "Current revision returned by the server. A stale value causes 409."
              },
              "carrier": {
                "type": "string",
                "minLength": 2,
                "maxLength": 80
              },
              "tracking_number": {
                "type": "string",
                "minLength": 3,
                "maxLength": 120
              },
              "tracking_url": {
                "type": "string",
                "description": "HTTPS URL without embedded username/password. Supplier entered, not carrier verified.",
                "format": "uri",
                "pattern": "^https://",
                "minLength": 8,
                "maxLength": 2048
              },
              "note": {
                "type": "string",
                "maxLength": 1000
              },
              "mode": {
                "type": "string",
                "enum": [
                  "carrier",
                  "supplier_delivery",
                  "pickup"
                ],
                "default": "carrier"
              },
              "handoff_note": {
                "type": "string",
                "minLength": 3,
                "maxLength": 1000
              }
            },
            "required": [
              "action",
              "revision"
            ],
            "allOf": [
              {
                "if": {
                  "properties": {
                    "mode": {
                      "enum": [
                        "supplier_delivery",
                        "pickup"
                      ]
                    }
                  },
                  "required": [
                    "mode"
                  ]
                },
                "then": {
                  "required": [
                    "handoff_note"
                  ]
                },
                "else": {
                  "required": [
                    "carrier",
                    "tracking_number",
                    "tracking_url"
                  ]
                }
              }
            ],
            "description": "Supplier registers actual carrier shipment, direct delivery or pickup instructions. Buyer confirms receipt separately. Corrections require a reason and preserve the original timestamp and before/after history."
          },
          {
            "type": "object",
            "properties": {
              "action": {
                "type": "string",
                "const": "correct_shipping"
              },
              "revision": {
                "type": "integer",
                "minimum": 1,
                "maximum": 9007199254740991,
                "description": "Current revision returned by the server. A stale value causes 409."
              },
              "carrier": {
                "type": "string",
                "minLength": 2,
                "maxLength": 80
              },
              "tracking_number": {
                "type": "string",
                "minLength": 3,
                "maxLength": 120
              },
              "tracking_url": {
                "type": "string",
                "description": "HTTPS URL without embedded username/password. Supplier entered, not carrier verified.",
                "format": "uri",
                "pattern": "^https://",
                "maxLength": 2048,
                "minLength": 8
              },
              "reason": {
                "type": "string",
                "minLength": 3,
                "maxLength": 1000,
                "description": "User-approved reason for changing the registered shipping details."
              },
              "mode": {
                "type": "string",
                "enum": [
                  "carrier",
                  "supplier_delivery",
                  "pickup"
                ],
                "default": "carrier"
              },
              "handoff_note": {
                "type": "string",
                "minLength": 3,
                "maxLength": 1000
              }
            },
            "required": [
              "action",
              "revision",
              "reason"
            ],
            "description": "Supplier registers actual carrier shipment, direct delivery or pickup instructions. Buyer confirms receipt separately. Corrections require a reason and preserve the original timestamp and before/after history.",
            "allOf": [
              {
                "if": {
                  "properties": {
                    "mode": {
                      "enum": [
                        "supplier_delivery",
                        "pickup"
                      ]
                    }
                  },
                  "required": [
                    "mode"
                  ]
                },
                "then": {
                  "required": [
                    "handoff_note"
                  ]
                },
                "else": {
                  "required": [
                    "carrier",
                    "tracking_number",
                    "tracking_url"
                  ]
                }
              }
            ]
          }
        ]
      },
      "UploadResult": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Server-issued identifier.",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "bytes": {
            "type": "integer",
            "minimum": 1,
            "maximum": 20971520
          },
          "sha256": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$"
          },
          "request_revision": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "Current revision returned by the server. A stale value causes 409."
          }
        },
        "required": [
          "id",
          "name",
          "bytes",
          "sha256",
          "request_revision"
        ]
      },
      "ShippingCorrectionDetails": {
        "type": "object",
        "description": "Immutable before/after record for a supplier shipping correction. Order event note is the required correction reason.",
        "properties": {
          "previous": {
            "$ref": "#/components/schemas/Shipping"
          },
          "current": {
            "$ref": "#/components/schemas/Shipping"
          }
        },
        "required": [
          "previous",
          "current"
        ]
      },
      "RequoteInput": {
        "allOf": [
          {
            "$ref": "#/components/schemas/RequestInput"
          },
          {
            "type": "object",
            "properties": {
              "revision": {
                "type": "integer",
                "minimum": 1,
                "maximum": 9007199254740991,
                "description": "Current source ORDER revision, not its request revision."
              },
              "file_ids": {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "uuid"
                },
                "maxItems": 10,
                "uniqueItems": true,
                "description": "Explicitly selected IDs from the source order snapshot.files. Empty is allowed. No paths, URLs or unrelated files."
              }
            },
            "required": [
              "revision",
              "file_ids"
            ]
          }
        ],
        "description": "Complete user-confirmed editable request fields plus source order revision and selected snapshot file IDs. Buyer organization of a declined/cancelled order only. Owner/org/source identity and copied file metadata are server owned."
      },
      "RequoteResult": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Request"
          },
          {
            "type": "object",
            "properties": {
              "reused": {
                "type": "boolean",
                "description": "False for first creation; true when returning the one existing follow-up without overwriting its current fields/files."
              }
            },
            "required": [
              "reused"
            ]
          }
        ]
      },
      "PersonalProjectFile": {
        "type": "object",
        "required": [
          "name",
          "sha256",
          "size"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "sha256": {
            "type": "string",
            "pattern": "^[a-fA-F0-9]{64}$"
          },
          "size": {
            "type": "integer",
            "minimum": 0,
            "maximum": 52428800
          },
          "modified_at": {
            "type": "number",
            "description": "Unix timestamp in seconds."
          }
        }
      },
      "PersonalProject": {
        "type": "object",
        "required": [
          "id",
          "revision",
          "files"
        ],
        "description": "Existing company broker personal project. Organization selection does not enable team sharing. Revision covers files and memory, not CAD.",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "revision": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991
          },
          "files": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PersonalProjectFile"
            }
          },
          "created_at": {
            "type": "number",
            "description": "Unix timestamp in seconds."
          },
          "updated_at": {
            "type": "number",
            "description": "Unix timestamp in seconds."
          },
          "archived_at": {
            "type": [
              "number",
              "null"
            ],
            "description": "Unix timestamp in seconds."
          }
        }
      },
      "ManufacturingDesign": {
        "type": "object",
        "description": "Files saved together for one manufacturing revision. Source hash identifies original report bytes, not a CAD revision or approval.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "source_sha256": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$"
          },
          "request_revision": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "Current revision returned by the server. A stale value causes 409."
          },
          "files": {
            "type": "array",
            "minItems": 2,
            "maxItems": 2,
            "items": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/File"
                },
                {
                  "type": "object",
                  "properties": {
                    "role": {
                      "type": "string",
                      "enum": [
                        "report",
                        "bom"
                      ]
                    }
                  },
                  "required": [
                    "role"
                  ]
                }
              ]
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "source_sha256",
          "request_revision",
          "files",
          "created_at"
        ]
      },
      "ManufacturingBundleHeader": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "minLength": 2,
            "maxLength": 120
          },
          "goal": {
            "type": "string",
            "minLength": 10,
            "maxLength": 8000
          },
          "process": {
            "type": "string",
            "minLength": 2,
            "maxLength": 100
          },
          "material": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "quantity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000
          },
          "budget_krw": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "maximum": 1000000000000,
            "description": "Target budget, not a quoted or enforced price. State whether it is per-unit or total in goal/notes."
          },
          "notes": {
            "type": "string",
            "maxLength": 3000,
            "default": ""
          },
          "operation_id": {
            "type": "string",
            "format": "uuid",
            "description": "UUID v4, stable for retries of the same exact target and bytes. Scoped to verified account and organization."
          },
          "source_sha256": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$"
          },
          "revision": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "Current revision returned by the server. A stale value causes 409."
          },
          "files": {
            "type": "array",
            "minItems": 2,
            "maxItems": 2,
            "description": "Exactly report then bom. Report SHA must equal source_sha256. Files are opaque, not executed or approved.",
            "items": {
              "type": "object",
              "properties": {
                "role": {
                  "type": "string",
                  "enum": [
                    "report",
                    "bom"
                  ]
                },
                "name": {
                  "type": "string",
                  "maxLength": 180
                },
                "bytes": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 20971520
                },
                "sha256": {
                  "type": "string",
                  "pattern": "^[a-f0-9]{64}$"
                }
              },
              "required": [
                "role",
                "name",
                "bytes",
                "sha256"
              ]
            }
          }
        },
        "required": [
          "title",
          "goal",
          "process",
          "material",
          "quantity",
          "operation_id",
          "source_sha256",
          "files"
        ]
      },
      "PostCreate": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "minLength": 2,
            "maxLength": 120
          },
          "body": {
            "type": "string",
            "minLength": 0,
            "maxLength": 12000
          },
          "author_name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 32
          },
          "category": {
            "type": "string",
            "description": "One of categories returned by /api/config."
          },
          "images": {
            "type": "array",
            "maxItems": 6,
            "description": "Already uploaded photo IDs in display order. Omit on edit to retain attachments; send the remaining list to remove photos.",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "alt": {
                  "type": "string",
                  "maxLength": 200
                }
              },
              "required": [
                "id",
                "alt"
              ]
            }
          },
          "operation_id": {
            "type": "string",
            "format": "uuid",
            "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[89abAB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$",
            "description": "Optional UUID v4. Retain it and the exact input when retrying an uncertain creation; omit only for legacy behavior without duplicate protection."
          },
          "making": {
            "$ref": "#/components/schemas/MakingSpec",
            "description": "Required when creating a 공동제작 post. Omit on edit to retain specifications. Edits require the current post expected_updated_at and remain available after participation or closing. Actual changes create a new specification revision and move existing quantities to pending confirmation."
          }
        },
        "required": [
          "title",
          "body",
          "author_name",
          "category"
        ],
        "allOf": [
          {
            "if": {
              "properties": {
                "category": {
                  "const": "공동제작"
                }
              },
              "required": [
                "category"
              ]
            },
            "then": {
              "required": [
                "making"
              ]
            }
          }
        ]
      },
      "PostEdit": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "minLength": 2,
            "maxLength": 120
          },
          "body": {
            "type": "string",
            "minLength": 0,
            "maxLength": 12000
          },
          "images": {
            "type": "array",
            "maxItems": 6,
            "description": "Already uploaded photo IDs in display order. Omit on edit to retain attachments; send the remaining list to remove photos.",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "alt": {
                  "type": "string",
                  "maxLength": 200
                }
              },
              "required": [
                "id",
                "alt"
              ]
            }
          },
          "expected_updated_at": {
            "type": "string",
            "description": "Optional exact updated_at from the fetched resource. A mismatch returns 409 without changing it. Omission preserves legacy unguarded edits."
          },
          "making": {
            "$ref": "#/components/schemas/MakingSpec",
            "description": "Required when creating a 공동제작 post. Omit on edit to retain specifications. Edits require the current post expected_updated_at and remain available after participation or closing. Actual changes create a new specification revision and move existing quantities to pending confirmation."
          }
        },
        "required": [
          "title",
          "body"
        ]
      },
      "CommentCreate": {
        "type": "object",
        "properties": {
          "body": {
            "type": "string",
            "minLength": 1,
            "maxLength": 4000
          },
          "author_name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 32
          },
          "parent_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional live comment in this post to reply to. A reply target is grouped under its root comment; deleted targets return 409."
          },
          "operation_id": {
            "type": "string",
            "format": "uuid",
            "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[89abAB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$",
            "description": "Optional UUID v4. Retain it and the exact input when retrying an uncertain creation; omit only for legacy behavior without duplicate protection."
          }
        },
        "required": [
          "body",
          "author_name"
        ]
      },
      "CommentEdit": {
        "type": "object",
        "properties": {
          "body": {
            "type": "string",
            "minLength": 1,
            "maxLength": 4000
          },
          "expected_updated_at": {
            "type": "string",
            "description": "Optional exact updated_at from the fetched resource. A mismatch returns 409 without changing it. Omission preserves legacy unguarded edits."
          }
        },
        "required": [
          "body"
        ]
      },
      "PostWriteResult": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Server-issued identifier.",
            "format": "uuid"
          },
          "author_name": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "body": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "owned": {
            "type": "boolean",
            "description": "False for anonymous reads; true only for the authenticated author."
          },
          "operation_id": {
            "type": "string",
            "format": "uuid",
            "description": "Present for creation with operation_id."
          },
          "reused": {
            "type": "boolean",
            "description": "Present for creation with operation_id. True for an exact retry."
          },
          "making": {
            "$ref": "#/components/schemas/MakingState",
            "description": "Present only on 공동제작 (shown as 수요 조사 · Interest check) posts."
          }
        },
        "required": [
          "id",
          "author_name",
          "title",
          "body",
          "category",
          "created_at",
          "updated_at",
          "owned"
        ]
      },
      "CommentsPage": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Comment"
            }
          },
          "total": {
            "type": "integer",
            "minimum": 0
          },
          "offset": {
            "type": "integer",
            "minimum": 0
          },
          "limit": {
            "type": "integer",
            "const": 20
          },
          "sort": {
            "type": "string",
            "enum": [
              "oldest",
              "newest"
            ]
          },
          "view": {
            "type": "string",
            "const": "flat"
          },
          "thread_total": {
            "type": "integer",
            "minimum": 0,
            "description": "Number of visible root threads; present when view is omitted."
          }
        },
        "required": [
          "items",
          "total",
          "offset",
          "limit",
          "sort"
        ]
      },
      "MakingSpec": {
        "type": "object",
        "properties": {
          "process": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80
          },
          "material": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80
          },
          "design_revision": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "description": "Organizer-supplied drawing version label. The linked file is not snapshotted or verified."
          },
          "target_quantity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100000
          },
          "desired_unit_price_krw": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 1000000000,
            "description": "Desired price, not a supplier quote. Omit or null if unknown."
          },
          "specifications": {
            "type": "string",
            "maxLength": 1000
          },
          "design_url": {
            "type": "string",
            "maxLength": 1000,
            "description": "Optional empty string or http(s) URL without embedded credentials. Public link supplied by the organizer; no private CAD file publication."
          },
          "deadline": {
            "type": "string",
            "description": "Optional empty string or YYYY-MM-DD. Closes at the end of that date in Asia/Seoul. Newly selected dates must be today or later; an unchanged past deadline may be retained while editing other fields."
          }
        },
        "required": [
          "process",
          "material",
          "design_revision",
          "target_quantity"
        ]
      },
      "MakingState": {
        "allOf": [
          {
            "$ref": "#/components/schemas/MakingSpec"
          },
          {
            "type": "object",
            "properties": {
              "stage": {
                "type": "string",
                "enum": [
                  "recruiting",
                  "quoting",
                  "closed"
                ]
              },
              "locked": {
                "type": "boolean",
                "const": false,
                "deprecated": true,
                "description": "Compatibility field; specifications remain editable."
              },
              "updated_at": {
                "type": "string"
              },
              "accepting_interest": {
                "type": "boolean"
              },
              "deadline_passed": {
                "type": "boolean"
              },
              "total_quantity": {
                "type": "integer",
                "minimum": 0,
                "description": "Positive quantities confirmed under the current specification revision."
              },
              "participant_count": {
                "type": "integer",
                "minimum": 0,
                "description": "Participants with a positive quantity confirmed under the current specification revision."
              },
              "my_quantity": {
                "type": "integer",
                "minimum": 0,
                "description": "Authenticated viewer quantity; zero for anonymous viewers."
              },
              "my_interest_updated_at": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Viewer interest version including cancellations. Never exposes another account identity."
              },
              "spec_revision": {
                "type": "integer",
                "minimum": 1
              },
              "spec_updated_at": {
                "type": "string",
                "description": "Timestamp of the last actual specification change."
              },
              "pending_quantity": {
                "type": "integer",
                "minimum": 0,
                "description": "Preserved quantities awaiting confirmation of the current specifications."
              },
              "pending_participant_count": {
                "type": "integer",
                "minimum": 0
              },
              "my_needs_confirmation": {
                "type": "boolean",
                "description": "True when the viewer has positive interest under an earlier specification revision. False for anonymous viewers."
              },
              "my_previous_spec": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/MakingSpec"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Snapshot of the specifications this viewer joined under, only while confirmation is pending. Otherwise null; never exposes other participant records."
              }
            },
            "required": [
              "stage",
              "locked",
              "updated_at",
              "accepting_interest",
              "deadline_passed",
              "total_quantity",
              "participant_count",
              "my_quantity",
              "my_interest_updated_at",
              "spec_revision",
              "spec_updated_at",
              "pending_quantity",
              "pending_participant_count",
              "my_needs_confirmation",
              "my_previous_spec"
            ]
          }
        ]
      },
      "Notification": {
        "type": "object",
        "required": [
          "id",
          "kind",
          "created_at",
          "read_at",
          "post_id",
          "comment_id",
          "post_title",
          "actor_name",
          "excerpt"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "post_comment",
              "comment_reply",
              "post_like",
              "credit_added",
              "credit_used",
              "credit_low",
              "credit_expiring"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "read_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "post_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "comment_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "post_title": {
            "type": [
              "string",
              "null"
            ]
          },
          "actor_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "excerpt": {
            "type": [
              "string",
              "null"
            ]
          },
          "amount": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991
          },
          "balance": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "PersonalStorage": {
        "type": "object",
        "description": "Platform-stored data owned by the signed-in account.",
        "required": [
          "posts",
          "comments",
          "pending_photos",
          "bookmarks",
          "canvas",
          "total_bytes"
        ],
        "properties": {
          "posts": {
            "type": "object",
            "required": [
              "count",
              "bytes",
              "items"
            ],
            "properties": {
              "count": {
                "type": "integer",
                "minimum": 0
              },
              "bytes": {
                "type": "integer",
                "minimum": 0
              },
              "items": {
                "type": "array",
                "maxItems": 50,
                "items": {
                  "type": "object",
                  "required": [
                    "id",
                    "title",
                    "category",
                    "created_at",
                    "updated_at",
                    "image_count",
                    "comment_count",
                    "like_count",
                    "file_count",
                    "file_bytes",
                    "bytes"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "title": {
                      "type": "string"
                    },
                    "category": {
                      "type": "string"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "updated_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "image_count": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "comment_count": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "like_count": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "file_count": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "file_bytes": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "bytes": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Title, body, photos and attached files."
                    }
                  }
                }
              }
            }
          },
          "comments": {
            "type": "object",
            "required": [
              "count",
              "bytes"
            ],
            "properties": {
              "count": {
                "type": "integer",
                "minimum": 0
              },
              "bytes": {
                "type": "integer",
                "minimum": 0
              }
            }
          },
          "pending_photos": {
            "type": "object",
            "required": [
              "count",
              "bytes",
              "limit"
            ],
            "properties": {
              "count": {
                "type": "integer",
                "minimum": 0
              },
              "bytes": {
                "type": "integer",
                "minimum": 0
              },
              "limit": {
                "type": "integer",
                "const": 12
              }
            }
          },
          "bookmarks": {
            "type": "object",
            "required": [
              "count",
              "items"
            ],
            "properties": {
              "count": {
                "type": "integer",
                "minimum": 0
              },
              "items": {
                "type": "array",
                "maxItems": 100,
                "items": {
                  "type": "object",
                  "required": [
                    "kind",
                    "item_id",
                    "created_at"
                  ],
                  "properties": {
                    "kind": {
                      "type": "string",
                      "enum": [
                        "tips",
                        "suppliers"
                      ]
                    },
                    "item_id": {
                      "type": "string"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "canvas": {
            "type": "object",
            "required": [
              "boards",
              "links",
              "bytes",
              "limit_bytes"
            ],
            "properties": {
              "boards": {
                "type": "object",
                "required": [
                  "count",
                  "items"
                ],
                "properties": {
                  "count": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "items": {
                    "type": "array",
                    "maxItems": 50,
                    "items": {
                      "type": "object",
                      "required": [
                        "id",
                        "project_id",
                        "canvas_id",
                        "revision",
                        "bytes",
                        "name"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "project_id": {
                          "type": "string"
                        },
                        "canvas_id": {
                          "type": "string"
                        },
                        "revision": {
                          "type": "integer",
                          "minimum": 1
                        },
                        "bytes": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "name": {
                          "type": "string",
                          "maxLength": 120
                        }
                      }
                    }
                  }
                }
              },
              "links": {
                "type": "object",
                "required": [
                  "total",
                  "active",
                  "active_limit"
                ],
                "properties": {
                  "total": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "active": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "active_limit": {
                    "type": "integer",
                    "const": 20
                  }
                }
              },
              "bytes": {
                "type": "integer",
                "minimum": 0
              },
              "limit_bytes": {
                "type": "integer",
                "const": 104857600
              }
            }
          },
          "agent_files": {
            "type": "object",
            "description": "Files uploaded through the AI publish API, on posts and drafts.",
            "required": [
              "count",
              "bytes",
              "unposted"
            ],
            "properties": {
              "count": {
                "type": "integer",
                "minimum": 0
              },
              "bytes": {
                "type": "integer",
                "minimum": 0
              },
              "unposted": {
                "type": "object",
                "description": "Uploads not attached to any post yet.",
                "required": [
                  "count",
                  "bytes"
                ],
                "properties": {
                  "count": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "bytes": {
                    "type": "integer",
                    "minimum": 0
                  }
                }
              }
            }
          },
          "total_bytes": {
            "type": "integer",
            "minimum": 0
          }
        }
      },
      "NotificationSummary": {
        "type": "object",
        "required": [
          "unread_count"
        ],
        "properties": {
          "unread_count": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          }
        }
      }
    }
  }
}
