{
  "openapi": "3.1.0",
  "info": {
    "title": "Patrick D Youngblood storefront (public read-only)",
    "version": "1.0.0",
    "summary": "Public, read-only catalog endpoints of patrickyoungblood.com.",
    "description": "Browse fine art prints and Curious Workman soap: list collections, list products with variant prices, fetch one product, and get search suggestions. Everything here is public and needs no account, API key or sign-up. Prices are decimal strings in USD on each variant. Missing resources return HTTP 404 with an EMPTY body, so check the status code before parsing. These endpoints are provided by the Shopify storefront and are rate limited: back off on HTTP 429 and honor Retry-After. Carts and checkout are not part of this document: use the Universal Commerce Protocol MCP endpoint at /api/ucp/mcp (see /.well-known/ucp and /agents.md). There are no write operations, no OAuth and no scoped permissions.",
    "contact": {
      "name": "Contact page",
      "url": "https://patrickyoungblood.com/pages/contact"
    },
    "license": {
      "name": "Catalog data is public. Product images are copyrighted artwork: do not republish.",
      "url": "https://patrickyoungblood.com/agents.md"
    }
  },
  "servers": [
    {
      "url": "https://patrickyoungblood.com",
      "description": "Production storefront"
    }
  ],
  "externalDocs": {
    "description": "Agent instructions: when to use this store and how to call it",
    "url": "https://patrickyoungblood.com/agents.md"
  },
  "security": [],
  "tags": [
    { "name": "catalog", "description": "Products and collections" },
    { "name": "search", "description": "Search suggestions" },
    { "name": "content", "description": "Pages" }
  ],
  "paths": {
    "/collections.json": {
      "get": {
        "operationId": "listCollections",
        "tags": ["catalog"],
        "summary": "List all collections",
        "description": "Returns every published collection with its handle and product count. Use the handle with listCollectionProducts. The 'art' collection holds the fine art prints and 'curious-workman' holds the soap.",
        "responses": {
          "200": {
            "description": "Collections",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/CollectionList" }
              }
            }
          },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/collections/{collection_handle}/products.json": {
      "get": {
        "operationId": "listCollectionProducts",
        "tags": ["catalog"],
        "summary": "List products in a collection",
        "description": "Returns the products of one collection, each with its variants (sizes) and prices. Use collection_handle 'art' for fine art prints or 'curious-workman' for soap.",
        "parameters": [
          {
            "name": "collection_handle",
            "in": "path",
            "required": true,
            "description": "Collection handle from listCollections, for example 'art' or 'curious-workman'.",
            "schema": { "type": "string", "examples": ["art", "curious-workman"] }
          },
          { "$ref": "#/components/parameters/limit" },
          { "$ref": "#/components/parameters/page" }
        ],
        "responses": {
          "200": {
            "description": "Products in the collection",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ProductList" }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/products.json": {
      "get": {
        "operationId": "listProducts",
        "tags": ["catalog"],
        "summary": "List all products",
        "description": "Returns every published product across all collections (art prints and soap), each with variants and prices.",
        "parameters": [
          { "$ref": "#/components/parameters/limit" },
          { "$ref": "#/components/parameters/page" }
        ],
        "responses": {
          "200": {
            "description": "Products",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ProductList" }
              }
            }
          },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/products/{product_handle}.json": {
      "get": {
        "operationId": "getProduct",
        "tags": ["catalog"],
        "summary": "Get one product",
        "description": "Returns one product with all variants (print sizes), prices, availability and images. The human page for the same product is /products/{product_handle}.",
        "parameters": [
          {
            "name": "product_handle",
            "in": "path",
            "required": true,
            "description": "Product handle from listProducts or listCollectionProducts, for example 'lavender'.",
            "schema": { "type": "string", "examples": ["lavender"] }
          }
        ],
        "responses": {
          "200": {
            "description": "The product",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["product"],
                  "properties": {
                    "product": { "$ref": "#/components/schemas/Product" }
                  }
                }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/search/suggest.json": {
      "get": {
        "operationId": "suggestSearch",
        "tags": ["search"],
        "summary": "Search suggestions",
        "description": "Returns products, collections and pages matching a query, for type-ahead search. Use it to find a piece by place or title, for example 'barcelona'.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Search text.",
            "schema": { "type": "string", "minLength": 1, "examples": ["barcelona"] }
          },
          {
            "name": "resources[type]",
            "in": "query",
            "required": false,
            "description": "Comma-separated resource types to return.",
            "schema": { "type": "string", "examples": ["product,collection"] }
          },
          {
            "name": "resources[limit]",
            "in": "query",
            "required": false,
            "description": "Maximum results per resource type (1 to 10).",
            "schema": { "type": "integer", "minimum": 1, "maximum": 10, "default": 10 }
          }
        ],
        "responses": {
          "200": {
            "description": "Suggestions grouped by resource type",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SearchSuggestions" }
              }
            }
          },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/pages.json": {
      "get": {
        "operationId": "listPages",
        "tags": ["content"],
        "summary": "List pages",
        "description": "Returns the published content pages such as Contact, with handle and title.",
        "responses": {
          "200": {
            "description": "Pages",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PageList" }
              }
            }
          },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    }
  },
  "components": {
    "parameters": {
      "limit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "description": "Products per page (1 to 250).",
        "schema": { "type": "integer", "minimum": 1, "maximum": 250, "default": 30 }
      },
      "page": {
        "name": "page",
        "in": "query",
        "required": false,
        "description": "Page number, starting at 1.",
        "schema": { "type": "integer", "minimum": 1, "default": 1 }
      }
    },
    "responses": {
      "NotFound": {
        "description": "No such resource. The body is EMPTY (zero bytes), so rely on the 404 status code, not on a parsed error object."
      },
      "RateLimited": {
        "description": "Too many requests. Wait for the number of seconds in the Retry-After header, then retry.",
        "headers": {
          "Retry-After": {
            "description": "Seconds to wait before retrying.",
            "schema": { "type": "integer" }
          }
        }
      }
    },
    "schemas": {
      "Money": {
        "type": "string",
        "description": "Decimal amount in USD as a string, for example \"295.00\".",
        "pattern": "^[0-9]+\\.[0-9]{2}$",
        "examples": ["295.00"]
      },
      "Variant": {
        "type": "object",
        "description": "A purchasable option. For art prints each variant is a print size.",
        "required": ["id", "title", "price", "available"],
        "properties": {
          "id": { "type": "integer", "description": "Variant ID." },
          "title": { "type": "string", "description": "Size or option name, for example 9\" x 12\"." },
          "option1": { "type": ["string", "null"] },
          "option2": { "type": ["string", "null"] },
          "option3": { "type": ["string", "null"] },
          "sku": { "type": ["string", "null"] },
          "requires_shipping": { "type": "boolean" },
          "taxable": { "type": "boolean" },
          "available": { "type": "boolean", "description": "True when the variant can be bought now." },
          "price": { "$ref": "#/components/schemas/Money" },
          "compare_at_price": {
            "oneOf": [{ "$ref": "#/components/schemas/Money" }, { "type": "null" }]
          },
          "grams": { "type": "integer" },
          "position": { "type": "integer" },
          "product_id": { "type": "integer" },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      },
      "Image": {
        "type": "object",
        "required": ["id", "src"],
        "properties": {
          "id": { "type": "integer" },
          "src": { "type": "string", "format": "uri", "description": "Image URL. Copyrighted artwork: do not republish." },
          "width": { "type": "integer" },
          "height": { "type": "integer" },
          "position": { "type": "integer" },
          "product_id": { "type": "integer" },
          "variant_ids": { "type": "array", "items": { "type": "integer" } },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      },
      "Option": {
        "type": "object",
        "required": ["name", "values"],
        "properties": {
          "name": { "type": "string" },
          "position": { "type": "integer" },
          "values": { "type": "array", "items": { "type": "string" } }
        }
      },
      "Product": {
        "type": "object",
        "required": ["id", "title", "handle", "variants"],
        "properties": {
          "id": { "type": "integer" },
          "title": { "type": "string" },
          "handle": { "type": "string", "description": "URL slug. The product page is /products/{handle}." },
          "body_html": { "type": "string", "description": "Description as HTML." },
          "vendor": { "type": "string" },
          "product_type": { "type": "string", "description": "For example 'Fine Art Painting' or 'Bars'." },
          "tags": { "type": "array", "items": { "type": "string" } },
          "published_at": { "type": "string", "format": "date-time" },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" },
          "variants": { "type": "array", "items": { "$ref": "#/components/schemas/Variant" } },
          "images": { "type": "array", "items": { "$ref": "#/components/schemas/Image" } },
          "options": { "type": "array", "items": { "$ref": "#/components/schemas/Option" } }
        }
      },
      "ProductList": {
        "type": "object",
        "required": ["products"],
        "properties": {
          "products": { "type": "array", "items": { "$ref": "#/components/schemas/Product" } }
        }
      },
      "Collection": {
        "type": "object",
        "required": ["id", "title", "handle"],
        "properties": {
          "id": { "type": "integer" },
          "title": { "type": "string" },
          "handle": { "type": "string" },
          "description": { "type": ["string", "null"] },
          "published_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" },
          "image": { "type": ["object", "null"] },
          "products_count": { "type": "integer" }
        }
      },
      "CollectionList": {
        "type": "object",
        "required": ["collections"],
        "properties": {
          "collections": { "type": "array", "items": { "$ref": "#/components/schemas/Collection" } }
        }
      },
      "Page": {
        "type": "object",
        "required": ["id", "handle", "title"],
        "properties": {
          "id": { "type": "integer" },
          "handle": { "type": "string" },
          "title": { "type": "string" },
          "body_html": { "type": ["string", "null"] },
          "published_at": { "type": "string", "format": "date-time" },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      },
      "PageList": {
        "type": "object",
        "required": ["pages"],
        "properties": {
          "pages": { "type": "array", "items": { "$ref": "#/components/schemas/Page" } }
        }
      },
      "SearchSuggestions": {
        "type": "object",
        "required": ["resources"],
        "properties": {
          "resources": {
            "type": "object",
            "required": ["results"],
            "properties": {
              "results": {
                "type": "object",
                "properties": {
                  "products": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": { "type": "integer" },
                        "title": { "type": "string" },
                        "handle": { "type": "string" },
                        "url": { "type": "string" },
                        "price": { "$ref": "#/components/schemas/Money" },
                        "price_min": { "$ref": "#/components/schemas/Money" },
                        "price_max": { "$ref": "#/components/schemas/Money" },
                        "available": { "type": "boolean" },
                        "image": { "type": ["string", "null"], "format": "uri" },
                        "type": { "type": "string" },
                        "tags": { "type": "array", "items": { "type": "string" } }
                      }
                    }
                  },
                  "collections": { "type": "array", "items": { "type": "object" } },
                  "pages": { "type": "array", "items": { "type": "object" } }
                }
              }
            }
          }
        }
      }
    }
  }
}
