{
  "openapi": "3.0.4",
  "info": {
    "title": "EGP Order API",
    "description": "Submit glass orders to ECO Windows programmatically — validated, priced live, and booked straight into production.\n\n**Authentication:** every request needs your dealer API key: `Authorization: Bearer egp_live_…` (issued by your ECO Windows rep; keep it secret, it can place real orders).\n\n**Start here:** `GET /v1/catalog/*` for the vocabulary, `POST /v1/quotes` to price without ordering, `POST /v1/orders` to book.\n\n**Limits:** 60 requests/min, 10 order submissions/min, 200 lines per order.",
    "version": "v1"
  },
  "paths": {
    "/v1/catalog/shapes": {
      "get": {
        "tags": [
          "Catalog"
        ],
        "summary": "List shapes",
        "description": "Every orderable shape, with the dimension letters (B/L/R/S/T/U) its lines must supply in the `dimensions` object. A `Rectangle` needs only `B` (width) and `L` (height). Pass the shape by `name` or `id`.",
        "operationId": "V1_Catalog_Shapes",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CatalogShape"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/catalog/pane-types": {
      "get": {
        "tags": [
          "Catalog"
        ],
        "summary": "List pane types",
        "description": "Pane makeups (Single Pane, Double Pane IG, Lami IG Pane, …) with an `accepts` matrix telling you which spec fields apply. Accepted specs are **required** (an IG unit physically has a spacer; use gas `AIR` for no fill), and sending a spec the pane type doesn't accept is a validation error. Pass by `name` or `id`.",
        "operationId": "V1_Catalog_PaneTypes",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CatalogPaneType"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/catalog/glass-types": {
      "get": {
        "tags": [
          "Catalog"
        ],
        "summary": "List glass types",
        "description": "Glass options for the `glassType` field. Pass the `code` (e.g. `1/8CL`); the `name` also resolves.",
        "operationId": "V1_Catalog_GlassTypes",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CatalogCode"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/catalog/laminates": {
      "get": {
        "tags": [
          "Catalog"
        ],
        "summary": "List laminates",
        "description": "Laminate options for the `laminate` field (lami pane types only).",
        "operationId": "V1_Catalog_Laminates",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CatalogCode"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/catalog/spacers": {
      "get": {
        "tags": [
          "Catalog"
        ],
        "summary": "List spacers",
        "description": "Spacer options for the `spacer` field (insulated-glass pane types only).",
        "operationId": "V1_Catalog_Spacers",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CatalogCode"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/catalog/gases": {
      "get": {
        "tags": [
          "Catalog"
        ],
        "summary": "List gas fills",
        "description": "Gas-fill options for the `gas` field (insulated-glass pane types only).",
        "operationId": "V1_Catalog_Gases",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CatalogCode"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/orders": {
      "post": {
        "tags": [
          "Orders"
        ],
        "summary": "Submit an order",
        "description": "Validates, prices, and books the order in one atomic call — it lands in production as **Hold** for office review, and appears in your portal history like any web order.\n\n```json\n{\n  \"poNumber\": \"20260825\",\n  \"orderName\": \"Smith Residence\",\n  \"shipDate\": \"2026-09-15\",\n  \"notes\": \"Deliver to north dock\",\n  \"lines\": [\n    {\n      \"lineNumber\": \"A1\",\n      \"quantity\": 2,\n      \"shape\": \"Rectangle\",\n      \"dimensions\": { \"B\": \"24\", \"L\": \"36-1/2\" },\n      \"paneType\": \"Double Pane IG\",\n      \"glassType\": \"1/8CL\",\n      \"spacer\": \"8TSpacer\",\n      \"gas\": \"ARG\",\n      \"product\": \"Living Room Left\",\n      \"poItemNumber\": \"001\"\n    }\n  ]\n}```\n\n**Idempotency:** `poNumber` (digits only) must be unique across your estimates and orders — resubmitting the same PO returns `409` with `existingOrderId`, so retries can never double-book. Set `\"validateOnly\": true` for a full dry run (responds `200` with the complete result, writes nothing).\n\n**Required for placement:** `shipDate` (the requested due date, today to two years out) — production scheduling can't process a dateless order.\n\nA line whose quantity is N is exploded into N production units sub-numbered `A1-1, A1-2, …`; their totals always sum to the quoted line total.",
        "operationId": "V1_Orders_Create",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicOrderRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicOrderResult"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicOrderResult"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Content",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "502": {
            "description": "Bad Gateway",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Orders"
        ],
        "summary": "List your orders",
        "description": "Your order history, newest first — the same data your portal shows. Page with `skip`/`take` (max 100), filter with `status` (e.g. `Hold`) or `search`.",
        "operationId": "V1_Orders_List",
        "parameters": [
          {
            "name": "skip",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "take",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sortDesc",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderDtoPagedResult"
                }
              }
            }
          }
        }
      }
    },
    "/v1/orders/{orderId}": {
      "get": {
        "tags": [
          "Orders"
        ],
        "summary": "Get one order with its lines",
        "description": "The order header plus every production line (one per unit after quantity explosion), including per-line status as it moves through production. Orders belonging to other dealers return `404`.",
        "operationId": "V1_Orders_Get",
        "parameters": [
          {
            "name": "orderId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicOrderDetailResult"
                }
              }
            }
          },
          "404": {
            "description": "Not Found"
          }
        }
      }
    },
    "/v1/quotes": {
      "post": {
        "tags": [
          "Quotes"
        ],
        "summary": "Price an order without placing it",
        "description": "Validates and prices the exact payload `POST /v1/orders` takes, **writing nothing** — use it as your integration playground and for live price checks.\n\n```json\n{\n  \"poNumber\": \"20260825\",\n  \"orderName\": \"Smith Residence\",\n  \"shipDate\": \"2026-09-15\",\n  \"notes\": \"Deliver to north dock\",\n  \"lines\": [\n    {\n      \"lineNumber\": \"A1\",\n      \"quantity\": 2,\n      \"shape\": \"Rectangle\",\n      \"dimensions\": { \"B\": \"24\", \"L\": \"36-1/2\" },\n      \"paneType\": \"Double Pane IG\",\n      \"glassType\": \"1/8CL\",\n      \"spacer\": \"8TSpacer\",\n      \"gas\": \"ARG\",\n      \"product\": \"Living Room Left\",\n      \"poItemNumber\": \"001\"\n    }\n  ]\n}```\n\nDimensions accept `24`, `24-1/2` or `24 1/2` (inches). `poNumber` may be omitted for quotes. Totals follow the portal math: surcharge and tax are both computed on the line amount.",
        "operationId": "V1_Quotes_Create",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicOrderRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicQuoteResult"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Content",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "502": {
            "description": "Bad Gateway",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "CatalogCode": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CatalogPaneType": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "layers": {
            "type": "integer",
            "format": "int32"
          },
          "accepts": {
            "$ref": "#/components/schemas/CatalogPaneTypeAccepts"
          }
        },
        "additionalProperties": false
      },
      "CatalogPaneTypeAccepts": {
        "type": "object",
        "properties": {
          "glassType": {
            "type": "boolean"
          },
          "laminate": {
            "type": "boolean"
          },
          "spacer": {
            "type": "boolean"
          },
          "gas": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "CatalogShape": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int32"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "notes": {
            "type": "string",
            "nullable": true
          },
          "requiredDimensions": {
            "$ref": "#/components/schemas/CatalogShapeDimensions"
          }
        },
        "additionalProperties": false
      },
      "CatalogShapeDimensions": {
        "type": "object",
        "properties": {
          "b": {
            "type": "boolean"
          },
          "l": {
            "type": "boolean"
          },
          "r": {
            "type": "boolean"
          },
          "s": {
            "type": "boolean"
          },
          "t": {
            "type": "boolean"
          },
          "u": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "OrderDetailDto": {
        "type": "object",
        "properties": {
          "orderDetailId": {
            "type": "integer",
            "format": "int32"
          },
          "customerOrderNumber": {
            "type": "string",
            "nullable": true
          },
          "unitCompositionID": {
            "type": "string",
            "nullable": true
          },
          "glassComposition": {
            "type": "string",
            "nullable": true
          },
          "quantity": {
            "type": "integer",
            "format": "int32"
          },
          "processID": {
            "type": "string",
            "nullable": true
          },
          "shapeProviderID": {
            "type": "string",
            "nullable": true
          },
          "shapeNumberID": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "shapeFileName": {
            "type": "string",
            "nullable": true
          },
          "height": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "width": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "edgeworkAmount": {
            "type": "string",
            "nullable": true
          },
          "edgeSideID": {
            "type": "string",
            "nullable": true
          },
          "edgeworkTypeID": {
            "type": "string",
            "nullable": true
          },
          "igUnitThickness": {
            "type": "string",
            "nullable": true
          },
          "spacerID": {
            "type": "string",
            "nullable": true
          },
          "muntinID": {
            "type": "string",
            "nullable": true
          },
          "shapeFlip": {
            "type": "boolean"
          },
          "shapeDimension1": {
            "type": "string",
            "nullable": true
          },
          "shapeDimension2": {
            "type": "string",
            "nullable": true
          },
          "shapeDimension3": {
            "type": "string",
            "nullable": true
          },
          "shapeDimension4": {
            "type": "string",
            "nullable": true
          },
          "shapeDimension5": {
            "type": "string",
            "nullable": true
          },
          "shapeDimension6": {
            "type": "string",
            "nullable": true
          },
          "shapeDimension7": {
            "type": "string",
            "nullable": true
          },
          "shapeDimension8": {
            "type": "string",
            "nullable": true
          },
          "shapeDimension9": {
            "type": "string",
            "nullable": true
          },
          "shapeDimension10": {
            "type": "string",
            "nullable": true
          },
          "partID": {
            "type": "string",
            "nullable": true
          },
          "paneTypeID": {
            "type": "string",
            "nullable": true
          },
          "spacerSightline": {
            "type": "string",
            "nullable": true
          },
          "product": {
            "type": "string",
            "nullable": true
          },
          "poNum": {
            "type": "string",
            "nullable": true
          },
          "poItemNum": {
            "type": "string",
            "nullable": true
          },
          "lineNumber": {
            "type": "string",
            "nullable": true
          },
          "usePart": {
            "type": "boolean"
          },
          "glassDescriptionType": {
            "type": "integer",
            "format": "int32"
          },
          "shapeType": {
            "type": "integer",
            "format": "int32"
          },
          "additionalItemInfo": {
            "type": "boolean"
          },
          "orderId": {
            "type": "integer",
            "format": "int32"
          },
          "fullDescription": {
            "type": "string",
            "nullable": true
          },
          "unitCost": {
            "type": "number",
            "format": "double"
          },
          "status": {
            "type": "integer",
            "format": "int32"
          },
          "scheduleId": {
            "type": "integer",
            "format": "int32"
          },
          "rackNumber": {
            "type": "integer",
            "format": "int32"
          },
          "sqFt": {
            "type": "number",
            "format": "double"
          },
          "lineCost": {
            "type": "number",
            "format": "double"
          },
          "lineSqFt": {
            "type": "number",
            "format": "double"
          },
          "code": {
            "type": "string",
            "nullable": true
          },
          "makeupCost": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "packingBarcode": {
            "type": "string",
            "nullable": true
          },
          "d365ItemNumber": {
            "type": "string",
            "nullable": true
          },
          "confirmationLineRef": {
            "type": "string",
            "nullable": true
          },
          "customerGlassCode": {
            "type": "string",
            "nullable": true
          },
          "rackSlot": {
            "type": "integer",
            "format": "int32"
          },
          "sequenceNumber": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "OrderDto": {
        "type": "object",
        "properties": {
          "orderId": {
            "type": "integer",
            "format": "int32"
          },
          "customerId": {
            "type": "integer",
            "format": "int32"
          },
          "customerOrderNumber": {
            "type": "string",
            "nullable": true
          },
          "date": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "notes": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "scheduleId": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "shipDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "approvedForProduction": {
            "type": "boolean"
          },
          "approvedByAccounting": {
            "type": "boolean"
          },
          "isQBSync": {
            "type": "boolean"
          },
          "priceCalculated": {
            "type": "boolean"
          },
          "priceCalculatedDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "orderName": {
            "type": "string",
            "nullable": true
          },
          "approvedDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "customerName": {
            "type": "string",
            "nullable": true
          },
          "confirmationEmail": {
            "type": "string",
            "nullable": true
          },
          "totalCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "OrderDtoPagedResult": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrderDto"
            },
            "nullable": true
          },
          "skip": {
            "type": "integer",
            "format": "int32"
          },
          "take": {
            "type": "integer",
            "format": "int32"
          },
          "totalCount": {
            "type": "integer",
            "format": "int32"
          },
          "isSuccess": {
            "type": "boolean"
          },
          "errorMessage": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "detail": {
            "type": "string",
            "nullable": true
          },
          "instance": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": { }
      },
      "PublicLineResult": {
        "type": "object",
        "properties": {
          "lineNumber": {
            "type": "string",
            "nullable": true
          },
          "quantity": {
            "type": "integer",
            "format": "int32"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "unitPrice": {
            "type": "number",
            "format": "double"
          },
          "unitSqFt": {
            "type": "number",
            "format": "double"
          },
          "lineSqFt": {
            "type": "number",
            "format": "double"
          },
          "lineTotal": {
            "type": "number",
            "format": "double"
          }
        },
        "additionalProperties": false
      },
      "PublicOrderDetailResult": {
        "type": "object",
        "properties": {
          "order": {
            "$ref": "#/components/schemas/OrderDto"
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrderDetailDto"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "PublicOrderLine": {
        "type": "object",
        "properties": {
          "lineNumber": {
            "type": "string",
            "nullable": true
          },
          "quantity": {
            "type": "integer",
            "format": "int32"
          },
          "shape": {
            "type": "string",
            "nullable": true
          },
          "dimensions": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "nullable": true
          },
          "paneType": {
            "type": "string",
            "nullable": true
          },
          "glassType": {
            "type": "string",
            "nullable": true
          },
          "laminate": {
            "type": "string",
            "nullable": true
          },
          "spacer": {
            "type": "string",
            "nullable": true
          },
          "gas": {
            "type": "string",
            "nullable": true
          },
          "product": {
            "type": "string",
            "nullable": true
          },
          "fullDescription": {
            "type": "string",
            "nullable": true
          },
          "poNum": {
            "type": "string",
            "nullable": true
          },
          "poItemNumber": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "PublicOrderRequest": {
        "type": "object",
        "properties": {
          "poNumber": {
            "type": "string",
            "nullable": true
          },
          "orderName": {
            "type": "string",
            "nullable": true
          },
          "shipDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "notes": {
            "type": "string",
            "nullable": true
          },
          "validateOnly": {
            "type": "boolean"
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicOrderLine"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "PublicOrderResult": {
        "type": "object",
        "properties": {
          "poNumber": {
            "type": "string",
            "nullable": true
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicLineResult"
            },
            "nullable": true
          },
          "totals": {
            "$ref": "#/components/schemas/PublicTotals"
          },
          "orderId": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "validateOnly": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "PublicQuoteResult": {
        "type": "object",
        "properties": {
          "poNumber": {
            "type": "string",
            "nullable": true
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicLineResult"
            },
            "nullable": true
          },
          "totals": {
            "$ref": "#/components/schemas/PublicTotals"
          }
        },
        "additionalProperties": false
      },
      "PublicTotals": {
        "type": "object",
        "properties": {
          "amount": {
            "type": "number",
            "format": "double"
          },
          "surcharge": {
            "type": "number",
            "format": "double"
          },
          "tax": {
            "type": "number",
            "format": "double"
          },
          "total": {
            "type": "number",
            "format": "double"
          }
        },
        "additionalProperties": false
      }
    },
    "securitySchemes": {
      "Bearer": {
        "type": "http",
        "description": "Dealer API key (egp_live_…) — or the portal shared secret on internal endpoints.",
        "scheme": "bearer"
      }
    }
  },
  "security": [
    {
      "Bearer": [ ]
    }
  ]
}