{
  "openapi": "3.0.1",
  "info": {
    "title": "LEGO Sale & Retiring Sets Monitor: Price Drop Alerts",
    "description": "LEGO.com sale and retiring-soon sets to Google Sheets or Discord: price, list price, % off, stock and the 'retiring soon' flag per set. Get alerts for new sales, price drops, sets just flagged retiring and back in stock. US, UK, Canada, Germany. No login, no images.",
    "version": "1.0",
    "x-build-id": "PMsnBAllzN9nWWRp1"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/accountable_eel~lego-sale-retiring-lookup/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-accountable_eel-lego-sale-retiring-lookup",
        "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/accountable_eel~lego-sale-retiring-lookup/runs": {
      "post": {
        "operationId": "runs-sync-accountable_eel-lego-sale-retiring-lookup",
        "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/accountable_eel~lego-sale-retiring-lookup/run-sync": {
      "post": {
        "operationId": "run-sync-accountable_eel-lego-sale-retiring-lookup",
        "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": {
          "lists": {
            "title": "LEGO.com lists to check",
            "type": "array",
            "description": "One list per line: sale, retiring-soon or new. Leave it as sale for the LEGO Sale page, add retiring-soon for the sets LEGO marks as retiring soon (the page LEGO calls Last chance to buy). A pasted LEGO.com category link is read for its list name. Prices and stock facts only: no images, no descriptions, no login. Accepted formats: sale, retiring-soon, new, https://www.lego.com/en-us/categories/sales-and-deals. You're only charged for the ones we actually find — a miss costs nothing.",
            "items": {
              "type": "string"
            }
          },
          "locale": {
            "title": "LEGO.com storefront",
            "enum": [
              "en-us",
              "en-gb",
              "en-ca",
              "de-de"
            ],
            "type": "string",
            "description": "Which LEGO.com storefront (and currency) to read. Sale: all four. Retiring soon: en-us, en-gb, de-de. New: en-us, de-de. A list a storefront does not serve is skipped with a note in the log.",
            "default": "en-us"
          },
          "maxItems": {
            "title": "Most sets per list",
            "type": "integer",
            "description": "Up to 300. Counted after your filters, per list, and it is your budget control: you pay per set returned. LEGO.com shows 19 to 24 sets per page, and the actor reads another page only while it needs more.",
            "default": 21
          },
          "minDiscountPct": {
            "title": "Only sets at least this % off",
            "type": "integer",
            "description": "Optional, 0 to 95. Applied here after the page is read (LEGO.com's page cannot filter by discount for us). 0 keeps every set, including full-price sets on the retiring list.",
            "default": 0
          },
          "themes": {
            "title": "Only these themes",
            "type": "array",
            "description": "Optional. One theme per line, e.g. Star Wars or Harry Potter. Case and the trademark sign do not matter; a line matches any theme that contains it. Applied here after the page is read.",
            "items": {
              "type": "string"
            }
          },
          "retiringOnly": {
            "title": "Only sets marked retiring soon",
            "type": "boolean",
            "description": "Keeps only sets LEGO.com flags 'Retiring soon'. Applied here after the page is read.",
            "default": false
          },
          "deltaMode": {
            "title": "Track changes between runs",
            "type": "boolean",
            "description": "Turns this into a watchlist. Each run compares every set with what the same watchlist saw last time and fills in 'Change since last run', 'Price last run', 'Price change %' and 'Lowest price seen'. By default only sets that changed in a way you asked for below come back, so a quiet run returns one summary row and bills nothing. Schedule it every few hours and send the alerts to Discord, Slack or Telegram with 'Send alerts to' below. The first run lists everything as new.",
            "default": false
          },
          "alertOn": {
            "title": "Alert on",
            "type": "array",
            "description": "One per line. new-sale (on sale and not before), price-drop, now-retiring (LEGO just flagged it), back-in-stock, gone (no longer on the list it was on; only trusted when the whole list was read). Leave the default for the first four.",
            "items": {
              "type": "string"
            }
          },
          "minPriceDropPct": {
            "title": "Smallest price drop to alert on (%)",
            "type": "integer",
            "description": "A set must be at least this much cheaper than when the watchlist last saw it to count as a price drop.",
            "default": 5
          },
          "alertOnChangeOnly": {
            "title": "Return only sets with an alert",
            "type": "boolean",
            "description": "On by default whenever monitoring is on: sets with no change you asked about are left out and not billed. Turn it off to get every set back each run, annotated with its change columns (and billed).",
            "default": true
          },
          "skipFirstRun": {
            "title": "Remember silently on the first run",
            "type": "boolean",
            "description": "The first run of a watchlist has nothing to compare with. Turn this on to remember every set without returning or billing it, so an alert link does not post the whole sale page.",
            "default": false
          },
          "deltaName": {
            "title": "Watchlist name (optional)",
            "type": "string",
            "description": "Leave empty and a name is derived from your lists, storefront and filters, so two schedules with different filters keep separate memories. Type your own name to keep one memory across changes.",
            "default": ""
          },
          "notifyUrl": {
            "title": "Send alerts to (Discord or Slack webhook, Telegram bot link, or any URL)",
            "type": "string",
            "description": "Optional. After the sets are billed, each alert set is posted here as one message: name, set number, price (and what it was), theme, pieces and link, with a NEW ON SALE / PRICE DROP -X% / NOW RETIRING SOON / BACK IN STOCK / GONE badge. No images. Discord or Slack: paste the channel's webhook URL. Telegram: https://api.telegram.org/bot<token>/sendMessage?chat_id=<chat id>. Any other URL receives JSON. Messages are free, and a message that fails never fails the run (the rows' 'Alert delivery errors' says why). Stored encrypted, never logged or written to the results."
          },
          "notifyFormat": {
            "title": "Message format",
            "enum": [
              "auto",
              "discord",
              "slack",
              "telegram",
              "json"
            ],
            "type": "string",
            "description": "Leave on auto and the format is detected from the link.",
            "default": "auto"
          },
          "maxNotificationsPerRun": {
            "title": "Most alert messages per run",
            "type": "integer",
            "description": "Up to 100. Above this, one '+N more' message says how many more alerts are in the run's dataset, so a busy first run never floods the channel. 0 sends only that summary.",
            "default": 20
          },
          "testRun": {
            "title": "Try it first — only process the first 5",
            "type": "boolean",
            "description": "Turn this on to test your input on a small sample before running the full list. Turn it off to process everything.",
            "default": false
          },
          "onlyFound": {
            "title": "Hide rows with no result",
            "type": "boolean",
            "description": "Only keep rows where something was actually found. Misses are always free, whether or not you show them here.",
            "default": false
          },
          "includeKeywords": {
            "title": "Only keep rows containing",
            "type": "array",
            "description": "Optional. Only keep results that mention at least one of these words (e.g. a job title, a city, a product name). Leave empty to keep everything.",
            "items": {
              "type": "string"
            }
          },
          "excludeKeywords": {
            "title": "Skip rows containing",
            "type": "array",
            "description": "Optional. Drop any result that mentions one of these words. Leave empty to skip nothing.",
            "items": {
              "type": "string"
            }
          },
          "maxResults": {
            "title": "Stop after this many results",
            "minimum": 1,
            "type": "integer",
            "description": "Optional. Stop the run once this many results have been found — useful for a quick, cheap sample. Leave blank for no limit."
          },
          "columns": {
            "title": "Which columns do you want?",
            "type": "array",
            "description": "Choose which pieces of information to include in each result row. All are included by default.",
            "items": {
              "type": "string",
              "enum": [
                "setCount",
                "setsRead",
                "listsChecked",
                "listsFailed",
                "truncated",
                "monitorStatus",
                "sets",
                "setNumber",
                "name",
                "theme",
                "url",
                "locale",
                "currency",
                "price",
                "listPrice",
                "discountPct",
                "retiringSoon",
                "featuredFlags",
                "availability",
                "canAddToBag",
                "pieces",
                "rating",
                "ageRange",
                "list",
                "listsFound",
                "checkedAt",
                "changeType",
                "changes",
                "previousPrice",
                "changePct",
                "lowestEverSeen",
                "firstSeenAt",
                "notifyErrors"
              ],
              "enumTitles": [
                "Sets returned",
                "Sets read",
                "Lists checked",
                "Lists that stopped early",
                "Stopped short",
                "Monitoring status",
                "All sets (full list)",
                "Set number",
                "Name",
                "Theme",
                "Product page",
                "Storefront",
                "Currency",
                "Price",
                "List price",
                "Discount %",
                "Retiring soon",
                "LEGO.com flags",
                "Availability",
                "Can add to bag",
                "Pieces",
                "Rating",
                "Age range",
                "List",
                "All lists it is on",
                "Checked at",
                "Change since last run",
                "All changes detected",
                "Price last run",
                "Price change %",
                "Lowest price seen",
                "First seen",
                "Alert delivery errors"
              ]
            },
            "default": [
              "setCount",
              "setsRead",
              "listsChecked",
              "listsFailed",
              "truncated",
              "monitorStatus",
              "sets",
              "setNumber",
              "name",
              "theme",
              "url",
              "locale",
              "currency",
              "price",
              "listPrice",
              "discountPct",
              "retiringSoon",
              "featuredFlags",
              "availability",
              "canAddToBag",
              "pieces",
              "rating",
              "ageRange",
              "list",
              "listsFound",
              "checkedAt",
              "changeType",
              "changes",
              "previousPrice",
              "changePct",
              "lowestEverSeen",
              "firstSeenAt",
              "notifyErrors"
            ]
          },
          "expandRows": {
            "title": "One row per set (recommended) — turn off for one row per LEGO.com list instead",
            "type": "boolean",
            "description": "When on, each set found gets its own row instead of being grouped under its LEGO.com list. You're still only charged once per LEGO.com list, no matter how many rows it produces.",
            "default": true
          },
          "maxConcurrency": {
            "title": "Max concurrency",
            "minimum": 1,
            "maximum": 1,
            "type": "integer",
            "description": "Parallel requests. Keep conservative — this target has no browser fallback, so getting blocked costs more than slow-and-steady.",
            "default": 1
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Apify Proxy config. Residential recommended for anti-bot-sensitive targets.",
            "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
                  },
                  "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}