Dermstore Product & Sale Price Scraper (US)
Pricing
from $2.10 / 1,000 product scrapeds
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
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
8 days ago
Last modified
Categories
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
| Field | Notes |
|---|---|
searchTerms | One 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. |
startUrls | Dermstore 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. |
maxItems | Products to read per term or page (default 100, up to 10,000). 32 per page. |
onlyOnSale | Return only products whose current price is below the list price. Products that are not reduced are read, not returned and not charged. |
sort | popularity (default), price-asc, price-desc, name, newest: the five choices of the site's own sort menu. |
proxyConfiguration | Apify 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).
| Field | Notes |
|---|---|
query, position | The 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, url | Dermstore's product id (11174243; the site's "sku") and the product link. |
name, brand | As the page shows them. brand is null if the page sends none. |
price, original_price | price 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_percent | on_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_code | The 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_count | The page's variant label and how many variants the product has. See the note below. |
in_stock, stock_label | False with stock_label COMING SOON when the card shows a disabled button instead of "Quick buy". |
image_url | The product photo, original size, on static.thcdn.com. |
list_name | The 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 $150price 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 SOONproduct 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 nullpriceandoriginal_pricerather 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.
variantis not the size of the row. It is the page's label for the product's default variant (theMedik8 Crystal Retinal 6 Serum 30mlrow saysRetinal 10). Read the size fromnameandurl.in_stockis 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 byonlyOnSale, 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:
serumto the Face Serums category (734 products),retinolandvitamin c serumto ingredient pages (211 and 359),eye creamto the eye cream category,ceraveto 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, andquerystays the term you typed. A broad term can return a whole category;maxItemsbounds 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 alsobirthday 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.