{
  "openapi": "3.0.1",
  "info": {
    "title": "Product Price Monitor & Scraper - WooCommerce, Schema.org",
    "description": "Product prices, stock, GTIN, brand and variants from WooCommerce stores (public Store API) and product pages with schema.org data (JSON-LD, microdata). One normalised format; monitor mode returns only price and stock changes. $0.001 per product.",
    "version": "1.1",
    "x-build-id": "4Jqm0gLtoWXFaq4X2"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/sophisticated_occasion~product-data-price-tracker/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-sophisticated_occasion-product-data-price-tracker",
        "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/sophisticated_occasion~product-data-price-tracker/runs": {
      "post": {
        "operationId": "runs-sync-sophisticated_occasion-product-data-price-tracker",
        "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/sophisticated_occasion~product-data-price-tracker/run-sync": {
      "post": {
        "operationId": "run-sync-sophisticated_occasion-product-data-price-tracker",
        "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": {
          "stores": {
            "title": "WooCommerce stores",
            "type": "array",
            "description": "Store domains or URLs of WooCommerce shops. The whole public catalog is read from the WooCommerce Store API (the storefront's own public API). Up to 500 per run.",
            "items": {
              "type": "string"
            }
          },
          "productUrls": {
            "title": "Product page URLs (any shop)",
            "type": "array",
            "description": "Product pages of any shop that publishes schema.org Product data (JSON-LD, microdata or OpenGraph product tags), which most shop systems do. Up to 10,000 per run.",
            "items": {
              "type": "string"
            }
          },
          "maxProductsPerStore": {
            "title": "Max products per store",
            "minimum": 1,
            "maximum": 25000,
            "type": "integer",
            "description": "Stops reading a store after this many products.",
            "default": 1000
          },
          "onlyChanges": {
            "title": "Monitor mode: only changes since the last run",
            "type": "boolean",
            "description": "Remembers every product in a named key-value store. The first run returns all products (changeType 'new'); later runs return only price drops/increases, back-in-stock/out-of-stock, new and removed products. You pay only for what is returned.",
            "default": false
          },
          "monitorName": {
            "title": "Monitor name",
            "type": "string",
            "description": "Use different names for separate monitors (lowercase letters, digits, dashes). Setting it turns on monitor mode."
          },
          "minPriceChangePercent": {
            "title": "Monitor: ignore price changes under X %",
            "minimum": 0,
            "maximum": 100,
            "type": "number",
            "description": "Monitor mode only. Price moves smaller than this percentage of the last reported price are not returned (and not charged). The baseline stays at the last reported price, so slow drifts are reported once they add up. Stock changes are always reported. 0 = report every change (default).",
            "default": 0
          },
          "minPriceChangeAmount": {
            "title": "Monitor: ignore price changes below this amount",
            "minimum": 0,
            "maximum": 1000000,
            "type": "number",
            "description": "Monitor mode only. Price moves smaller than this absolute amount (in the product's own currency, e.g. 0.50) are not returned. If both thresholds are set, a change must pass both. Stock changes are always reported. 0 = off (default).",
            "default": 0
          },
          "keepPriceHistory": {
            "title": "Monitor: keep a price history dataset",
            "type": "boolean",
            "description": "Monitor mode only. Appends one compact row per returned change (price, old price, % change, stock, time) to a named dataset 'product-tracker-<monitorName>-history' in your account, so you get a full price history across runs. Free (not charged); the dataset counts toward your own Apify storage.",
            "default": false
          },
          "alertMinDropPercent": {
            "title": "Monitor: alert on price drops of at least (%)",
            "minimum": 0,
            "maximum": 100,
            "type": "number",
            "description": "Monitor mode only. Each run writes an ALERTS record (key-value store) listing back-in-stock products and price drops of at least this percentage, ready for a webhook, Make, n8n or Zapier step. 0 = every price drop (default).",
            "default": 0
          },
          "discoverFromSitemap": {
            "title": "Discover product pages from the sitemap",
            "type": "boolean",
            "description": "Opt-in. For each site under 'stores', read robots-allowed sitemaps (and nested indexes), keep URLs matching productUrlPattern, then fetch those product pages for schema.org Product data. Sitemap fetches are free; you are charged only for products delivered. Off by default (existing behaviour unchanged).",
            "default": false
          },
          "productUrlPattern": {
            "title": "Sitemap: product URL pattern (regex)",
            "type": "string",
            "description": "Regular expression matched against each sitemap URL. Default 'product|/p/|/products/' keeps typical product paths and drops about/blog/category pages. Only used when discoverFromSitemap is on.",
            "default": "product|/p/|/products/"
          },
          "maxSitemapUrls": {
            "title": "Sitemap: max product URLs to discover per store",
            "minimum": 1,
            "maximum": 10000,
            "type": "integer",
            "description": "Stops sitemap discovery for a store after this many matching URLs. Only used when discoverFromSitemap is on.",
            "default": 500
          },
          "productFeeds": {
            "title": "Open product feed URLs (Google Merchant)",
            "type": "array",
            "description": "Opt-in. Public Google Merchant product feeds (RSS 2.0 with g: namespace, Atom, or CSV/TSV with Google Merchant column names; gzip OK). robots.txt is checked for every feed URL (fail-closed). Feed downloads are free; you are charged only for products delivered. Up to 100 feeds per run.",
            "items": {
              "type": "string"
            }
          },
          "maxFeedItems": {
            "title": "Max products per feed",
            "minimum": 1,
            "maximum": 50000,
            "type": "integer",
            "description": "Stops reading a product feed after this many products (after item_group_id grouping). Only used when productFeeds is set.",
            "default": 1000
          },
          "storeApis": {
            "title": "Platform store APIs (Magento GraphQL / Shopware Store API)",
            "type": "array",
            "description": "Opt-in. Magento 2 GraphQL (anonymous catalog reads) or Shopware 6 Store API (needs your sales-channel sw-access-key). robots.txt is checked fail-closed for /graphql and /store-api/*; API pages are free; you pay only for products delivered. Existing stores[] WooCommerce path is unchanged. Up to 100 entries. Use only on stores you own or have permission for (or vendor demos).",
            "items": {
              "type": "object",
              "properties": {
                "url": {
                  "title": "Store origin URL",
                  "type": "string",
                  "editor": "textfield",
                  "description": "Shop origin, e.g. https://shop.example (no path required)."
                },
                "platformApi": {
                  "title": "Platform API",
                  "type": "string",
                  "editor": "select",
                  "enum": [
                    "auto",
                    "magento-graphql",
                    "shopware-store-api"
                  ],
                  "enumTitles": [
                    "Auto-detect (Magento GraphQL, or Shopware if a key is set)",
                    "Magento 2 GraphQL",
                    "Shopware 6 Store API"
                  ],
                  "default": "auto",
                  "description": "auto tries Magento GraphQL; if shopwareAccessKey is set it uses Shopware first."
                },
                "shopwareAccessKey": {
                  "title": "Shopware sw-access-key (secret)",
                  "type": "string",
                  "editor": "textfield",
                  "description": "Optional per-store Shopware sales-channel key (overrides top-level shopwareAccessKey). Prefer the top-level secret field when you have one key. Never scraped from page source."
                }
              },
              "required": [
                "url"
              ]
            }
          },
          "shopwareAccessKey": {
            "title": "Shopware sw-access-key (secret)",
            "type": "string",
            "description": "Default Shopware 6 sales-channel access key for storeApis entries that need it (Admin > Sales Channels > API access, or a vendor-published demo key). Stored as a secret. Per-entry shopwareAccessKey overrides this. Never scraped from page source."
          },
          "includeVariants": {
            "title": "Include variants",
            "type": "boolean",
            "description": "Variants with attributes (size, colour...), SKU, GTIN, price and availability where the source provides them.",
            "default": true
          },
          "maxVariationsPerProduct": {
            "title": "WooCommerce: fetch prices for up to N variations per product",
            "minimum": 0,
            "maximum": 100,
            "type": "integer",
            "description": "The WooCommerce catalog lists variations without prices. Set > 0 to fetch each variation's price and stock (one extra request per variation, 1 per second per store).",
            "default": 0
          },
          "onlyInStock": {
            "title": "Only products in stock",
            "type": "boolean",
            "description": "Skip products that are known to be out of stock.",
            "default": false
          },
          "minQualityScore": {
            "title": "Minimum data-quality score (0-100)",
            "minimum": 0,
            "maximum": 100,
            "type": "integer",
            "description": "Skip (and do not charge for) products whose quality.score is lower, e.g. 70 drops records without a price or currency.",
            "default": 0
          },
          "includeDescription": {
            "title": "Include description text",
            "type": "boolean",
            "description": "Product description as plain text (HTML removed, e-mail addresses and phone numbers redacted, max 20,000 characters).",
            "default": false
          },
          "convertToEur": {
            "title": "Add EUR prices (ECB reference rates)",
            "type": "boolean",
            "description": "Adds priceEur / priceMinEur / priceMaxEur / regularPriceEur, fxDate and fxRate to every product, converted with the latest European Central Bank euro reference rates (about 30 currencies, updated each working day). One free fetch per run. Rates are for information only, not for transactions; source and free availability are stated in fxNote.",
            "default": false
          },
          "matchAcrossStores": {
            "title": "Compare the same product across stores",
            "type": "boolean",
            "description": "Opt-in. After all inputs are read, groups products from different stores that are the same item, by valid GTIN (UPC/EAN normalised to GTIN-14, check digit verified) or else exact brand + MPN. Titles are never compared. Adds matchGroup to each product and writes a free MATCHES record with lowest/highest price, cheapest store and price spread (prices compared in EUR with convertToEur, otherwise only within one currency). Free; billing unchanged. Products are saved at the end of the run.",
            "default": false
          },
          "ownStoreHosts": {
            "title": "Your own store host(s) for a price-position report",
            "type": "array",
            "description": "Opt-in, needs matchAcrossStores. Host(s) or URL(s) of your own shop (e.g. myshop.example; www. and paths are ignored, a port is kept). Writes a free PRICE_POSITION record: for every matched product your shop sells, your price vs the cheapest and the highest competitor, the difference in amount and %, and a position (cheapest, tied-cheapest, mid, most-expensive, only-offer, no-comparable-price). Ready for a webhook. Free; billing unchanged.",
            "items": {
              "type": "string"
            }
          },
          "merchantFeedExport": {
            "title": "Export a Google Merchant Center feed (your own shop)",
            "type": "boolean",
            "description": "Opt-in. Writes a free MERCHANT_FEED record (tab-separated, Google Merchant Center attribute names: id, title, description, link, image_link, availability, price, sale_price, brand, gtin, mpn, item_group_id, ...) from the products of this run, plus MERCHANT_FEED_ISSUES listing every product Google would reject and why. Meant for your own shop. Turn on includeDescription, because Google requires a description. Free; billing unchanged.",
            "default": 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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}