{
  "openapi": "3.0.1",
  "info": {
    "title": "Flashfood Scraper - Discounted Groceries, Prices & Availability",
    "description": "Scrape Flashfood discounted groceries and stores by location or store. Extract current and original prices, savings, quantity, best-before date, department, and store details. Track NEW, UPDATED, REAPPEARED, and EXPIRED items with incremental runs, resume, and MCP export.",
    "version": "0.1",
    "x-build-id": "ejI45tQwDGL4c9y9F"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/abotapi~flashfood-grocery-deals-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-abotapi-flashfood-grocery-deals-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/abotapi~flashfood-grocery-deals-scraper/runs": {
      "post": {
        "operationId": "runs-sync-abotapi-flashfood-grocery-deals-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/abotapi~flashfood-grocery-deals-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-abotapi-flashfood-grocery-deals-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",
        "required": [
          "mode"
        ],
        "properties": {
          "mode": {
            "title": "Mode",
            "enum": [
              "search",
              "url"
            ],
            "type": "string",
            "description": "Search finds stores and their discounted food around one or more locations. Store mode reads one or more stores by id or link.",
            "default": "search"
          },
          "locations": {
            "title": "Locations",
            "type": "array",
            "description": "Where to search: one entry per location. A city or place name (Detroit, Toronto, M4C 1A5), or exact coordinates as lat,lng (42.3314,-83.0458). Names are resolved automatically. The source covers the US and Canada.",
            "items": {
              "type": "string"
            }
          },
          "radiusKm": {
            "title": "Radius (km)",
            "minimum": 1,
            "maximum": 400,
            "type": "integer",
            "description": "Search mode: how far from each point to look, 1 to 400 km. A single query still returns at most 100 stores, nearest first.",
            "default": 40
          },
          "countries": {
            "title": "Countries",
            "type": "array",
            "description": "Keep only stores in these countries. Empty means both Canada and the United States.",
            "items": {
              "type": "string",
              "enum": [
                "CA",
                "US"
              ],
              "enumTitles": [
                "Canada",
                "United States"
              ]
            }
          },
          "banners": {
            "title": "Store chains (banners)",
            "type": "array",
            "description": "Keep only these store chains, for example Loblaws or Metro. Case and accent-insensitive, partial match. Empty means all.",
            "items": {
              "type": "string"
            }
          },
          "keywords": {
            "title": "Keywords",
            "type": "array",
            "description": "Keep only items whose name has a word starting with the keyword (several words in one keyword must all match). Empty means all.",
            "items": {
              "type": "string"
            }
          },
          "departments": {
            "title": "Departments",
            "type": "array",
            "description": "Keep only these departments, in English or French (Bakery, Boulangerie). Partial, case and accent-insensitive match. Empty means all.",
            "items": {
              "type": "string"
            }
          },
          "minDiscountPercent": {
            "title": "Minimum discount (%)",
            "minimum": 0,
            "maximum": 100,
            "type": "integer",
            "description": "Keep only items discounted by at least this percent."
          },
          "maxPrice": {
            "title": "Maximum price",
            "pattern": "^\\d+([.,]\\d{1,2})?$",
            "type": "string",
            "description": "Keep only items priced at or below this amount, for example 5 or 4.99."
          },
          "expiringWithinDays": {
            "title": "Best before within (days)",
            "minimum": 0,
            "type": "integer",
            "description": "Keep only items whose best-before date is within this many days (0 = today or already past)."
          },
          "maxStores": {
            "title": "Max stores",
            "minimum": 1,
            "type": "integer",
            "description": "Read at most this many stores, nearest first."
          },
          "fullNetwork": {
            "title": "Network sweep",
            "type": "boolean",
            "description": "Search mode: ignore Locations and sweep a built-in list of about 45 Canadian and US metro areas, 160 km each, de-duplicating stores. Combine with Max items and the filters. Coverage is the stores within reach of those areas.",
            "default": false
          },
          "storesOnly": {
            "title": "Store records only",
            "type": "boolean",
            "description": "Return only store records (kind=store, with item counts) and no deal items. Store records are billed like any other record.",
            "default": false
          },
          "emitSoldOut": {
            "title": "Emit sold-out items (incremental mode only)",
            "type": "boolean",
            "description": "With Emit expired on, items that disappeared from a store that was read this run are returned as SOLD_OUT. Turn off to drop those rows.",
            "default": true
          },
          "storeInputs": {
            "title": "Store links or ids",
            "type": "array",
            "description": "URL mode: a store id, a store link (…/api/v1/stores/<id>), an items link (…/api/v1/items/?storeIds=<id>), or a stores-near-a-point link with latitude, longitude and optional maxDistance in meters. The website locations page carries no store id and is skipped with a warning. Multi-value supported.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "urls": {
            "title": "Store links or ids (alias)",
            "type": "array",
            "description": "Alias for Store links or ids, accepted under the name other Apify actors use for URL mode. Same shapes and the same default examples; used only when Store links or ids is not given.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "maxItems": {
            "title": "Max items",
            "minimum": 0,
            "type": "integer",
            "description": "Stop after this many records (0 = no limit; the run then stops when stores or items run out).",
            "default": 20
          },
          "includeStores": {
            "title": "Also return store records",
            "type": "boolean",
            "description": "Off by default: the dataset then carries the discounted food items only. Turn on to also emit one record per store (name, banner, address, hours, pickup instructions).",
            "default": false
          },
          "countryHint": {
            "title": "Currency hint (optional)",
            "enum": [
              "CAD",
              "USD"
            ],
            "type": "string",
            "description": "Optional. Fill the currency field of item records with CAD or USD for stores that do not state a country. Leave empty to derive the currency from each store's country automatically."
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Apify Proxy settings. Works on every proxy plan; the source is served through connection pools with automatic exit rotation."
          },
          "resumeFromRunId": {
            "title": "Resume from a previous run",
            "type": "string",
            "description": "Paste a previous run ID or dataset ID to continue a large pull without returning items already collected there."
          },
          "incrementalMode": {
            "title": "Incremental changes for scheduled runs",
            "type": "boolean",
            "description": "Turn this on for daily or recurring monitoring. The first run returns every matching record as NEW. Later runs normally return only NEW, UPDATED and REAPPEARED records. Turn on Emit unchanged or Emit expired only when you also want those rows returned (and billed). State is kept separately for each search, filter and lookup setup; use State key to name or deliberately share a monitoring campaign.",
            "default": false
          },
          "stateKey": {
            "title": "State key (optional, incremental mode only)",
            "type": "string",
            "description": "Optional. Name this monitoring campaign to keep its state stable, or deliberately share state across differently configured runs. Leave empty to let the actor derive a key automatically from the search and filter settings."
          },
          "emitUnchanged": {
            "title": "Emit unchanged records (incremental mode only)",
            "type": "boolean",
            "description": "Off by default. Turn on to also return records that have not changed since the last run, marked UNCHANGED. This returns, and bills, extra rows you already have.",
            "default": false
          },
          "emitExpired": {
            "title": "Emit expired records (incremental mode only)",
            "type": "boolean",
            "description": "Off by default. Turn on to also return records that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search.",
            "default": false
          },
          "ignoreFieldsForChanges": {
            "title": "Ignore fields when detecting changes (incremental mode only)",
            "type": "array",
            "description": "Output field names that should NOT make a record count as UPDATED. Always ignored: distanceKm, daysToExpiry, scrapedAt, queryLocation, apiUrl and the derived fields name, gtin, savings, departmentFr, address, website, itemCount and timezone (they depend on where or when you search, not on the deal). Add fields such as quantityAvailable here if changes to them are not relevant to you. Use a dotted path (for example raw.price) for a field inside a nested object. Ignored fields are still returned in the output.",
            "items": {
              "type": "string"
            }
          },
          "mcpConnectors": {
            "title": "Pipe results into your apps (optional)",
            "type": "array",
            "description": "Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify, Settings, API & Integrations, then select it here. Notion gets a rich page-per-item export; other connectors get a best-effort write or digest. Leave empty to skip; never changes the dataset output.",
            "items": {
              "type": "string"
            }
          },
          "notionParentPageUrl": {
            "title": "Notion parent page (Notion connector only)",
            "type": "string",
            "description": "URL or id of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors."
          },
          "maxNotifyListings": {
            "title": "Max items to export per connector",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "Cap on items written to each connector per run. Does not affect the dataset.",
            "default": 50
          }
        }
      },
      "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}