# Changelog of Shopify Store Leads Scraper (`devilscrapes/shopify-store-leads-scraper`) Actor

- **URL**: https://apify.com/devilscrapes/shopify-store-leads-scraper/changelog.md
- **Full Actor documentation**: https://apify.com/devilscrapes/shopify-store-leads-scraper.md

## Changelog — shopify-store-leads-scraper

All notable changes are documented here.

### \[0.2] — 2026-09-22

#### Fixed

- Don't fail a run just because `onlyShopify=true` (the default) filtered
  every domain out of the dataset. 17% of customer runs were failing (6 of
  35 in 30d) while our own runs never did — the tell: `tests/fixtures/input.qa.json`
  probes `allbirds.com` and `gymshark.com`, two real Shopify stores, so it can
  never reach the empty-result path. A customer batch-checking domains that
  happen to be WordPress/Wix/etc — a completely valid use of this Actor — got
  a FAILED run instead of the correct answer: "checked N domains, 0 are Shopify."
- `main()` collapsed "checked every domain and none is Shopify" and "could not
  reach any domain at all" into the same `total_rows == 0` check. Split them:
  `scraper.DetectionResult` now carries a `reachable` flag (True once ANY tier
  gets a real HTTP response, any status code — a 403/404 still proves the
  domain answered). `main._run_domain_loop` returns `RunOutcome(total_rows,
  any_reachable)`; `_finish_run` only raises `SystemExit` when nothing was
  reachable. A genuinely-empty, fully-reached batch now SUCCEEDS with zero
  rows and a status message describing what was checked.
- Verified live locally: `wikipedia.org` + `github.com` (real, reachable,
  non-Shopify) now exits 0 with "Checked 2 domain(s) — 0 Shopify stores
  found."; two `.invalid` domains (unreachable) still exit non-zero with
  "Could not reach any of 2 domain(s)"; `allbirds.com` + `gymshark.com`
  (the QA fixture) still emit real, spot-checked product rows.

### \[0.1] — 2026-06-07

#### Added

- Initial release.
- 3-tier Shopify detection: `/products.json`, HTTP response headers (`x-shopify-stage`, `x-sorting-hat-shopid`, `x-sorting-hat-section`, `Server: Shopify`), and HTML markers (`cdn.shopify.com`, `Shopify.theme`, `*.myshopify.com`).
- Homepage enrichment via `parsel`: contact email (`mailto:` links + plain-text fallback), social profile links (Instagram, Facebook, Twitter/X, TikTok, YouTube, LinkedIn, Pinterest), storefront currency, page title.
- `curl-cffi` impersonation (Chrome/Firefox/Safari rotation) for homepage fetches.
- `httpx` for `/products.json` (clean public REST endpoint — no fingerprinting needed).
- Apify Proxy integration with residential proxy group support.
- PPE events: `actor-start` ($0.005/run) + `result-row` ($0.0025/row) → ~$2.50 per 1 000 results.
- Pydantic v2 `ActorInput` + `ResultRow` models per ADR-0004.
- 20 unit tests, all passing.
