{
  "openapi": "3.1.0",
  "info": {
    "title": "WooCommerce Store API",
    "version": "1.0.0",
    "description": "Any WooCommerce storefront read as structured JSON: detection, store details, products with prices and stock, one product in full, and the category tree."
  },
  "servers": [
    {
      "url": "https://api.fetchlayer.dev/woocommerce-stores"
    }
  ],
  "security": [
    {
      "BearerAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API Key",
        "description": "Send your FetchLayer key as Authorization: Bearer ss-your-key."
      }
    }
  },
  "paths": {
    "/detect-store": {
      "post": {
        "operationId": "detect-store",
        "tags": [
          "Store"
        ],
        "summary": "Check a domain runs WooCommerce",
        "description": "Confirm a domain is a WooCommerce store and find the real storefront behind it, before anything else spends a request on it. Returns a verdict with a confidence level, the individual signals that were checked and which of them matched, and every published data source that answered — most complete first. Run it once per new domain; the dataSource it reports is the one every later call will use.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "store": {
                    "type": "string",
                    "description": "Store domain, for example example.com, or any URL on the store. 3–255 characters."
                  },
                  "timeoutMs": {
                    "type": "number",
                    "description": "Per-request time limit in milliseconds (max 600000)."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "store"
                ]
              },
              "examples": {
                "default": {
                  "value": {
                    "store": "example-shop.com"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "requestedUrl": {
                      "type": "string",
                      "description": "The store this result corresponds to."
                    },
                    "scrapedAt": {
                      "type": "string",
                      "description": "ISO 8601 timestamp of the read."
                    },
                    "blocked": {
                      "type": "boolean",
                      "description": "Always false on a successful response."
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Caveats about this particular result — a truncated walk, an upstream limit, a field this store does not publish. Read it: a short result set is usually explained here rather than by an error."
                    },
                    "store": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "The resolved store: canonical domain and the store's own base URL."
                    },
                    "detection": {
                      "type": "object",
                      "properties": {
                        "isWooCommerce": {
                          "type": "boolean",
                          "description": "Whether the domain runs WooCommerce."
                        },
                        "confidence": {
                          "type": "string",
                          "description": "high when the store publishes product data or identifies WooCommerce outright, medium on weaker storefront signals alone, none when nothing matched."
                        },
                        "evidence": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "One row per signal checked: what was looked for, whether it was found, and what matched."
                        },
                        "dataSource": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The most complete source available, or null when none is. This is what a products call will read from."
                        },
                        "availableDataSources": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Every source that answered, most complete first."
                        },
                        "storeVersion": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Null unless the store publishes it, and many do not."
                        },
                        "platformVersion": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The underlying platform version, where the store publishes it."
                        }
                      },
                      "additionalProperties": false
                    }
                  },
                  "additionalProperties": false
                },
                "examples": {
                  "default": {
                    "value": {
                      "store": {
                        "domain": "example-shop.com",
                        "url": "https://example-shop.com"
                      },
                      "detection": {
                        "isWooCommerce": true,
                        "confidence": "high",
                        "dataSource": "catalog-api",
                        "availableDataSources": [
                          "catalog-api",
                          "content-api",
                          "product-pages"
                        ],
                        "evidence": [
                          {
                            "signal": "store-catalog-endpoint",
                            "found": true,
                            "detail": "200 with 412 products"
                          }
                        ]
                      },
                      "notes": []
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid or missing Bearer token"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/store-profile": {
      "post": {
        "operationId": "store-profile",
        "tags": [
          "Store"
        ],
        "summary": "Get a store's details",
        "description": "Read a WooCommerce store's own details: its name and description, the currency and symbol it prices in, its locale, its logo, the social profiles the storefront advertises, and the product and category counts it reports. The cheapest way to qualify a store before pulling its catalog.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "store": {
                    "type": "string",
                    "description": "Store domain, for example example.com, or any URL on the store. 3–255 characters."
                  },
                  "dataSource": {
                    "type": "string",
                    "description": "Pin the read to one published source: catalog-api, content-api or product-pages. catalog-api carries every field, content-api carries no prices, SKUs or stock, and product-pages carries no attributes or variations and is far more expensive to read.",
                    "example": "the most complete source the store offers"
                  },
                  "timeoutMs": {
                    "type": "number",
                    "description": "Per-request time limit in milliseconds (max 600000)."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "store"
                ]
              },
              "examples": {
                "default": {
                  "value": {
                    "store": "example-shop.com"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "requestedUrl": {
                      "type": "string",
                      "description": "The store this result corresponds to."
                    },
                    "scrapedAt": {
                      "type": "string",
                      "description": "ISO 8601 timestamp of the read."
                    },
                    "blocked": {
                      "type": "boolean",
                      "description": "Always false on a successful response."
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Caveats about this particular result — a truncated walk, an upstream limit, a field this store does not publish. Read it: a short result set is usually explained here rather than by an error."
                    },
                    "store": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "The resolved store: canonical domain and the store's own base URL."
                    },
                    "profile": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The store name."
                        },
                        "description": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The tagline or description the storefront publishes."
                        },
                        "currency": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "ISO 4217 code, for example USD."
                        },
                        "currencySymbol": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The symbol the store displays prices with."
                        },
                        "locale": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The storefront's locale."
                        },
                        "productCount": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "Products the store reports holding."
                        },
                        "categoryCount": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "Categories the store reports holding."
                        },
                        "logoUrl": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The store logo."
                        },
                        "socialLinks": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Social profile URLs the storefront advertises."
                        },
                        "storeVersion": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Null unless the store publishes it."
                        },
                        "dataSource": {
                          "type": "string",
                          "description": "Which published source this profile came from."
                        }
                      },
                      "additionalProperties": false
                    }
                  },
                  "additionalProperties": false
                },
                "examples": {
                  "default": {
                    "value": {
                      "profile": {
                        "name": "Example Shop",
                        "currency": "USD",
                        "currencySymbol": "$",
                        "locale": "en-US",
                        "productCount": 412,
                        "categoryCount": 24,
                        "socialLinks": [
                          "https://instagram.com/exampleshop"
                        ],
                        "dataSource": "catalog-api"
                      },
                      "notes": []
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid or missing Bearer token"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/products": {
      "post": {
        "operationId": "products",
        "tags": [
          "Catalog"
        ],
        "summary": "List a store's products",
        "description": "List a WooCommerce store's products with prices, sale prices, stock, SKUs, categories, tags, brands, attributes, variations and image URLs. Filter by search text, category, tag, price range, on sale and in stock, and order by date, price, popularity, rating, title or the store's own menu order. Read the response's dataSource: on a store with no published catalog the records are read from rendered product pages, which is dramatically more expensive per product, and limit becomes a hard request budget rather than a target.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "store": {
                    "type": "string",
                    "description": "Store domain, for example example.com, or any URL on the store. 3–255 characters."
                  },
                  "dataSource": {
                    "type": "string",
                    "description": "Pin the read to one published source: catalog-api, content-api or product-pages. catalog-api carries every field, content-api carries no prices, SKUs or stock, and product-pages carries no attributes or variations and is far more expensive to read.",
                    "example": "the most complete source the store offers"
                  },
                  "limit": {
                    "type": "number",
                    "description": "Maximum products returned (max 250), or -1 for everything available. On a store read from rendered pages this is a budget, not a target — every product is a page fetch.",
                    "example": "30"
                  },
                  "search": {
                    "type": "string",
                    "description": "Only products matching this text."
                  },
                  "category": {
                    "type": "string",
                    "description": "Only products in this category, by slug or id."
                  },
                  "tag": {
                    "type": "string",
                    "description": "Only products with this tag, by slug or id."
                  },
                  "minPrice": {
                    "type": "string",
                    "description": "Only products at or above this price, in the store's own currency. A decimal string, for example 19.99."
                  },
                  "maxPrice": {
                    "type": "string",
                    "description": "Only products at or below this price, in the store's own currency."
                  },
                  "onSale": {
                    "type": "boolean",
                    "description": "Only products the store has discounted."
                  },
                  "inStock": {
                    "type": "boolean",
                    "description": "Only products the store reports as in stock."
                  },
                  "orderBy": {
                    "type": "string",
                    "description": "date, price, popularity, rating, title or menu_order. Follows the store's own order by default."
                  },
                  "orderDirection": {
                    "type": "string",
                    "description": "asc or desc."
                  },
                  "pages": {
                    "type": "number",
                    "description": "Pages of results to collect in one request (max 100), or -1 for the maximum allowed. Each page walked counts as one request."
                  },
                  "cursor": {
                    "type": "string",
                    "description": "Resume from a previous response's nextCursor."
                  },
                  "delayMs": {
                    "type": "number",
                    "description": "Milliseconds to wait between requests to the store (max 30000). Use it on a store you are walking deeply."
                  },
                  "timeoutMs": {
                    "type": "number",
                    "description": "Per-request time limit in milliseconds (max 600000). Worth raising on a store read from rendered pages."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "store"
                ]
              },
              "examples": {
                "default": {
                  "value": {
                    "store": "example-shop.com",
                    "category": "outerwear",
                    "onSale": true,
                    "orderBy": "price",
                    "orderDirection": "asc",
                    "limit": 50
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "requestedUrl": {
                      "type": "string",
                      "description": "The store this result corresponds to."
                    },
                    "scrapedAt": {
                      "type": "string",
                      "description": "ISO 8601 timestamp of the read."
                    },
                    "blocked": {
                      "type": "boolean",
                      "description": "Always false on a successful response."
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Caveats about this particular result — a truncated walk, an upstream limit, a field this store does not publish. Read it: a short result set is usually explained here rather than by an error."
                    },
                    "store": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "The resolved store: canonical domain and the store's own base URL."
                    },
                    "dataSource": {
                      "type": "string",
                      "description": "catalog-api, content-api or product-pages — the source these products were read from, and the single biggest factor in what the call cost."
                    },
                    "filters": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "The filters this call actually ran with, after defaults were resolved."
                    },
                    "products": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "The store's own product id, where it publishes one."
                          },
                          "name": {
                            "type": "string",
                            "description": "Product title."
                          },
                          "slug": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "URL slug — pass it to /product-detail as product."
                          },
                          "permalink": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "The product page on the store."
                          },
                          "type": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "simple, variable, grouped, external or variation, as the store reports it."
                          },
                          "sku": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Stock keeping unit. Absent on the content-api source."
                          },
                          "description": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Plain text, markup removed."
                          },
                          "shortDescription": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "The store's own summary line, where it publishes one."
                          },
                          "prices": {
                            "type": "object",
                            "additionalProperties": true,
                            "description": "currency, currencySymbol, price, regularPrice, salePrice, onSale, priceRangeMin and priceRangeMax. Amounts are exact decimal strings in the store's own currency, never floats."
                          },
                          "stockStatus": {
                            "type": "string",
                            "description": "in-stock, out-of-stock, on-backorder or unknown."
                          },
                          "stockQuantity": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "Set only where the store publishes a number rather than a status."
                          },
                          "averageRating": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "The rating the store displays."
                          },
                          "reviewCount": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "How many reviews the store reports. The review text itself is not offered yet."
                          },
                          "categories": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "additionalProperties": true
                            },
                            "description": "Categories on the product: id, name, slug and URL."
                          },
                          "tags": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "additionalProperties": true
                            },
                            "description": "Tags on the product."
                          },
                          "brands": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "additionalProperties": true
                            },
                            "description": "Brands on the product, where the store uses them."
                          },
                          "attributes": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "additionalProperties": true
                            },
                            "description": "Attribute name, the store's key, its terms, and whether variations differ by it. Absent on the product-pages source."
                          },
                          "variations": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "additionalProperties": true
                            },
                            "description": "Each variation with its own id, SKU, option values, prices, permalink and stock status. Absent on the product-pages source."
                          },
                          "images": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "additionalProperties": true
                            },
                            "description": "url, thumbnailUrl, alt, title and a downloadUrl that streams the file through GET /media. Image bytes are never fetched while reading a catalog."
                          },
                          "weight": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Shipping weight, as the store reports it."
                          },
                          "dimensions": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "additionalProperties": true,
                            "description": "length, width and height, as the store reports them."
                          },
                          "dateCreated": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "When the product was published."
                          },
                          "dateModified": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "When the product last changed — the field to diff for catalog monitoring."
                          },
                          "source": {
                            "type": "string",
                            "description": "Which published source this record came from: catalog-api, content-api or product-pages. It tells you which fields to trust and what the read cost."
                          }
                        }
                      },
                      "description": "The matching products."
                    },
                    "productCount": {
                      "type": "number",
                      "description": "Products in this response."
                    },
                    "totalProducts": {
                      "type": [
                        "number",
                        "null"
                      ],
                      "description": "The total the store reports for these filters, where it reports one."
                    },
                    "pagesScraped": {
                      "type": "number",
                      "description": "Pages actually collected. Each page counts as one request against your plan."
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Pass back as cursor to continue, or null when the listing is exhausted."
                    },
                    "hasNextPage": {
                      "type": "boolean",
                      "description": "Whether more results are available beyond this response."
                    }
                  },
                  "additionalProperties": false
                },
                "examples": {
                  "default": {
                    "value": {
                      "dataSource": "catalog-api",
                      "productCount": 50,
                      "totalProducts": 118,
                      "pagesScraped": 1,
                      "hasNextPage": true,
                      "products": [
                        {
                          "id": 8842,
                          "name": "Coastal Rain Shell",
                          "slug": "coastal-rain-shell",
                          "sku": "CRS-BLK-M",
                          "prices": {
                            "currency": "USD",
                            "price": "129.00",
                            "regularPrice": "179.00",
                            "salePrice": "129.00",
                            "onSale": true
                          },
                          "stockStatus": "in-stock",
                          "source": "catalog-api"
                        }
                      ],
                      "notes": []
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid or missing Bearer token"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/product-detail": {
      "post": {
        "operationId": "product-detail",
        "tags": [
          "Catalog"
        ],
        "summary": "Get one product in full",
        "description": "Read one product completely: full description, prices and sale prices, SKU, stock status and quantity, rating and review count, categories, tags and brands, every attribute, every variation with its own price, SKU and stock, all image URLs, weight and dimensions, and the products the store lists as related. Takes a product id, a slug, or the product's URL on the store.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "store": {
                    "type": "string",
                    "description": "Store domain, for example example.com, or any URL on the store. 3–255 characters."
                  },
                  "product": {
                    "type": "string",
                    "description": "Product id, slug, or the product's URL on the store."
                  },
                  "dataSource": {
                    "type": "string",
                    "description": "Pin the read to one published source: catalog-api, content-api or product-pages. catalog-api carries every field, content-api carries no prices, SKUs or stock, and product-pages carries no attributes or variations and is far more expensive to read.",
                    "example": "the most complete source the store offers"
                  },
                  "includeVariations": {
                    "type": "boolean",
                    "description": "Also resolve each variation's own price, SKU and stock.",
                    "example": "true"
                  },
                  "timeoutMs": {
                    "type": "number",
                    "description": "Per-request time limit in milliseconds (max 600000)."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "store",
                  "product"
                ]
              },
              "examples": {
                "default": {
                  "value": {
                    "store": "example-shop.com",
                    "product": "coastal-rain-shell",
                    "includeVariations": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "requestedUrl": {
                      "type": "string",
                      "description": "The store this result corresponds to."
                    },
                    "scrapedAt": {
                      "type": "string",
                      "description": "ISO 8601 timestamp of the read."
                    },
                    "blocked": {
                      "type": "boolean",
                      "description": "Always false on a successful response."
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Caveats about this particular result — a truncated walk, an upstream limit, a field this store does not publish. Read it: a short result set is usually explained here rather than by an error."
                    },
                    "store": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "The resolved store: canonical domain and the store's own base URL."
                    },
                    "dataSource": {
                      "type": "string",
                      "description": "Which published source this product was read from."
                    },
                    "product": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "The full product record — the same shape as a row in /products, with variations and attributes resolved.",
                      "properties": {
                        "variations": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "Each variation's id, SKU, option values, prices, permalink and stock status."
                        },
                        "attributes": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "Attribute name, key, terms, and whether variations differ by it."
                        },
                        "images": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "Every image on the product, each with a downloadUrl that streams the file through GET /media."
                        }
                      }
                    },
                    "relatedProductIds": {
                      "type": "array",
                      "items": {
                        "type": "number"
                      },
                      "description": "Products the store lists as related, where it publishes any."
                    }
                  },
                  "additionalProperties": false
                },
                "examples": {
                  "default": {
                    "value": {
                      "dataSource": "catalog-api",
                      "product": {
                        "id": 8842,
                        "name": "Coastal Rain Shell",
                        "type": "variable",
                        "prices": {
                          "currency": "USD",
                          "priceRangeMin": "129.00",
                          "priceRangeMax": "149.00",
                          "onSale": true
                        },
                        "variations": [
                          {
                            "id": 8845,
                            "sku": "CRS-BLK-M",
                            "stockStatus": "in-stock",
                            "attributes": [
                              {
                                "name": "Size",
                                "value": "M"
                              }
                            ]
                          }
                        ]
                      },
                      "relatedProductIds": [
                        8801,
                        8912
                      ],
                      "notes": []
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid or missing Bearer token"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/categories": {
      "post": {
        "operationId": "categories",
        "tags": [
          "Catalog"
        ],
        "summary": "List a store's categories",
        "description": "Read a WooCommerce store's category tree: each category's name, slug, URL, description, parent, image and the number of products the store reports in it. Cheap on every data source, so it is the usual way to map a catalog before deciding which slices of it are worth pulling as products.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "store": {
                    "type": "string",
                    "description": "Store domain, for example example.com, or any URL on the store. 3–255 characters."
                  },
                  "dataSource": {
                    "type": "string",
                    "description": "Pin the read to one published source: catalog-api, content-api or product-pages. catalog-api carries every field, content-api carries no prices, SKUs or stock, and product-pages carries no attributes or variations and is far more expensive to read.",
                    "example": "the most complete source the store offers"
                  },
                  "limit": {
                    "type": "number",
                    "description": "Maximum categories returned (max 500), or -1 for everything available.",
                    "example": "30"
                  },
                  "slug": {
                    "type": "string",
                    "description": "Only the category with this slug."
                  },
                  "parent": {
                    "type": "string",
                    "description": "Only categories directly under this one, by slug or id."
                  },
                  "includeEmpty": {
                    "type": "boolean",
                    "description": "Include categories holding no products.",
                    "example": "false"
                  },
                  "pages": {
                    "type": "number",
                    "description": "Pages of results to collect in one request (max 100), or -1 for the maximum allowed. Each page walked counts as one request."
                  },
                  "cursor": {
                    "type": "string",
                    "description": "Resume from a previous response's nextCursor."
                  },
                  "delayMs": {
                    "type": "number",
                    "description": "Milliseconds to wait between requests to the store (max 30000). Use it on a store you are walking deeply."
                  },
                  "timeoutMs": {
                    "type": "number",
                    "description": "Per-request time limit in milliseconds (max 600000)."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "store"
                ]
              },
              "examples": {
                "default": {
                  "value": {
                    "store": "example-shop.com",
                    "includeEmpty": false,
                    "limit": 100
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "requestedUrl": {
                      "type": "string",
                      "description": "The store this result corresponds to."
                    },
                    "scrapedAt": {
                      "type": "string",
                      "description": "ISO 8601 timestamp of the read."
                    },
                    "blocked": {
                      "type": "boolean",
                      "description": "Always false on a successful response."
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Caveats about this particular result — a truncated walk, an upstream limit, a field this store does not publish. Read it: a short result set is usually explained here rather than by an error."
                    },
                    "store": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "The resolved store: canonical domain and the store's own base URL."
                    },
                    "dataSource": {
                      "type": "string",
                      "description": "Which published source these categories were read from."
                    },
                    "categories": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "The store's own category id."
                          },
                          "name": {
                            "type": "string",
                            "description": "Category name."
                          },
                          "slug": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Pass it to /products as category."
                          },
                          "parentId": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "Parent category id — walk it to rebuild the tree."
                          },
                          "productCount": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "Products in the category, as the store reports it."
                          },
                          "imageUrl": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Category image, where the store sets one."
                          }
                        }
                      },
                      "description": "The matching categories."
                    },
                    "categoryCount": {
                      "type": "number",
                      "description": "Categories in this response."
                    },
                    "totalCategories": {
                      "type": [
                        "number",
                        "null"
                      ],
                      "description": "The total the store reports, where it reports one."
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Pass back as cursor to continue, or null when the listing is exhausted."
                    }
                  },
                  "additionalProperties": false
                },
                "examples": {
                  "default": {
                    "value": {
                      "dataSource": "catalog-api",
                      "categoryCount": 24,
                      "totalCategories": 24,
                      "categories": [
                        {
                          "id": 31,
                          "name": "Outerwear",
                          "slug": "outerwear",
                          "parentId": null,
                          "productCount": 118
                        }
                      ],
                      "notes": []
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid or missing Bearer token"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/media": {
      "get": {
        "operationId": "media",
        "tags": [
          "Media"
        ],
        "summary": "Download a product image",
        "description": "Stream a product image's actual bytes, using the store and url from an image returned by /products or /product-detail. The URL must belong to that store. Every image carries a downloadUrl that already contains both parameters — use it verbatim. HTTP Range requests are supported. This is a GET with query parameters, not a JSON POST, and it bills as one request. Image bytes are never fetched while reading a catalog, so this is the only route that moves them.",
        "parameters": [
          {
            "name": "store",
            "in": "query",
            "required": true,
            "description": "The store the image belongs to. Passed as a query parameter.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "url",
            "in": "query",
            "required": true,
            "description": "Image URL, exactly as returned on a product. Must belong to that store. Passed as a query parameter.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "filename",
            "in": "query",
            "required": false,
            "description": "Content-Disposition filename to serve the file as (max 200 characters).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Range",
            "in": "header",
            "required": false,
            "description": "Standard HTTP Range request header, for example bytes=0-65535. Sent as a header, not a query parameter.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or missing Bearer token"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/resolve-url": {
      "post": {
        "operationId": "resolve-url",
        "tags": [
          "Utility"
        ],
        "summary": "Parse a store URL",
        "description": "Turn any store, product or category URL into the structured input the other endpoints take — the domain, the store base URL, and the product slug, product id or category slug it encodes, plus what kind of page it points at. Use it when a URL is all you have. Parsing a URL does not consume a credit.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "description": "Any store, product or category URL, to be parsed into structured input."
                  },
                  "timeoutMs": {
                    "type": "number",
                    "description": "Per-request time limit in milliseconds (max 600000)."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "url"
                ]
              },
              "examples": {
                "default": {
                  "value": {
                    "url": "https://example-shop.com/product/coastal-rain-shell/"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "kind": {
                      "type": "string",
                      "description": "What the URL points at: store, product, category or unknown."
                    },
                    "domain": {
                      "type": "string",
                      "description": "Canonical hostname — pass it as store."
                    },
                    "storeUrl": {
                      "type": "string",
                      "description": "The store's own base URL."
                    },
                    "productSlug": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Present when kind is product."
                    },
                    "productId": {
                      "type": [
                        "number",
                        "null"
                      ],
                      "description": "Present when the URL carries one."
                    },
                    "categorySlug": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Present when kind is category."
                    }
                  },
                  "additionalProperties": false
                },
                "examples": {
                  "default": {
                    "value": {
                      "kind": "product",
                      "domain": "example-shop.com",
                      "storeUrl": "https://example-shop.com",
                      "productSlug": "coastal-rain-shell",
                      "productId": null,
                      "categorySlug": null
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid or missing Bearer token"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ]
      }
    }
  }
}