# Watch Digest: Price, Stock & Rank Changes (`cleanpull/watch-digest`) Actor

One schedule for your whole watchlist: runs CleanPull's store, Amazon, rank, Shopify, reviews, promotions and marketplace watchers and sends one digest of what changed (price, stock, rank, reviews, sales, new entrants) by email, Slack, Discord, Teams or webhook. $5 per 1,000 digests.

- **URL**: https://apify.com/cleanpull/watch-digest.md
- **Developed by:** [CleanPull](https://apify.com/cleanpull) (community)
- **Categories:** E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 digests

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Watch Digest: Price, Stock & Rank Changes

One schedule for your whole watchlist. Give it product pages from **any online store**, **Amazon products**, **Amazon keywords** for your own products, **whole Shopify stores**, products whose **reviews** you follow, stores whose **promotions and launches** you follow, **marketplace searches** (Amazon, eBay, Etsy, Walmart, Target, Best Buy), advertisers whose **ads** you follow (Google, Meta, TikTok), **TikTok Shop keywords** (units sold per day), **Amazon Best Sellers charts** and **Google Trends terms** for your niches; it runs CleanPull's watchers for each and sends **one digest of what changed** (price, stock, sale, Buy Box, sellers, rank, new and removed products, new reviews and rating moves, sales and codes that start or end, new entrants and price-band moves, ads that start or stop, TikTok Shop sales per day, chart entries and climbers, new rising searches and interest moves) by **email** (through your own Resend, Postmark, SendGrid or SMTP account), **Slack**, **Discord**, **Microsoft Teams** or **any webhook**. **$5 per 1,000 digests**, plus what each watcher reads at its own price.

### What you can do with it

- **"Every morning, tell me what my competitors changed."** Add their product pages and stores, schedule it daily, and get one email or Slack message with every price move, sale and stock change across all of them.
- **"Watch my Amazon listings and where they rank."** Your ASINs for Buy Box, price, sellers and Best Sellers Rank; your keywords for organic and sponsored place, with milestones (entered the top 10, reached page 1).
- **"Tell me when reviews turn, a competitor starts a sale, or someone new enters my search."** Product pages for new reviews, rating moves and the top complaint themes; competitor stores for codes, free-shipping offers and launches; keywords for new listings in the top results and moves in the price band.
- **"How fast is it selling, and what is climbing?"** TikTok Shop keywords for each top product's units per day speeding up or slowing down (from the third run), products new to the keyword and price moves; Amazon Best Sellers or New Releases categories for new entries, climbers and, if you want, brands entering.
- **"Every week, what is taking off in my niches?"** Google Trends terms, Amazon chart categories and TikTok Shop keywords in one watchlist give one **Opportunities this week** section at the top of the digest: new rising searches and breakouts first, then new entries on the charts, then products selling faster on TikTok Shop.
- **"Only bother me when something happened."** A quiet run sends nothing (unless you turn on Send when nothing changed).
- **"Only tell me about the bad reviews, the real price cuts and the big rank moments."** Alert settings narrow what your email or chat gets: reviews under N stars, price drops of at least N% in store products and Shopify stores, rank milestones only. Every change is still in the run's dataset.
- **"Several watchlists, one account."** Each Watchlist name keeps its own history, so a client's or a brand's digest never mixes with another.

### How it works

1. Each watcher you gave items to runs once, all at the same time, in Changes only mode, under this watchlist's name: [Any Store Product Monitor](https://apify.com/cleanpull/any-store-product-monitor) for product pages, [Amazon Product Scraper](https://apify.com/cleanpull/amazon-product-scraper) for ASINs, [Amazon Keyword Rank Tracker](https://apify.com/cleanpull/amazon-keyword-rank-tracker) for keywords, [Shopify Store Scraper](https://apify.com/cleanpull/shopify-store-scraper) for stores, [Reviews Monitor](https://apify.com/cleanpull/reviews-monitor) for reviews, [Promotions Monitor](https://apify.com/cleanpull/promotions-monitor) for promotions and launches, [Marketplace Search Scanner](https://apify.com/cleanpull/marketplace-search-scanner) for marketplace searches, [Ad Library Monitor](https://apify.com/cleanpull/ad-library-monitor) for ads, [TikTok Shop Sales Tracker](https://apify.com/cleanpull/tiktok-shop-sales-tracker) for TikTok Shop keywords, [Amazon Best Sellers Tracker](https://apify.com/cleanpull/amazon-bestsellers-tracker) for Amazon charts, and [Google Trends Scraper](https://apify.com/cleanpull/google-trends-scraper) for Google Trends terms.
2. Their changes are put in one shape (what changed, the item, from → to, the link) and grouped by watcher into a digest. Signs of a product on the rise (rising searches, chart new entries, TikTok Shop products speeding up) come first, under **Opportunities this week**; the changes listed are split in half between the opportunities (they get the odd place) and the other watchers' changes, and a side with fewer changes than its half leaves its places to the other, so price drops and stock moves are never pushed out; the opportunity places go in turn to rising searches, chart entries and TikTok, so each group with changes is shown.
3. [Alerts Sender](https://apify.com/cleanpull/alerts-sender) delivers it to every channel you filled in: a short summary (changes per watcher, and anything not checked) with the changes as a table.

The first run reads everything once and says how many items are now watched; changes appear from the second run. A Shopify store (or a store whose promotions you follow) added to a watchlist later is read the same way on its first run, without the other stores' changes being lost.

### What makes it dependable

- **As fast as the slowest watcher.** The watchers run side by side, so a digest takes about as long as its slowest watcher, not the sum of all of them.
- **Your spending limit covers the whole digest.** Each watcher gets a share of the limit you set for the run (after this run's own events) in proportion to what it is expected to cost at its own prices, what each one charges is counted, and Alerts Sender gets what is left. A watcher stopped at its share or its time limit still reports what it read, with a note. A scheduled run often has no spending limit of its own: set Max cost per run, and the digest holds itself to that the same way. Reviews Monitor, Promotions Monitor and Marketplace Search Scanner also get their share as their own Max cost per run, so they stop cleanly before an item they could not finish. Each of them first gets enough to start one item; if the limit cannot cover that, it is not started, and the digest says how much Max cost per run would fit them all. Their items are taken in a different order each run, so one held to its share does not leave the same items out every time.
- **Safe to restart.** If Apify moves the run to another server, or you resurrect it, it picks up where it was: it waits on the watchers it already started, and never stores, sends or bills the digest twice. If you abort the digest, the watchers and the delivery it started are aborted too.
- **One watcher failing never stops the digest.** It goes out with the others' changes and a "Not checked this time" section that says why.
- **Delivery you can check.** The digest row says whether it was sent, partly sent or failed, with each channel's reason from Alerts Sender (a wrong key, a webhook that answered 404).
- **Email settings checked first.** A missing sender, key or SMTP login stops the run before any watcher spends anything.
- **Safe to forward.** Product names and values come from other sites, so the characters that make links, bold text or mentions are softened before the digest is rendered: a product named `[click](…)` cannot become a disguised link.
- **Everything is kept.** Every change is a row in the run's dataset; the digest is saved as `DIGEST.md` and `DIGEST` (JSON) in the run's key-value store. Up to 20,000 rows are read from each watcher; past that, the digest says so.
- **Runs light.** The digest runs at 128 MB with a 2-hour timeout; each watcher runs at its own default memory, with a timeout that leaves the digest time to read and deliver.

### Input

| Field                                                                              | What it does                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| ---------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `title`, `monitorName`                                                             | The digest's name (in the subject) and the watchlist name runs compare under                                                                                                                                                                                                                                                                                                                                                                                          |
| `productUrls`                                                                      | Product pages on any store (Shopify, WooCommerce, Magento, Wix…)                                                                                                                                                                                                                                                                                                                                                                                                      |
| `amazonAsins`, `amazonMarketplace`                                                 | Amazon products (ASINs or URLs) and their marketplace                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `rankKeywords`, `rankAsins`, `rankMarketplace`                                     | Keywords, the ASINs whose place is tracked for each, and the marketplace                                                                                                                                                                                                                                                                                                                                                                                              |
| `rankSponsored`                                                                    | On by default: also the ad (sponsored) place. Off: organic rank only, cheaper (the ads are read through residential addresses, most of a search page's cost)                                                                                                                                                                                                                                                                                                          |
| `shopifyStores`, `maxProductsPerStore`                                             | Whole Shopify stores (brand.com), and how many products to watch in each                                                                                                                                                                                                                                                                                                                                                                                              |
| `shopifyIncludeStock`                                                              | Off by default. Optional, paid: stock per variant and, from the second run, units sold and sales per day where the store publishes stock (+$0.50 per 1,000 products read)                                                                                                                                                                                                                                                                                             |
| `reviewProductUrls`, `reviewAsins`, `reviewTrustpilotDomains`, `reviewMarketplace` | Products whose reviews are watched: pages on shops using Judge.me, Yotpo, Okendo, Loox or Stamped, ASINs with their marketplace, and Trustpilot businesses (domains or review pages); at most 1,000                                                                                                                                                                                                                                                                   |
| `promotionStores`                                                                  | Stores (any platform) whose sales, codes, free-shipping offers and launches are watched (at most 200)                                                                                                                                                                                                                                                                                                                                                                 |
| `marketKeywords`, `marketSources`, `marketAmazonMarketplaces`                      | Marketplace searches: keywords, where (Amazon, eBay, Etsy, Walmart, Target, Best Buy) and which Amazon countries (at most 300 keyword × marketplace searches)                                                                                                                                                                                                                                                                                                         |
| `adAdvertisers`, `adKeywords`, `adGoogleAdvertiserIds`, `adMetaPageIds`            | Ads to watch: brands or domains, words in the ads (Meta, TikTok), Google advertiser ids and Meta page ids (at most 200 watch items)                                                                                                                                                                                                                                                                                                                                   |
| `adPlatforms`, `adCountries`                                                       | Where (Google, Meta, TikTok) and in which countries (at most 5)                                                                                                                                                                                                                                                                                                                                                                                                       |
| `tiktokKeywords`, `tiktokMaxProductsPerKeyword`                                    | TikTok Shop US keywords (at most 100) and the top products watched in each (default 20)                                                                                                                                                                                                                                                                                                                                                                               |
| `chartCategories`, `chartTypes`, `chartMarketplaces`, `chartMaxItemsPerChart`      | Amazon chart categories (slugs, names or department/node), which charts (Best Sellers and New Releases by default), which Amazon countries (US by default) and ranks per chart (default 100); at most 200 charts                                                                                                                                                                                                                                                      |
| `chartMinRankChange`, `chartProductDetailsTopN`                                    | The smallest climb reported (default 10 places); optional, paid: product pages for the top N per chart, so brands entering can be named (0, off, by default)                                                                                                                                                                                                                                                                                                          |
| `trendsTerms`, `trendsGeo`, `trendsTimeRange`, `trendsMinInterestChangePercent`    | Google Trends terms for your niches (at most 100), the location (the form prefills US; clear it or write worldwide for worldwide, which is also what an API input without it gets), the period (past 90 days by default) and the smallest interest move reported (50% by default: the term's latest quarter of the period against its earliest, once per crossing; after a crossing the term must come back 10 points inside the threshold before it can cross again) |
| `minPriceChangePercent`                                                            | Ignore smaller price moves, in every watcher (for marketplace price bands, 10% when this is 0)                                                                                                                                                                                                                                                                                                                                                                        |
| `maxRunCostUsd`                                                                    | Optional. Max cost per run: the most one digest may cost in all (its events, the watchers and the delivery). For scheduled runs, which may have no spending limit of their own                                                                                                                                                                                                                                                                                        |
| `alertBelowRating`, `alertPriceDropPercent`, `alertRankMilestonesOnly`             | Optional alert settings, off by default: the channels get only new reviews under N stars (and ratings that fell under it), price drops of at least N% (store products and Shopify stores), and Amazon rank milestones; the rest stays in the dataset and `DIGEST.md`                                                                                                                                                                                                  |
| `sendWhenNoChanges`, `maxChangesShown`                                             | Send a "no changes" digest too; how many changes the message lists (all are in the dataset)                                                                                                                                                                                                                                                                                                                                                                           |
| `emailTo`, `emailCc`, `emailBcc`, `emailSeparately`                                | Recipients (at most 50); each "to" recipient gets their own email unless you add CCs or turn it off                                                                                                                                                                                                                                                                                                                                                                   |
| `emailFrom`, `emailReplyTo`, `emailProvider`, `emailApiKey`                        | A sender on your own domain, and your Resend, Postmark or SendGrid key                                                                                                                                                                                                                                                                                                                                                                                                |
| `smtpHost`, `smtpPort`, `smtpSecure`, `smtpUser`, `smtpPassword`                   | Or any SMTP server with a login, over TLS                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `slackWebhookUrl`, `discordWebhookUrl`, `teamsWebhookUrl`, `webhookUrl`            | Chat webhooks and any other endpoint                                                                                                                                                                                                                                                                                                                                                                                                                                  |

With no channel, the digest is stored in the run but not sent.

#### Example input

Competitors' products and your Amazon ranks, to Slack every morning:

```json
{
  "title": "Morning watch",
  "monitorName": "competitors",
  "productUrls": ["https://www.allbirds.com/products/mens-tree-runners"],
  "rankKeywords": ["wool sneakers"],
  "rankAsins": ["B0XXXXXXXX"],
  "minPriceChangePercent": 2,
  "slackWebhookUrl": "https://hooks.slack.com/services/…"
}
```

Your niches' opportunities, to email every Monday (schedule it weekly):

```json
{
  "title": "Kitchen opportunities",
  "monitorName": "kitchen",
  "trendsTerms": ["air fryer liners", "mushroom coffee"],
  "chartCategories": ["kitchen"],
  "chartTypes": ["new-releases", "movers-and-shakers"],
  "tiktokKeywords": ["air fryer"],
  "maxRunCostUsd": 0.5,
  "emailTo": ["you@example.com"],
  "emailFrom": "digest@your-domain.com",
  "emailApiKey": "re_…"
}
```

### Output

One row per change:

```json
{
  "recordType": "change",
  "source": "stores",
  "what": "Price",
  "title": "Men's Tree Runners",
  "keyword": null,
  "from": 110,
  "to": 98,
  "detail": "USD 110 → USD 98 (-10.9%)",
  "url": "https://www.allbirds.com/products/mens-tree-runners",
  "at": "2026-10-14T08:00:00.000Z"
}
```

and one `digest` row with the subject, the counts, each watcher's run and outcome, the delivery status and the markdown.

### Pricing

| Event        | Free and Bronze | Silver          | Gold and above  |
| ------------ | --------------- | --------------- | --------------- |
| Digest       | $5.00 per 1,000 | $4.50 per 1,000 | $4.00 per 1,000 |
| Item watched | $0.25 per 1,000 | $0.22 per 1,000 | $0.20 per 1,000 |

An item is something a watcher actually checked (a watcher stopped early is billed only for what it read):

| Watcher                     | One item                                                                  |
| --------------------------- | ------------------------------------------------------------------------- |
| Any Store Product Monitor   | a product page                                                            |
| Amazon Product Scraper      | an ASIN                                                                   |
| Amazon Keyword Rank Tracker | a keyword × ASIN pair                                                     |
| Shopify Store Scraper       | up to 250 products of a store                                             |
| Reviews Monitor             | a product (page or ASIN) or a Trustpilot business whose reviews were read |
| Promotions Monitor          | a store whose promotions and launches were checked                        |
| Marketplace Search Scanner  | a search: one keyword on one marketplace                                  |
| Ad Library Monitor          | a watch item on one platform, per 100 ads read                            |
| TikTok Shop Sales Tracker   | a keyword read (none when the run stopped at its share)                   |
| Amazon Best Sellers Tracker | a chart read: one category × chart × marketplace                          |
| Google Trends Scraper       | a term read in its location                                               |

Each run also has a $0.00005 start fee. The watchers charge their own events in their own runs (for example $1.50 per 1,000 store products, $3 per 1,000 Amazon products, $3 per 1,000 review summaries with $0.50 per 1,000 reviews (and on Trustpilot $3 per 1,000 records and per read), $2 per 1,000 promotions or launches, $3 per 1,000 keyword summaries (and on eBay, Etsy, Walmart, Target and Best Buy $3 per 1,000 records and $0.015 per marketplace searched), and less for an item checked with no change), and Alerts Sender charges $1 per 1,000 messages delivered; all of it counts against this run's spending limit. Each watcher's share of the limit follows what it is expected to cost at its own prices: a product or ASIN is one of its main events (an ASIN outside the US two, with its $0.003 local-market event; a Walmart, Target, Best Buy, eBay or Etsy product three, with its record, and $0.015 per such marketplace), an Amazon keyword about 4 search pages, a Shopify item 250 products, and for the newer watchers their first run, the dearest: a reviews product what Reviews Monitor needs free before it starts one ($0.037: a summary, 20 reviews and its worst case of residential requests; a Trustpilot business $0.0235: a summary, 5 reviews with their records and the read), a promotions store a page check and about 12 rows, a marketplace search what Marketplace Search Scanner needs free before it starts one ($0.049 on Amazon; $0.166 on eBay, Etsy, Walmart, Target and Best Buy: 48 records, the search fee, the summary and the change rows), and an ad watch item a full first run: its check and 100 ad rows ($0.151) plus the most library requests Ad Library Monitor may need for it at $3.50 per 1,000 (5 per country on Meta, 10 on TikTok, and up to 6 on Google, which uses the service only when Google declines a run). Once an ad watch item has been read whole (it is in the digest's memory), it counts at its steady state instead: its check, room for 20 new or stopped ads and 2 library requests ($0.038; never less than what Ad Library Monitor holds before it reads the item), so a watchlist past its first run needs a much smaller Max cost per run. These amounts, plus each run's start fee and 5%, are caps on each watcher, not what it spends: a product checked with no change costs Reviews Monitor $0.0005. **Setting Max cost per run:** about 1.5× a typical run, plus room for each newer watcher's least share: for ads $0.18 per watchlist on the first run (the baseline) and about $0.05 after it; for reviews $0.04 and for a marketplace search $0.05 on Amazon or $0.17 elsewhere on every run (those watchers hold that much before each item, whatever their history). A daily digest of 20 review products, 10 stores and 10 searches is 40 items a day: about $0.30 a month of item events plus $0.15 of digests, and the watchers' own events. TikTok Shop Sales Tracker charges $3 per 1,000 products delivered ($0.50 per 1,000 unchanged), so a keyword's first run is its top products in full (20 by default, $0.06) and later runs the ones that sold or changed; Amazon Best Sellers Tracker charges $1.50 per 1,000 ranks on a chart's first run ($0.15 for 100), then $2 per 1,000 moves and $0.10 per 1,000 unchanged (about $0.03 a chart a day), plus $0.002 a chart summary and, if asked, $0.004 a product page. Google Trends Scraper charges $1.50 per 1,000 terms (every term is read each run: a weekly digest of 20 terms is $0.03 a run in its events and $0.005 in item events). These three are weighed by their first run and get their share as their spending limit; they take no Max cost per run of their own and stop cleanly at it, keeping what they did not deliver for the next run (a Google Trends term not read is compared on the next run; its terms are taken in a different order each run). A run where no watcher could run is not charged.

### Limits

- **Email needs your own provider account** and a sender on a domain it lets you send from.
- **Rank keywords need your ASINs** (Rank: your ASINs); keywords alone are skipped with a warning. At most 300 keywords in one digest.
- **Promotions:** Amazon, Walmart and Target are not read. **Reviews:** Trustpilot businesses by domain or review page; a watchlist keeps the newest 5 reviews per business.
- **Ads:** a watch item's first run is its baseline: every active ad, up to 100. Meta and TikTok need no credentials of your own (Ad Library Monitor reads them through an ad library service, billed per request).
- **The watchers' own limits apply**, for example Amazon search pages for a ZIP code need sign-in and are not read. See each watcher's page.
- **TikTok Shop** is US only. A product's first units per day (its second run) is the baseline; speed-ups and slow-downs are reported from the third run. **Amazon charts:** brands entering need product pages (`chartProductDetailsTopN`); without them, new entries and climbers are reported.
- **Google Trends** values are relative (0-100 within the period), so an interest move is the term's own latest quarter against its earliest, not search counts. A term's interest and its related searches each have their baseline the first time they come (nothing reported for them that run); related searches set their baseline only once Google returns some (an empty list, usual for low-volume terms, or none returned at all, leaves the term watched on its interest only, and the digest says which); a term with no usable interest and no related-searches baseline yet is noted as not checked. A term rising from no measurable interest at the start of the period is reported as rising, and again only after 2 runs in a row without that rise (the same for a fall). A term's memory is updated only once the digest reached every channel (a failed or partial delivery brings the same changes again next run, to every channel). A term is billed as an item watched only when it was compared or baselined, and only on a run whose digest reached every channel (otherwise it is compared and billed again on the run that delivers, and the digest's notes say so). Give terms one per line: a term may contain commas.
- **One history per watchlist name.** Items added to a watchlist show as newly watched on their first run, and changes from the next.
- **Nothing watched**: when no watcher could start because of your spending limit or too little of the run's time, the run still succeeds, with a free `recordType: "unreadable"` row per watcher giving the `reason`; nothing is charged. A run whose watchers all failed still fails.

### Changelog

- **0.1.x, reliability** (2026-10-24): watchers not started for the spending limit or the time left end the run SUCCEEDED with a row each saying why, instead of FAILED; input that cannot work is explained in a free row. Prices unchanged.

- **0.1.x** (2026-10-23): Google Trends terms (`trendsTerms`, `trendsGeo`, `trendsTimeRange`, `trendsMinInterestChangePercent`, read by Google Trends Scraper): new rising related searches and breakouts since the last run, and interest moves past a threshold. Rising searches, chart new entries and TikTok Shop products speeding up open the digest under **Opportunities this week**. Billed as items watched, like the other watchers. Existing inputs work unchanged.

- **0.1.x** (2026-10-16): `rankSponsored` (off: organic-only rank watch, cheaper) and `shopifyIncludeStock` (stock and sales per day for Shopify stores, $0.50 per 1,000 products more). Defaults keep existing digests as they were.

- **0.1.x** (2026-10-16): alert settings (`alertBelowRating`, `alertPriceDropPercent`, `alertRankMilestonesOnly`): the digest sent to your channels carries only the changes you asked for, with a line saying how many more are in the dataset. Off by default; existing inputs work unchanged.

- **0.1.x** (2026-10-16): two new watchers: TikTok Shop keywords (TikTok Shop Sales Tracker: units per day, products new to a keyword, price moves) and Amazon charts (Amazon Best Sellers Tracker: new entries, re-entries, climbers, and brands entering with product pages on). Existing inputs work unchanged.

- **0.1.x** (2026-10-16): an ad watch item already read whole is given its steady-state share (its check, 20 ad rows and 2 library requests, at least what Ad Library Monitor holds), not a full first run, so watchlists past their baseline run under a smaller Max cost per run; new items keep the full first-run share. Amazon ASINs outside the US weigh in their local-market event. Existing inputs work unchanged.

- **0.1.x** (2026-10-15): marketplace searches on Walmart, Target and Best Buy, and eBay and Etsy without your own keys (Marketplace Search Scanner 0.2); Trustpilot businesses for reviews (Reviews Monitor 0.2); shares follow those watchers' live prices. Inputs that still carry the old eBay and Etsy key fields work unchanged (those fields are ignored).

- **0.1.x** (2026-10-15): ads on Meta and TikTok without your own credentials (Ad Library Monitor 0.2); shares count its library requests. Inputs that still carry the old Meta and TikTok credential fields work unchanged (those fields are ignored).

- **0.1.x** (2026-10-15): ads watcher (Ad Library Monitor): ads that start or stop on Google, Meta and TikTok, billed per watch item read, with Meta and TikTok credentials passed through as secrets.

- **0.1.x** (2026-10-14): three new watchers: reviews (Reviews Monitor), promotions and launches (Promotions Monitor) and marketplace searches (Marketplace Search Scanner), each billed per item checked and given its share as its own Max cost per run (at least enough to start one item). Links in the table sent to Alerts Sender are http(s) only. Existing inputs work unchanged.

- **0.1.x** (2026-10-14): stopped-early notes count the items actually missed (none when all were checked) and show small shares to 4 decimals.

- **0.1.x** (2026-10-14): Max cost per run (`maxRunCostUsd`): the whole digest (watchers and delivery included) stays within it, for scheduled runs without a spending limit.

- **0.1** (October 2026): store products, Amazon products, Amazon keyword ranks and Shopify stores in one digest; email, Slack, Discord, Teams and webhook delivery through Alerts Sender; spending limit shared across watchers.

# Actor input Schema

## `title` (type: `string`):

The digest's name, used in its subject line.

## `monitorName` (type: `string`):

Runs with the same name compare against each other. Use one name per watchlist.

## `productUrls` (type: `array`):

Product page URLs from any shop (Shopify, WooCommerce, Magento, Wix…), checked with Any Store Product Monitor for price, stock, sale, variant and page changes.

## `amazonAsins` (type: `array`):

ASINs or Amazon product URLs, checked with Amazon Product Scraper for price, Buy Box, stock, rank, rating and seller changes.

## `amazonMarketplace` (type: `string`):

For the ASINs above: US, GB, DE, FR, JP…

## `rankKeywords` (type: `array`):

Search keywords (at most 300) whose rank for your products is watched with Amazon Keyword Rank Tracker (needs Rank: your ASINs).

## `rankAsins` (type: `array`):

Your products whose organic and sponsored place is tracked for each keyword above.

## `rankMarketplace` (type: `string`):

For the keywords above.

## `rankSponsored` (type: `boolean`):

Also record each product's ad (sponsored) place. Off: organic rank only, which costs less (Amazon Keyword Rank Tracker reads the ads through residential addresses).

## `shopifyStores` (type: `array`):

Store addresses (brand.com), watched with Shopify Store Scraper for new and removed products, price moves, discounts and stock.

## `maxProductsPerStore` (type: `integer`):

At most this many products watched in each Shopify store (each one read is billed by Shopify Store Scraper).

## `shopifyIncludeStock` (type: `boolean`):

Optional, paid: exact stock per variant where the store publishes it and, from the second run, units sold and sales per day (Shopify Store Scraper's stock add-on, $0.50 per 1,000 products).

## `reviewProductUrls` (type: `array`):

Product pages on shops using Judge.me, Yotpo, Okendo, Loox or Stamped (or Amazon product URLs, or Trustpilot review pages), watched with Reviews Monitor for new reviews, rating moves and review-count jumps, with the top complaint themes.

## `reviewAsins` (type: `array`):

ASINs whose rating and new top reviews are watched with Reviews Monitor.

## `reviewTrustpilotDomains` (type: `array`):

Business domains (brand.com) or Trustpilot review pages (trustpilot.com/review/brand.com), whose Trustpilot reviews and rating are watched with Reviews Monitor.

## `reviewMarketplace` (type: `string`):

For the review ASINs above: US, GB, DE, FR, JP…

## `promotionStores` (type: `array`):

Store addresses (brand.com, any platform), watched with Promotions Monitor for sales, codes and free-shipping offers that start or end, and for new products and collections. At most 200.

## `marketKeywords` (type: `array`):

Search keywords watched with Marketplace Search Scanner for new entrants in the top results, new sellers and price-band moves, on Amazon, eBay, Etsy, Walmart, Target or Best Buy. At most 300 searches (keywords × marketplaces).

## `marketSources` (type: `array`):

Where the keywords above are searched. eBay, Etsy, Walmart, Target and Best Buy are read through CleanPull's marketplace data service; no keys of your own.

## `marketAmazonMarketplaces` (type: `array`):

Amazon countries to search: US, GB, DE, JP… (default US). Each one is a search per keyword.

## `adAdvertisers` (type: `array`):

Brand names or domains (allbirds.com) whose ads are watched with Ad Library Monitor on Google's Ads Transparency Center, the Meta Ad Library and the TikTok Ad Library, for ads that start or stop.

## `adKeywords` (type: `array`):

Words in the ads' text, watched on Meta and TikTok (Google is searched by advertiser only).

## `adGoogleAdvertiserIds` (type: `array`):

Google advertiser ids (AR…) or Ads Transparency Center addresses.

## `adMetaPageIds` (type: `array`):

Meta page ids, or Meta Ad Library addresses with view_all_page_id.

## `adPlatforms` (type: `array`):

Where the ads above are watched. Each watch item on each platform is an item.

## `adCountries` (type: `array`):

Optional. Two-letter country codes (at most 5) the ads are watched in; empty is anywhere the platform covers.

## `tiktokKeywords` (type: `array`):

Shopping terms on TikTok Shop US (at most 100). Each keyword is an item: its products' units per day speeding up or slowing down (from the third run), products new to it, and price moves, read by TikTok Shop Sales Tracker ($3 per 1,000 products delivered; $0.50 per 1,000 unchanged).

## `tiktokMaxProductsPerKeyword` (type: `integer`):

The top products watched per TikTok Shop keyword. The first run delivers all of them (the baseline); later runs the ones that sold or changed.

## `chartCategories` (type: `array`):

Department slugs (kitchen, toys-and-games), names (Toys & Games) or department/node for a subcategory (kitchen/289728), read by Amazon Best Sellers Tracker: new entries, re-entries, climbers and brands entering. Each category × chart × marketplace is an item (at most 200).

## `chartTypes` (type: `array`):

Which charts of each category are watched.

## `chartMarketplaces` (type: `array`):

Optional. Amazon countries (US, GB, DE, FR, JP…) for the charts; empty is US.

## `chartMaxItemsPerChart` (type: `integer`):

How many ranks of each chart are watched. The first run delivers all of them ($1.50 per 1,000), later runs only the moves ($2 per 1,000; $0.10 per 1,000 unchanged).

## `chartMinRankChange` (type: `integer`):

A product that climbed fewer places than this is not reported (nor billed as a change).

## `chartProductDetailsTopN` (type: `integer`):

Optional, paid: read the product pages of this many top products per chart ($4 per 1,000) so the digest can name brands entering the chart. 0 (default) is off.

## `trendsTerms` (type: `array`):

Searches that describe your niches (at most 100), read by Google Trends Scraper ($1.50 per 1,000 terms): new rising related searches and breakouts since the last run, and terms whose interest crossed the threshold below. Each term is an item. The first run is the baseline.

## `trendsGeo` (type: `string`):

A country or region code (US, GB, US-CA). Clear it, or write worldwide, for worldwide.

## `trendsTimeRange` (type: `string`):

The period rising searches and interest moves are measured over. Past 90 days suits a weekly digest.

## `trendsMinInterestChangePercent` (type: `integer`):

A term is reported when its interest (its latest quarter of the period against its earliest) moves at least this much up or down, once each time it crosses (it must come back 10 points inside the threshold before it can cross again).

## `minPriceChangePercent` (type: `integer`):

Ignore price moves smaller than this percentage, in every watcher.

## `maxRunCostUsd` (type: `number`):

Optional. The most one digest may cost in all: its own events, every watcher's run and the delivery. Use it for scheduled runs, which may have no spending limit of their own. With a run spending limit too, the lower one applies.

## `sendWhenNoChanges` (type: `boolean`):

Also send a digest that says nothing changed. Off: a quiet run sends nothing.

## `maxChangesShown` (type: `integer`):

At most this many changes in the message; all of them are in the run's dataset.

## `alertBelowRating` (type: `number`):

Optional. The digest sent to your channels lists only new reviews with one under this many stars, and ratings that fell under it; other review changes stay in the run's dataset. Empty: every review change.

## `alertPriceDropPercent` (type: `number`):

Optional. The digest sent to your channels lists only price drops of at least this percent from store products and Shopify stores; their other changes stay in the run's dataset. Empty: every store product change.

## `alertRankMilestonesOnly` (type: `boolean`):

The digest sent to your channels lists only Amazon search rank milestones (entered or left the top 3 or 10, reached or left page 1); every rank move stays in the run's dataset.

## `emailTo` (type: `array`):

Recipients, one per line (at most 50 in all). Each one gets the digest separately (see Send separately).

## `emailCc` (type: `array`):

Optional. Copied recipients (shown to everyone; with CCs the email goes out once to all).

## `emailBcc` (type: `array`):

Optional. Hidden recipients.

## `emailSeparately` (type: `boolean`):

Send each recipient their own email (no one sees the other addresses; each email is billed). Off: one email to all of them.

## `emailFrom` (type: `string`):

The sender, on a domain your provider lets you send from, for example alerts@yourdomain.com or "Alerts <alerts@yourdomain.com>".

## `emailReplyTo` (type: `string`):

Optional. Where replies go.

## `emailProvider` (type: `string`):

How the email is sent: with your account at Resend, Postmark or SendGrid (API key), or through any SMTP server (Gmail, Outlook, Mailgun, your own).

## `emailApiKey` (type: `string`):

Your Resend, Postmark (server token) or SendGrid API key. Stored encrypted; never shown in logs or results.

## `smtpHost` (type: `string`):

For SMTP: the server, for example smtp.gmail.com or smtp.office365.com.

## `smtpPort` (type: `integer`):

For SMTP: 587 (STARTTLS) or 465 (TLS, with Secure on).

## `smtpSecure` (type: `boolean`):

On for servers that use TLS from the start (usually port 465). Off: STARTTLS on 587.

## `smtpUser` (type: `string`):

For SMTP: the login, usually your email address.

## `smtpPassword` (type: `string`):

For SMTP: the password or app password. Stored encrypted; never shown in logs or results.

## `slackWebhookUrl` (type: `string`):

A Slack incoming webhook (https://hooks.slack.com/services/…).

## `discordWebhookUrl` (type: `string`):

A Discord channel webhook (https://discord.com/api/webhooks/…).

## `teamsWebhookUrl` (type: `string`):

A Teams workflow webhook ("Post to a channel when a webhook request is received"); the message arrives as an Adaptive Card.

## `webhookUrl` (type: `string`):

Any https endpoint (Zapier, Make, n8n, your own): receives the subject, text, markdown and items as JSON.

## Actor input object example

```json
{
  "title": "Watch digest",
  "monitorName": "digest",
  "productUrls": [
    "https://www.allbirds.com/products/mens-tree-runners"
  ],
  "amazonMarketplace": "US",
  "rankMarketplace": "US",
  "rankSponsored": true,
  "maxProductsPerStore": 1000,
  "shopifyIncludeStock": false,
  "reviewMarketplace": "US",
  "marketSources": [
    "amazon"
  ],
  "adPlatforms": [
    "google",
    "meta",
    "tiktok"
  ],
  "tiktokMaxProductsPerKeyword": 20,
  "chartTypes": [
    "best-sellers",
    "new-releases"
  ],
  "chartMaxItemsPerChart": 100,
  "chartMinRankChange": 10,
  "chartProductDetailsTopN": 0,
  "trendsGeo": "US",
  "trendsTimeRange": "past-90-days",
  "trendsMinInterestChangePercent": 50,
  "minPriceChangePercent": 0,
  "sendWhenNoChanges": false,
  "maxChangesShown": 50,
  "alertRankMilestonesOnly": false,
  "emailSeparately": true,
  "emailProvider": "resend",
  "smtpPort": 587,
  "smtpSecure": false
}
```

# Actor output Schema

## `changes` (type: `string`):

No description

## `digest` (type: `string`):

No description

## `summary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "productUrls": [
        "https://www.allbirds.com/products/mens-tree-runners"
    ],
    "trendsGeo": "US"
};

// Run the Actor and wait for it to finish
const run = await client.actor("cleanpull/watch-digest").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "productUrls": ["https://www.allbirds.com/products/mens-tree-runners"],
    "trendsGeo": "US",
}

# Run the Actor and wait for it to finish
run = client.actor("cleanpull/watch-digest").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "productUrls": [
    "https://www.allbirds.com/products/mens-tree-runners"
  ],
  "trendsGeo": "US"
}' |
apify call cleanpull/watch-digest --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cleanpull/watch-digest"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/9x3tdrBiV2wEwLuTA/builds/pcUEvI4BFnp5IAaau/openapi.json
