Price range and pasted URLs (brief docs/cloud-tasks/2026-10-20_etsy-search-extend-monitor-filters.md, 2026-10-20; reworked after the review of PR #32, user decision of 2026-10-20, option b): Etsy's robots.txt disallows order=, min= and max= for crawlers (audit §1), so no sort option is offered (Etsy's default order only) and no request ever carries order, min or max (test on buildMarketUrl, pasted URLs included, and on every request of the crawler tests). priceMin / priceMax (whole amounts in the locale currency, bounds included) are a local filter on the listings fetched: a listing outside the range, without a price or shown in another currency than the locale's (the USD-rendered first cards of a /fr/ page) is neither written nor charged nor counted against maxResults; pagination goes on past pages whose listings are all left out (they still count as new listings for the "two pages without new listings" stop) and stops at maxResults listings in the range, the last page, 3 consecutive pages without any listing in the range (cost guard added after the second review of PR #32: such pages are paid in residential traffic, about 0.0008 $ each, and never charged; without it a range no listing falls in read up to 150 pages per default run), the 200-page cap or maxRequests; a search stopped by the last three is warned about at its end and in the final log (RUN_STATS.extra.priceFiltered, priceFilterStopped, priceFilterCapped); after the cost-guard stop the monitor record is written as after an exhausted search; a listing left out by one search can still be kept by another one of the run. startUrls: market pages /{prefix/}market/<slug> and search URLs /{prefix/}search?q=…, converted to the market route of the audit with the locale of the URL and its free_shipping parameter; order is removed and min / max become the bounds of the local filter when the input sets none (each bound on its own), with one warning per URL in the log before the first request; any other URL, host or locale prefix fails the run before any request with a message naming the URL. explicit=1 accompanies the free-shipping filter only, as on the captured page.
Price monitoring, same rules as the AliExpress Actor and same option names as the eBay Actor (aligned after the second review of PR #32, as the brief asks): monitorPrices (off by default), onlyChanges and monitorStoreName (default etsy-price-monitor, lower-cased, Apify storage-name shape, 63 characters at most); previous prices kept in that named key-value store of the customer's account, one record per search (words or URL, locale, price range, free shipping); with onlyChanges only new listings and price changes are returned and charged, otherwise every compared listing with its changeType; first run = reference (RUN_STATS.monitorBaseline); RUN_STATS.monitor summary and monitorCompared / monitorNew / monitorPriceChanged / monitorUnchanged counters; records written only after a search that ended cleanly (fail-closed: not after a block, a failed API call, a charge cut or a run that ran out of budget); a monitoring run without any change succeeds with an empty dataset; maxResults = listings compared per search; same currency only (the USD-rendered first cards of a locale-prefixed page compare as unchanged until the currencies match).
Each crawl task now carries its own search parameters (SearchTask.params: words, locale, filters) so that keyword and URL tasks of different locales run in one run; Accept-Language follows the task. Without the new options the requests, rows and log lines are those of 0.1 (regression test on the fixtures).
Dataset: new view Changes; the four monitoring columns are documented as filled in monitoring runs. Input form: Results and filters section extended, new Price monitoring section. README: sections Price range and search URLs and Price monitoring, FAQ reworded (10 entries; the price filter applies to the results fetched, not to Etsy's search). One more example task (etsy-monitor-ceramic-mug-prices, 9 in total). Tests: URL conversion, removed parameters and refusals, input defaults with URLs only, local price filter (bounds, missing price, other currency, maxResults, pagination, caps, the 3-page cost guard and its reset, across searches), monitoring options (eBay names, store-name shape, old draft names ignored), monitor record and comparison, crawler locale per task, monitoring baseline, onlyChanges on and off, caps, identities, fail-closed, unknown record format, unreadable store.
To check at the first run (Mac): a run with a price range reads more pages for the same maxResults (cost per listing kept, RUN_STATS.extra.priceFiltered, priceFilterStopped); a /search?q= URL pasted by a customer converts to a market page that exists.
Store texts (brief docs/cloud-tasks/2026-10-20_studio-promote-store-texts.md, 2026-10-20): README opens with what you get / for whom / how much, shows the real input of the validation run, a pricing table that points to the Pricing tab (no figure in the text), a For AI agents (MCP) section with a minimal input, the key output fields, the cost per 1,000 results and the typical time; FAQ kept to 8–10 questions; no proxy or anti-bot detail left in the texts visible on the Store. Tests on the Store lengths (seoTitle ≤ 60, seoDescription ≤ 155, description ≤ 300), the README structure and the forbidden mentions. No code change.