Dermstore Product & Sale Price Scraper (US) avatar

Dermstore Product & Sale Price Scraper (US)

Pricing

from $2.10 / 1,000 product scrapeds

Go to Apify Store
Dermstore Product & Sale Price Scraper (US)

Dermstore Product & Sale Price Scraper (US)

Dermstore scraper: search terms or category, brand, ingredient and sale pages to one row per product with USD price, list price, discount percent, promo text and code, brand, size variant, stock and image. For US skincare price and promo watching.

Pricing

from $2.10 / 1,000 product scrapeds

Rating

0.0

(0)

Developer

Superslow Sloth

Superslow Sloth

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

8 days ago

Last modified

Share

Search Dermstore (a US skincare and beauty retailer) by keyword, or read a category, brand, ingredient or sale page, and get one flat row per product: the current price and the list price in USD, the dollars and percent off, the promo text and its promo code, brand, size variant, whether it can be bought, the product link and the photo. Run it on a schedule and diff the dataset to get a US skincare price and promo watch: which serums, brands or sale items dropped in price, which carry a gift-with-purchase, and which only advertise a code.

No account, no API key, no login, no browser. One request returns 32 products.

Input

FieldNotes
searchTermsOne or more search terms, one per line (vitamin c serum, cerave, retinol night cream). Dermstore sends most terms it recognises to a category, ingredient or brand page, and that whole list is read; any other term is read as search results. A product found by two terms is returned once, under the first.
startUrlsDermstore pages to read in full: a category (/c/skin-care/treatments-serums/face-serum/), a brand (/c/brands/skinceuticals/), an ingredient (/c/ingredient/retinol/) or the sale page (/c/sale/). A search URL (/search/?q=...) is read as that search term. Pages must list products; see the notes below for the few that do not. Give terms, URLs or both.
maxItemsProducts to read per term or page (default 100, up to 10,000). 32 per page.
onlyOnSaleReturn only products whose current price is below the list price. Products that are not reduced are read, not returned and not charged.
sortpopularity (default), price-asc, price-desc, name, newest: the five choices of the site's own sort menu.
proxyConfigurationApify datacenter proxy by default.

Example input:

{
"searchTerms": ["vitamin c serum", "cerave"],
"startUrls": [{ "url": "https://www.dermstore.com/c/sale/" }],
"maxItems": 100,
"sort": "popularity",
"onlyOnSale": false
}

Output

Prices are numbers in US dollars; currency is the currency the page states (USD on every page measured).

FieldNotes
query, positionThe search term or page URL that first found the product, and its place in the site's list for that source and sort (1 is first).
product_id, urlDermstore's product id (11174243; the site's "sku") and the product link.
name, brandAs the page shows them. brand is null if the page sends none.
price, original_priceprice is the price now, the card's "Current price". original_price is the list price the card strikes through (Dermstore labels it "Recommended Retail Price"). They are equal when the product is not reduced.
on_sale, discount_amount, discount_percenton_sale is true when price is below original_price. discount_amount is the dollars off, as the page sends it. discount_percent is worked out from the two prices (one decimal place). Both are null when the product is not on sale, never 0.
promo, promo_codeThe promotion banner on the card: Save 25%, Code SHIP, Unlock Free 2-Day Shipping at $150, Free Shipping + $20 Gift, Medik8 Gift, $65 Full-Size Gift, New Arrival. promo_code is the code the text names (SHIP). Null when there is none.
variant, variant_countThe page's variant label and how many variants the product has. See the note below.
in_stock, stock_labelFalse with stock_label COMING SOON when the card shows a disabled button instead of "Quick buy".
image_urlThe product photo, original size, on static.thcdn.com.
list_nameThe list's own title in the site's tracking data (Face Serums, CeraVe). Null on search pages.

Example row (real values from the sale page, 2026-10-16):

{
"query": "https://www.dermstore.com/c/sale/",
"position": 13,
"product_id": "11174243",
"name": "Paula's Choice CLINICAL 1% Retinol Treatment (1 fl. oz.)",
"brand": "Paula's Choice",
"url": "https://www.dermstore.com/p/paula-s-choice-clinical-1-retinol-treatment-30ml/11174243/",
"image_url": "https://static.thcdn.com/productimg/original/11174243-8085356454909766.jpg",
"currency": "USD",
"price": 48.75,
"original_price": 65.0,
"on_sale": true,
"discount_amount": 16.25,
"discount_percent": 25.0,
"promo": "Save 25%",
"promo_code": null,
"variant": "30ml",
"variant_count": 1,
"in_stock": true,
"stock_label": null,
"list_name": "Dermstore Skin Care, Hair & Beauty Sale"
}

What the price fields mean

The page's own tracking data calls the list price price and the current price value, which reads backwards. Which is which was checked against the product cards on 2026-10-16 over 1,025 products (all 23 pages of the face serum category, the sale list and a search): on every reduced product (193 of them) the struck-through "Recommended Retail Price" on the card equals the list price, the "Current price" equals the current price, and the dollars off equal the difference, with no exception. Every "Save N%" banner measured sat on a reduced product and matched its reduction.

A promo code is not a reduction. The most common banner,

Code SHIP, Unlock Free 2-Day Shipping at $150
, is a free-shipping code; the card shows the full price. price never includes a code's saving, and the offer is in promo and promo_code. Filter on promo_code to see code offers, on on_sale for shelf reductions, and on promo for gifts with purchase.

Honest nulls

A field the page did not send is null, never 0 or "".

  • A COMING SOON product can have no price. On 2 of the 1,025 products measured the tracking data sent null for both prices although the card still printed one; the row is returned with null price and original_price rather than a figure the data did not carry.
  • No rating or review count. The ratings are filled in by the browser after the page loads and are not in the HTML, so the rows do not carry them.
  • variant is not the size of the row. It is the page's label for the product's default variant (the Medik8 Crystal Retinal 6 Serum 30ml row says Retinal 10). Read the size from name and url.
  • in_stock is about the card. True means a working buy button, false a disabled one. The site does not say more (stock levels, delivery dates).

Pricing

Pay per event:

  • $0.002 per run (actor-start), charged only after your input is validated, so a run that fails on bad input costs nothing.
  • $0.0021 per product row written (product-scraped), i.e. $2.10 per 1,000 products. A row that is not written is not charged: rows filtered by onlyOnSale, and repeats of a product another term already returned, are free.

How it fetches

It reads the product list that dermstore.com's own pages embed (an item map keyed by product id) and the product cards next to it. Measured 2026-10-16: HTTP 200 HTML from a plain connection and from Apify datacenter addresses, no key or cookie needed. A refusal (403, 429, 5xx), a 200 that is not a Dermstore page, or a dropped connection is treated as the address being blocked, and the actor rotates to a fresh one and retries.

Things worth knowing, all measured on 2026-10-16:

  • A search usually lands on a list page. Dermstore redirects most terms it knows: serum to the Face Serums category (734 products), retinol and vitamin c serum to ingredient pages (211 and 359), eye cream to the eye cream category, cerave to the CeraVe brand page (50 products). Terms it does not redirect are answered in place (retinol night cream: 134 products, 5 pages). The actor reads whatever list the site lands on, all its pages, and query stays the term you typed. A broad term can return a whole category; maxItems bounds it. The run log says where each term was sent.
  • Brand pages are product lists. /c/brands/cerave/, /c/brands/medik8/, /c/brands/skinceuticals/ and the other brand pages tried list their products directly and take the sort and page settings.
  • No results, and brands Dermstore does not carry. A term the site cannot match (zzzqqqxx, and also birthday gift) goes to a "no search results" page. A brand it does not stock (the ordinary) goes to a "We don't stock this brand" page that lists thousands of unrelated products; the actor treats that as no results and returns nothing for the term rather than charge you for products you did not ask for.
  • The redirect drops sort. The actor re-reads the first page from the landing list when you asked for a sort, so the order you chose is the order you get. The price sorts were in strict order on the pages checked.
  • A few pages are landing pages. /c/sunscreen/ is a page of carousels; it links its own list of everything (/c/sunscreen/view-all/, 498 products) and the actor reads that instead. The brand index /c/brands/ links no such list and fails (at no charge) with a message rather than return nothing.
  • Depth. The site lists 32 products per page and has no page-size setting. The largest category measured, /c/skin-care/, has 134 pages. A page past the last is an empty list and the actor stops there. At most 10,000 products per term or page.
  • Pages repeat nothing. All 23 pages of the face serum category were read: 734 products, none twice. A guard still ends a walk after three pages in a row that bring nothing new.
  • Not offered. The site's facet filters (brand, price range, skin concern) are not wired into this actor; start from a category, ingredient or brand page that already narrows the list.