{
  "openapi": "3.1.0",
  "info": {
    "title": "Conde Professional Storefront API",
    "version": "1.0.0",
    "summary": "Public, unauthenticated HTTP surface of the Conde Professional storefront.",
    "description": "Conde Professional is a wholesale supplier of 100% human hair extensions for licensed salon professionals.\n\nThis document describes the public, read-mostly HTTP endpoints of the storefront at https://condeprofessional.com. These are the same four operations exposed to in-page agents through the WebMCP provider (`navigator.modelContext`) in `assets/conde-webmcp.js`, so a tool call and an HTTP call return the same data.\n\nFor full agent-driven commerce — catalog search, carts, checkout and order completion — use the Universal Commerce Protocol MCP endpoint at `POST https://condeprofessional.com/api/ucp/mcp` instead. Discovery: `GET https://condeprofessional.com/.well-known/ucp`. Agent instructions: https://condeprofessional.com/agents.md\n\nNone of the operations below require authentication. Automated traffic is rate limited.",
    "contact": {
      "name": "Conde Professional developer reference",
      "url": "https://condeprofessional.com/pages/developers"
    },
    "license": {
      "name": "Proprietary — catalog data may be read to answer user questions and complete purchases, but not used for model training.",
      "identifier": "LicenseRef-Conde-Proprietary"
    }
  },
  "externalDocs": {
    "description": "Agent instructions (agents.md)",
    "url": "https://condeprofessional.com/agents.md"
  },
  "servers": [
    { "url": "https://condeprofessional.com", "description": "Production storefront" }
  ],
  "tags": [
    { "name": "catalog", "description": "Read product and collection data." },
    { "name": "cart", "description": "Read and modify the current session cart." }
  ],
  "paths": {
    "/search/suggest.json": {
      "get": {
        "operationId": "searchProducts",
        "summary": "Search products",
        "description": "Typeahead search across the Conde Professional catalog. Use this to resolve a shopper's free-text intent (colour, length, texture or install method) into product handles, then call getProduct for full detail.",
        "tags": ["catalog"],
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Search terms, for example 'merlot fantasy 20 inch'.",
            "schema": { "type": "string", "minLength": 1 }
          },
          {
            "name": "resources[type]",
            "in": "query",
            "required": true,
            "description": "Resource types to search. Use 'product' for catalog search.",
            "schema": { "type": "string", "enum": ["product", "collection", "page", "article"], "default": "product" }
          },
          {
            "name": "resources[limit]",
            "in": "query",
            "required": false,
            "description": "Maximum results to return.",
            "schema": { "type": "integer", "minimum": 1, "maximum": 10, "default": 10 }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching products.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SearchSuggestResponse" }
              }
            }
          },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/products/{handle}.js": {
      "get": {
        "operationId": "getProduct",
        "summary": "Get a product by handle",
        "description": "Returns the full product record including every variant with its own price, SKU, option values and live availability. Prices are integers in the smallest currency unit (cents USD).",
        "tags": ["catalog"],
        "parameters": [
          {
            "name": "handle",
            "in": "path",
            "required": true,
            "description": "Product handle taken from its URL, for example 'bead-pro-plier'.",
            "schema": { "type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$" }
          }
        ],
        "responses": {
          "200": {
            "description": "The product.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Product" }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/cart.js": {
      "get": {
        "operationId": "getCart",
        "summary": "Get the current cart",
        "description": "Returns the cart bound to the caller's session cookie, including line items, quantities and totals. An empty cart is a 200 with item_count 0, never a 404.",
        "tags": ["cart"],
        "responses": {
          "200": {
            "description": "The current cart.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Cart" }
              }
            }
          }
        }
      }
    },
    "/cart/add.js": {
      "post": {
        "operationId": "addToCart",
        "summary": "Add a variant to the cart",
        "description": "Adds one or more product variants to the session cart. Variant ids come from getProduct; they are numeric, not GraphQL global ids. Returns 422 with a structured error when the variant does not exist or is out of stock.",
        "tags": ["cart"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/AddToCartRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The added line items.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Cart" }
              }
            }
          },
          "422": { "$ref": "#/components/responses/UnprocessableEntity" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    }
  },
  "components": {
    "responses": {
      "NotFound": {
        "description": "No such resource.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "UnprocessableEntity": {
        "description": "The request was well formed but could not be applied, for example an unknown or unavailable variant.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" },
            "examples": {
              "unknownVariant": {
                "summary": "Variant id does not exist",
                "value": { "status": 422, "message": "Cart Error", "description": "Cannot find variant" }
              }
            }
          }
        }
      },
      "RateLimited": {
        "description": "Automated traffic is rate limited. Back off and retry.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "description": "Structured JSON error envelope returned by the storefront Ajax endpoints. HTML error pages are never returned for these paths.",
        "required": ["status", "message"],
        "properties": {
          "status": { "type": "integer", "description": "HTTP status code, repeated in the body.", "examples": [422] },
          "message": { "type": "string", "description": "Short machine-stable error label.", "examples": ["Cart Error"] },
          "description": { "type": "string", "description": "Human-readable explanation and resolution hint.", "examples": ["Cannot find variant"] }
        }
      },
      "SearchSuggestResponse": {
        "type": "object",
        "required": ["resources"],
        "properties": {
          "resources": {
            "type": "object",
            "required": ["results"],
            "properties": {
              "results": {
                "type": "object",
                "properties": {
                  "products": {
                    "type": "array",
                    "items": { "$ref": "#/components/schemas/ProductSummary" }
                  }
                }
              }
            }
          }
        }
      },
      "ProductSummary": {
        "type": "object",
        "required": ["title", "handle", "url"],
        "properties": {
          "title": { "type": "string" },
          "handle": { "type": "string", "description": "Use with getProduct." },
          "url": { "type": "string", "format": "uri-reference" },
          "price": { "type": "string", "description": "Formatted price string." },
          "vendor": { "type": "string" },
          "product_type": { "type": "string" }
        }
      },
      "Product": {
        "type": "object",
        "required": ["id", "title", "handle", "available", "variants"],
        "properties": {
          "id": { "type": "integer" },
          "title": { "type": "string" },
          "handle": { "type": "string" },
          "description": { "type": "string", "description": "HTML description." },
          "vendor": { "type": "string" },
          "type": { "type": "string" },
          "tags": { "type": "array", "items": { "type": "string" } },
          "price": { "type": "integer", "description": "Current price in cents." },
          "price_min": { "type": "integer" },
          "price_max": { "type": "integer" },
          "available": { "type": "boolean" },
          "variants": { "type": "array", "items": { "$ref": "#/components/schemas/Variant" } }
        }
      },
      "Variant": {
        "type": "object",
        "required": ["id", "title", "price", "available"],
        "properties": {
          "id": { "type": "integer", "description": "Numeric variant id. Pass to addToCart." },
          "title": { "type": "string" },
          "sku": { "type": ["string", "null"] },
          "price": { "type": "integer", "description": "Price in cents." },
          "available": { "type": "boolean" },
          "options": { "type": "array", "items": { "type": "string" } }
        }
      },
      "AddToCartRequest": {
        "type": "object",
        "description": "Either a single variant, or an items array for several at once.",
        "properties": {
          "id": { "type": "integer", "description": "Numeric variant id." },
          "quantity": { "type": "integer", "minimum": 1, "default": 1 },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "required": ["id"],
              "properties": {
                "id": { "type": "integer" },
                "quantity": { "type": "integer", "minimum": 1, "default": 1 }
              }
            }
          }
        }
      },
      "Cart": {
        "type": "object",
        "required": ["item_count", "currency", "items"],
        "properties": {
          "item_count": { "type": "integer" },
          "total_price": { "type": "integer", "description": "Total in cents." },
          "currency": { "type": "string", "examples": ["USD"] },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "product_title": { "type": "string" },
                "variant_title": { "type": ["string", "null"] },
                "quantity": { "type": "integer" },
                "price": { "type": "integer" },
                "line_price": { "type": "integer" },
                "url": { "type": "string", "format": "uri-reference" }
              }
            }
          }
        }
      }
    }
  }
}
