{
  "openapi": "3.1.0",
  "info": {
    "title": "CanvasRack Shopping API",
    "version": "1.0.0",
    "description": "Public discovery and quoting cannot access private artwork, approve designs, charge money or fulfill orders. Read product purchasable_live and quote test_only flags for operating mode. Apparel is quote-required. Shipping, upgrades and applicable tax are finalized at checkout."
  },
  "servers": [
    {
      "url": "/"
    }
  ],
  "paths": {
    "/api/v1/products": {
      "get": {
        "operationId": "search_products",
        "summary": "Discover bounded catalog (max 20)",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 100
            }
          },
          {
            "name": "category",
            "in": "query",
            "schema": {
              "enum": ["canvas", "apparel", "all"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Products with explicit staging and live-purchase flags"
          }
        }
      }
    },
    "/api/v1/products/{id}": {
      "get": {
        "operationId": "get_product",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Product"
          },
          "404": {
            "description": "Structured request error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/products/{id}/options": {
      "get": {
        "operationId": "get_product_options",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Options and template"
          },
          "404": {
            "description": "Structured request error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/validate": {
      "post": {
        "operationId": "validate_configuration",
        "summary": "Validate supported canvas choices",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": ["product", "size", "quantity"],
                "properties": {
                  "product": {
                    "const": "canvas"
                  },
                  "size": {
                    "enum": ["8x12", "12x18", "16x24", "20x30", "24x36"]
                  },
                  "orientation": {
                    "enum": ["landscape", "portrait"],
                    "default": "landscape"
                  },
                  "quantity": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 20
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Validated response; prices are integer USD cents. Inspect test_only for the operating mode."
          },
          "400": {
            "description": "Structured request error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Structured request error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "Structured request error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Structured request error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Retry delay in seconds"
              }
            }
          }
        }
      }
    },
    "/api/v1/quotes": {
      "post": {
        "operationId": "request_quote",
        "summary": "Authoritative 15-minute canvas quote; maximum 20 total canvases",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": ["items"],
                "properties": {
                  "items": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 20,
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": ["product", "size", "quantity"],
                      "properties": {
                        "product": {
                          "const": "canvas"
                        },
                        "size": {
                          "enum": ["8x12", "12x18", "16x24", "20x30", "24x36"]
                        },
                        "orientation": {
                          "enum": ["landscape", "portrait"],
                          "default": "landscape"
                        },
                        "quantity": {
                          "type": "integer",
                          "minimum": 1,
                          "maximum": 20
                        }
                      }
                    }
                  },
                  "discount": {
                    "enum": ["auto", "none"],
                    "default": "auto"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Validated response; prices are integer USD cents. Inspect test_only for the operating mode."
          },
          "400": {
            "description": "Structured request error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Structured request error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "Structured request error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Structured request error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Retry delay in seconds"
              }
            }
          }
        }
      }
    },
    "/api/v1/review-links": {
      "post": {
        "operationId": "create_review_link",
        "summary": "Opaque review token valid one hour. No private fields accepted.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": ["product", "size", "quantity"],
                "properties": {
                  "product": {
                    "const": "canvas"
                  },
                  "size": {
                    "enum": ["8x12", "12x18", "16x24", "20x30", "24x36"]
                  },
                  "orientation": {
                    "enum": ["landscape", "portrait"],
                    "default": "landscape"
                  },
                  "quantity": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 20
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Validated response; prices are integer USD cents. Inspect test_only for the operating mode."
          },
          "400": {
            "description": "Structured request error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Structured request error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "Structured request error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Structured request error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Retry delay in seconds"
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "CanvasConfiguration": {
        "type": "object",
        "additionalProperties": false,
        "required": ["product", "size", "quantity"],
        "properties": {
          "product": {
            "const": "canvas"
          },
          "size": {
            "enum": ["8x12", "12x18", "16x24", "20x30", "24x36"]
          },
          "orientation": {
            "enum": ["landscape", "portrait"],
            "default": "landscape"
          },
          "quantity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 20
          }
        }
      },
      "QuoteRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["items"],
        "properties": {
          "items": {
            "type": "array",
            "minItems": 1,
            "maxItems": 20,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": ["product", "size", "quantity"],
              "properties": {
                "product": {
                  "const": "canvas"
                },
                "size": {
                  "enum": ["8x12", "12x18", "16x24", "20x30", "24x36"]
                },
                "orientation": {
                  "enum": ["landscape", "portrait"],
                  "default": "landscape"
                },
                "quantity": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 20
                }
              }
            }
          },
          "discount": {
            "enum": ["auto", "none"],
            "default": "auto"
          }
        }
      }
    }
  }
}
