{
  "openapi": "3.0.1",
  "info": {
    "title": "Morrisons UK Grocery Scraper",
    "description": "Scrape Morrisons UK groceries by search term: export prices, availability, unit prices, pack sizes, promotions, ratings, categories and images as JSON, CSV or Excel. Fast JSON-API scraper for price monitoring, competitor intelligence and product data.",
    "version": "0.1",
    "x-build-id": "3cbSE6MHeiSKuJE4f"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/bobcodgodkid.1~morrisons-grocery-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-bobcodgodkid.1-morrisons-grocery-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/bobcodgodkid.1~morrisons-grocery-scraper/runs": {
      "post": {
        "operationId": "runs-sync-bobcodgodkid.1-morrisons-grocery-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/bobcodgodkid.1~morrisons-grocery-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-bobcodgodkid.1-morrisons-grocery-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "mode": {
            "title": "Mode",
            "enum": [
              "search",
              "offers"
            ],
            "type": "string",
            "description": "What to scrape. 'Search' (default) runs the search terms and/or category URLs below. 'Offers' ignores those and pulls the site-wide promotions feed — every product currently on a Morrisons offer, with was/now prices.",
            "default": "search"
          },
          "searchTerms": {
            "title": "Search terms",
            "type": "array",
            "description": "Terms to search Morrisons groceries for (one search per term, all result pages followed). Provide this, 'categoryUrls', or both. Duplicates and blanks are ignored.",
            "items": {
              "type": "string"
            }
          },
          "categoryUrls": {
            "title": "Category URLs",
            "type": "array",
            "description": "Morrisons category page URLs to crawl in full (every product, all pages). Paste the URL straight from the browser address bar. Provide this, 'searchTerms', or both. Duplicates and blanks are ignored.",
            "items": {
              "type": "string"
            }
          },
          "offerCategories": {
            "title": "Offer categories",
            "type": "array",
            "description": "Offers mode only. Restrict the promotions feed to named categories (e.g. 'Frozen Food', 'Meat & Fish'), matched case-insensitively against each product's category. Leave empty for every offer. Unknown names are ignored.",
            "items": {
              "type": "string"
            }
          },
          "maxItems": {
            "title": "Max items",
            "minimum": 0,
            "type": "integer",
            "description": "Stop after this many unique products are saved to the dataset across all terms. 0 means no limit.",
            "default": 0
          },
          "maxPagesPerTerm": {
            "title": "Max pages per term/category",
            "minimum": 0,
            "type": "integer",
            "description": "Cap the number of result pages fetched per search term and per category (each page is up to 300 products). 0 means all pages.",
            "default": 0
          },
          "enrichProducts": {
            "title": "Enrich with product detail",
            "type": "boolean",
            "description": "Fetch the full product-detail panel for every product saved — nutrition (per 100g/ml and per serving), allergens, ingredients, storage, full description and brand info. Adds one request per product, so it is slower and costs more; leave off for price-only runs. IMPORTANT: this needs Residential proxy — Morrisons product pages block datacenter IPs, so set the proxy below to Residential or 'details' will come back empty. (EAN/GTIN is not published by Morrisons, so it is not included.)",
            "default": false
          },
          "fetchReviews": {
            "title": "Fetch customer reviews",
            "type": "boolean",
            "description": "For every product saved, fetch its customer reviews — rating histogram plus up to 100 newest reviews (text, author, date, verified-buyer flag). Adds one request per product, so it is slower and costs more. Off by default.",
            "default": false
          },
          "fetchRelated": {
            "title": "Fetch related products",
            "type": "boolean",
            "description": "For every product saved, fetch the IDs of similar and related products (for recommendation / product-graph use-cases). Adds up to two lightweight requests per product. Off by default.",
            "default": false
          },
          "monitorPrices": {
            "title": "Monitor price changes",
            "type": "boolean",
            "description": "Compare each product's price to the previous run and emit a change record (old price, new price, delta, direction) when it moves. Prices are stored by SKU between runs in a named key-value store — this needs a saved, scheduled task to be useful (the first run only records a baseline).",
            "default": false
          },
          "maxProductsToDecorate": {
            "title": "Products decorated per page",
            "minimum": 1,
            "maximum": 300,
            "type": "integer",
            "description": "How many of the (up to 300) results per page come back fully detailed. 300 (default) returns everything in one request — leave it unless you have a reason to lower it.",
            "default": 300
          },
          "blockFailureThreshold": {
            "title": "Block failure threshold",
            "minimum": 0,
            "maximum": 100,
            "type": "integer",
            "description": "Abort the whole run if this percentage of attempted terms is blocked (after a small sample). 100 = only stop when essentially everything is blocked.",
            "default": 100
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Apify Proxy settings. Datacenter is the default (cheapest). If you see widespread blocking, switch to Residential.",
            "default": {
              "useApifyProxy": true
            }
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}