{
  "openapi": "3.0.1",
  "info": {
    "title": "Shopify Product Monitor: Price Drops, Stock and New Products",
    "description": "Shopify products scraper and price monitor. Competitor price tracking for any store: one row per variant with price, compare-at price and stock, then only the price drops, back in stock alerts, new and removed products since the last run. Alerts to Discord, Slack or Telegram; rows to Google Sheets.",
    "version": "1.0",
    "x-build-id": "P2KYg1syVpUSZnWA1"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/accountable_eel~shopify-product-monitor/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-accountable_eel-shopify-product-monitor",
        "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~shopify-product-monitor/runs": {
      "post": {
        "operationId": "runs-sync-accountable_eel-shopify-product-monitor",
        "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~shopify-product-monitor/run-sync": {
      "post": {
        "operationId": "run-sync-accountable_eel-shopify-product-monitor",
        "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": [
          "stores"
        ],
        "properties": {
          "stores": {
            "title": "Shopify stores to read (domains or links)",
            "type": "array",
            "description": "One store per line: a domain such as allbirds.com, or a store link (a link ending in /collections/<handle> reads just that collection). Only public Shopify stores work; no login and no API key. Accepted formats: allbirds.com, gymshark.com, https://kyliecosmetics.com/collections/award-winners. You're only charged for the ones we actually find — a miss costs nothing.",
            "items": {
              "type": "string"
            }
          },
          "maxProducts": {
            "title": "Most products per store",
            "type": "integer",
            "description": "Products read per store, up to 10,000. Each product usually has several variants (sizes, colours) and you pay per variant row returned: a 250-product store returned between about 700 and 2,700 rows in testing. Lower this to cap the cost.",
            "default": 250
          },
          "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."
          },
          "collections": {
            "title": "Only these collections (optional)",
            "type": "array",
            "description": "Optional. Collection handles such as \"sale\" or \"new-arrivals\", or collection links, one per line. Leave empty to read each store's whole catalog. A store link that already ends in /collections/<handle> reads just that collection.",
            "items": {
              "type": "string"
            }
          },
          "deltaMode": {
            "title": "Only return variants that changed since the last run",
            "type": "boolean",
            "description": "Turns each store into a watchlist. The first run remembers every variant's price and stock; every later run returns only the variants that are new, cheaper, dearer, back in stock, out of stock or removed (pick which below). Unchanged variants are removed before you are billed, so a quiet run costs only the start fee. Schedule it hourly or daily and send the alerts to Discord, Slack or Telegram.",
            "default": false
          },
          "deltaName": {
            "title": "Watchlist name (optional)",
            "type": "string",
            "description": "Leave empty and a name is derived from your alert settings, so two schedules with different settings keep separate memories. Type your own name to keep one memory across a settings change, or to share it between schedules. Naming a watchlist with the checkbox above off returns every variant but still marks each one.",
            "default": ""
          },
          "alertOn": {
            "title": "Alert me on",
            "type": "array",
            "description": "Which changes count. Only these are returned and billed with monitoring on, and only these are sent as messages. A variant that changed in two ways (cheaper and back in stock) is one row whose changeType is the first match and whose changes lists both. Leave all selected to see everything.",
            "items": {
              "type": "string",
              "enum": [
                "new",
                "price-drop",
                "price-rise",
                "back-in-stock",
                "out-of-stock",
                "removed"
              ],
              "enumTitles": [
                "New variants",
                "Price drops",
                "Price rises",
                "Back in stock",
                "Out of stock",
                "Removed from the store"
              ]
            },
            "default": [
              "new",
              "price-drop",
              "price-rise",
              "back-in-stock",
              "out-of-stock",
              "removed"
            ]
          },
          "minPriceChangePct": {
            "title": "Smallest price change to count (percent)",
            "type": "integer",
            "description": "A price move smaller than this is ignored, so a 1 cent rounding change does not fire an alert. 0 counts every change. Applies to price drops and price rises.",
            "default": 0
          },
          "skipFirstRun": {
            "title": "Remember silently on the first run",
            "type": "boolean",
            "description": "Off by default: on the first run every variant counts as new and is billed. Turn this on to store the baseline and return nothing (no rows, no messages, no per-row charge) so alerts start with the second run.",
            "default": false
          },
          "quietRunOutput": {
            "title": "What a quiet monitoring run writes to the dataset",
            "enum": [
              "summary",
              "none"
            ],
            "type": "string",
            "description": "A quiet run is a store with no changes since the last run. \"One summary row\" keeps a row with monitorStatus NO_CHANGES so you can see the store was checked. \"Nothing\" writes zero items, so a bot or spreadsheet integration never has to skip rows. A store that failed still returns its error row.",
            "default": "summary"
          },
          "notifyUrl": {
            "title": "Send alerts to (Discord or Slack webhook, Telegram bot link, or any URL)",
            "type": "string",
            "description": "Optional. After the variants are billed, each changed variant is posted here as one message: photo, title, size or colour, price, stock and link, with a NEW / PRICE DROP -X% / BACK IN STOCK badge. 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 the alert as JSON. Messages are free, and a message that fails never fails the run (the row's notifyErrors says why). Stored encrypted, never logged or written to the results. Needs monitoring turned on."
          },
          "notifyFormat": {
            "title": "Message format",
            "enum": [
              "auto",
              "discord",
              "slack",
              "telegram",
              "json"
            ],
            "type": "string",
            "description": "Leave on \"Detect from the link\": discord.com links get Discord messages, hooks.slack.com Slack, api.telegram.org Telegram, anything else JSON. Pick one only to override that.",
            "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 variants are in the run's dataset, so a busy first run never floods the channel. 0 sends only that one summary message.",
            "default": 20
          },
          "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": [
                "store",
                "currency",
                "currencySource",
                "productCount",
                "totalVariants",
                "variantCount",
                "truncated",
                "truncatedBy",
                "monitorStatus",
                "newCount",
                "priceDropCount",
                "priceRiseCount",
                "backInStockCount",
                "outOfStockCount",
                "removedCount",
                "variants",
                "productId",
                "variantId",
                "title",
                "variantTitle",
                "vendor",
                "productType",
                "tags",
                "handle",
                "url",
                "sku",
                "price",
                "compareAtPrice",
                "discountPct",
                "available",
                "imageUrl",
                "publishedAt",
                "updatedAt"
              ],
              "enumTitles": [
                "Store",
                "Currency",
                "Currency read from",
                "Products read",
                "Variants read",
                "Variants returned (billed)",
                "Stopped short of the whole catalog",
                "Why it stopped short",
                "Monitoring status",
                "New variants",
                "Price drops",
                "Price rises",
                "Back in stock",
                "Went out of stock",
                "Removed variants",
                "All variants (grouped mode)",
                "Product ID",
                "Variant ID",
                "Product title",
                "Variant (size, colour)",
                "Vendor",
                "Product type",
                "Tags",
                "URL handle",
                "Product link",
                "SKU",
                "Price",
                "Compare-at price",
                "Discount %",
                "In stock",
                "Image",
                "Published",
                "Updated"
              ]
            },
            "default": [
              "store",
              "currency",
              "currencySource",
              "productCount",
              "totalVariants",
              "variantCount",
              "truncated",
              "truncatedBy",
              "monitorStatus",
              "newCount",
              "priceDropCount",
              "priceRiseCount",
              "backInStockCount",
              "outOfStockCount",
              "removedCount",
              "variants",
              "productId",
              "variantId",
              "title",
              "variantTitle",
              "vendor",
              "productType",
              "tags",
              "handle",
              "url",
              "sku",
              "price",
              "compareAtPrice",
              "discountPct",
              "available",
              "imageUrl",
              "publishedAt",
              "updatedAt"
            ]
          },
          "expandRows": {
            "title": "One row per variant (recommended) — turn off for one row per store instead",
            "type": "boolean",
            "description": "When on, each variant found gets its own row instead of being grouped under its store. You're still only charged once per store, no matter how many rows it produces.",
            "default": true
          },
          "maxConcurrency": {
            "title": "Max concurrency",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "Parallel requests. Keep conservative — this target has no browser fallback, so getting blocked costs more than slow-and-steady.",
            "default": 5
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Optional. Off by default: Shopify stores answer ordinary requests, so most runs need no proxy. If a store comes back as BLOCKED, switch on Apify Proxy (datacenter). Avoid Residential: every catalog page is about 1.8 MB.",
            "default": {
              "useApifyProxy": false
            }
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}