Shopify Category and Price Band Summary avatar

Shopify Category and Price Band Summary

Pricing

from $2.00 / 1,000 shop summaries

Go to Apify Store
Shopify Category and Price Band Summary

Shopify Category and Price Band Summary

Summarize price distributions, price bands, product types and vendors from a limited public Shopify feed sample, without guessing currency.

Pricing

from $2.00 / 1,000 shop summaries

Rating

0.0

(0)

Developer

Practical AI Lab

Practical AI Lab

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

9 days ago

Last modified

Security

Limited permissions

Share

Turns a limited sample of a Shopify store's public product feed (/products.json) into one compact summary row per shop: price statistics, price bands, and counts by product type and vendor.

It is built for quick catalog positioning checks: "Where does this shop sit on price, and what does it mostly sell?" It deliberately returns summaries, not product dumps, and it never guesses a currency.

What you get per shop

  • Sample size, priced-product count, and whether the sample cap was reached.
  • Price statistics: min, 25th percentile, median, 75th percentile, max, mean (lowest positive variant price per product).
  • Price bands: your own edges, or automatic quartile bands when at least 8 priced products exist.
  • Top product types and top vendors with counts, plus otherCount and unlabeledCount.
  • Plain-language caveats generated from the actual sample.

Input example

{
"shopDomains": ["allbirds.com"],
"maxProductsPerShop": 250,
"priceBandEdges": ["50", "100", "150"],
"topN": 10,
"requestDelaySeconds": 1
}

Replace the example domain with shops you are permitted to analyze. Only the domain is used.

Output shape (illustrative, not real data)

{
"shop": "shop.example.com",
"status": "ok",
"currency": null,
"sampledProducts": 250,
"sampleCapReached": true,
"priceStats": {"min": "...", "median": "...", "max": "..."},
"priceBands": [{"label": "below 50.00", "productCount": 0, "share": 0.0}],
"productTypes": {"distinct": 0, "top": [], "otherCount": 0, "unlabeledCount": 0},
"caveats": ["..."]
}

Currency handling

The public feed contains numbers but no currency code. This Actor reports currency: null, shows prices exactly as the feed gives them, and never converts or merges them across shops. Compare bands between shops only if you know they share a currency.

Safety and politeness

  • HTTPS only, public domain names only. IP addresses, ports, credentials and local/internal names are rejected.
  • DNS must resolve to public addresses; redirects are followed only within the same host.
  • robots.txt is checked for the feed path (wildcards and longest-match rules supported). If it cannot be read, the shop is skipped.
  • Requests are sequential with a delay of at least 0.5 s, response size is capped at 5 MB, and no proxies are used.
  • Low memory: products are streamed into counters; only one number per priced product is kept.

Pricing event

The code emits one shop-summary event per successfully summarized shop. Shops that fail (robots disallow, missing feed, rate limit, invalid data, empty feed) produce an error row and are not charged. The event price is not configured in this repository.

Limitations and sample-size caveats

  • Maximum 1,000 products per shop and 20 shops per run. Large catalogs are sampled in the store's own feed order, which is not random and may favor new, best-selling or alphabetical items.
  • Percentiles and band shares from fewer than about 30 priced products are rough; the output says so.
  • The summary uses the lowest positive variant price per product; compare-at prices, discounts, taxes, shipping and market-specific pricing are not captured.
  • Product type and vendor are merchant-entered free text; spelling variants beyond case and spacing are not merged.
  • Some stores disable or restrict /products.json, use a different public domain than their myshopify.com address, or block automated access. Those shops return an error row.
  • Hidden, unpublished or password-protected products are not visible.
  • DNS is validated before each request, but a hostile DNS server could in theory change answers between lookup and connection.
  • The results describe a snapshot of public listings. They are not sales data, revenue, or proof of demand.

Local tests

Tests are offline and use only the Python standard library:

python -m unittest discover -s tests -t .