Outdoor Voices Product Scraper & Price Tracker
Pricing
from $6.30 / 1,000 product scrapeds
Outdoor Voices Product Scraper & Price Tracker
Outdoor Voices scraper for www.outdoorvoices.com (US): the whole catalogue or any collection, one row per product with USD price range, price before markdown, discount percent, per-size stock and SKU, tags, photo and publish date. For activewear new-product and markdown alerts.
Pricing
from $6.30 / 1,000 product scrapeds
Rating
0.0
(0)
Developer
Superslow Sloth
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
6 days ago
Last modified
Categories
Share
An Outdoor Voices scraper and Outdoor Voices price tracker for
www.outdoorvoices.com, the US activewear shop.
Read the whole catalogue or any collection (w-new-arrivals, ov-extra,
shoes) and get one flat row per product: the current price and its range in
USD, the price before markdown, the largest discount in percent, whether it
is in stock and how many sizes are, and every size or colour variant with its
own SKU, price and stock flag. Run it on a schedule for activewear
new-product and markdown alerts: which leggings or shorts went live this
week, which went on sale since yesterday, by how much, and which sizes came
back.
No account, no API key, no login, no browser. One request returns 250 products; the whole catalogue (about 380 products on 2026-10-19) is two requests.
Input
| Field | Notes |
|---|---|
collections | Outdoor Voices collections to read instead of the whole catalogue, one per line: the name from the address bar (w-new-arrivals, m-new-arrivals, ov-extra, shoes) or the link (https://www.outdoorvoices.com/collections/ov-extra). Each is read in the shop's own order. A product found by two collections is returned once, under the first. Leave empty to read the whole catalogue, newest first. A collection name the shop does not have fails at no charge. |
publishedAfter | Only products that went live after this moment: 24 hours, 7 days, 2 weeks, a date (2026-10-01) or a date-time (2026-10-01T12:00:00Z). On the whole catalogue the run stops at the first older product, since the feed is newest-published first. Leave empty for no cut-off. |
onlyOnSale | Return only products where at least one variant is priced below its price before markdown (on_sale). Others are read, not returned and not charged, and do not count toward maxItems. |
maxItems | Products to return per collection, or for the whole catalogue (default 250, up to 25,000). 250 per page. |
proxyConfiguration | Apify datacenter proxy by default. |
Example input, products that went live in the last week:
{"publishedAfter": "7 days","maxItems": 500}
Example input, everything currently marked down:
{"onlyOnSale": true,"maxItems": 1000}
Output
Prices are numbers in US dollars; currency is USD (the shop's own
/meta.json says so). A field the shop did not send is null, never 0 or "".
| Field | Notes |
|---|---|
query, position | The shop URL (whole catalogue) or collection URL that first found the product, and its place in that list (1 is first, 250 per page). The whole catalogue is newest-published first. |
store | www.outdoorvoices.com. |
product_id, handle, url | Shopify's product id (a string), its URL handle, and the product link. One product is usually one colourway of a style, with its sizes as variants. |
title, vendor, product_type | As the shop sends them (ThinkFast Mesh Muscle Tank, Outdoor Voices, Tanks). Null when empty. |
tags | The shop's own merchandising tags (seasons, promotions, categories), as sent. Not a standard vocabulary. |
price, price_max | The lowest and highest current variant price. They differ when only some sizes are reduced; a gift card spans its amounts. |
original_price, original_price_max | The lowest and highest price before markdown: per variant its compare_at_price when that is above its price, otherwise its price. Equal to the current price when nothing is reduced. |
on_sale | True when at least one variant's compare_at_price is above its price. |
discount_percent | The largest reduction of any variant, (1 - price / compare_at_price) * 100, one decimal place. Worked out from the prices, not sent. Null when nothing is reduced, never 0. |
available, variant_count, available_variant_count | Whether any variant can be bought now, how many variants there are, and how many can be bought: the restock signal. |
option_names | The product's options, e.g. ["Color", "Size"]. |
variants | Every variant: variant_id, title (Black / XXS), sku, price, compare_at_price (null when the shop sends none), available, and options (the variant's values in option_names order). |
created_at, published_at, updated_at | ISO 8601 times with the shop's offset. published_at is when the product went live, which is what publishedAfter reads; created_at can be many months older. updated_at is rewritten in bulk, so it is not a price-change time. |
image_url, image_count | The first photo on cdn.shopify.com, as sent (null when there is none), and how many photos there are. |
Example row (real values, 2026-10-19; tags and variants shortened here to
two and one entries):
{"query": "https://www.outdoorvoices.com","position": 1,"store": "www.outdoorvoices.com","product_id": "7585333018702","title": "ThinkFast Mesh Muscle Tank","handle": "m-thinkfast-mesh-muscle-tank-black","url": "https://www.outdoorvoices.com/products/m-thinkfast-mesh-muscle-tank-black","vendor": "Outdoor Voices","product_type": "Tanks","tags": ["260SS","91md"],"created_at": "2025-03-17T18:44:59-04:00","published_at": "2026-10-15T13:12:14-04:00","updated_at": "2026-10-18T15:49:40-04:00","image_url": "https://cdn.shopify.com/s/files/1/0190/1390/files/thinkfast-mesh-muscle-tank-activewear-performance-fabric-techsweat-outdoor-voices-athleisure.jpg?v=1776648651","image_count": 2,"currency": "USD","price": 39.99,"price_max": 58.0,"original_price": 58.0,"original_price_max": 58.0,"on_sale": true,"discount_percent": 31.1,"available": true,"variant_count": 13,"available_variant_count": 5,"option_names": ["Color","Size"],"variants": [{"variant_id": "42326858039374","title": "Black / XXS","sku": "M302273-CLM-BLK-1","price": 39.99,"compare_at_price": 58.0,"available": true,"options": ["Black","XXS"]}]}
Honest nulls
- No ratings, reviews or stock counts. The catalogue feed carries none.
availablesays a variant can be bought, nothing more. discount_percentis null when nothing is reduced. Outdoor Voices sends acompare_at_priceon nearly every variant, often equal to the price on a full-price line (CloudKnit Cami: 34.00 and 34.00). Acompare_at_priceequal to or below the price is not a reduction, so that line ison_sale: false.
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.0063 per product row written (
product-scraped), i.e. $6.30 per 1,000 products. A row that is not written is not charged: rows filtered byonlyOnSaleorpublishedAfter, and repeats of a product another collection already returned, are free.
How it fetches
It reads /products.json, the public catalogue feed every Shopify shop serves
(and /collections/<name>/products.json for a collection). Measured
2026-10-19: HTTP 200 JSON, about 1.2 MB per 250 products, no key or cookie
needed, open from datacenter and residential addresses (15 of 15). A refusal
(403, 429, 430, 5xx), a 200 that is not the feed, 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:
- 250 per page is the ceiling. A larger
limitis silently capped at 250. - The end is an empty page. Page 3 is HTTP 200 with
{"products":[]}; the actor stops there. - Newest-published first. Both pages of the whole catalogue are in
published_atorder, which is what makespublishedAfterstop early. - There is no
salecollection./collections/saleis HTTP 404 on this shop; markdowns are spread across the catalogue (284 of 380 products had at least one reduced variant), so useonlyOnSale, or the shop'sov-extraoutlet collection. - An unknown collection looks empty. The feed answers an unknown name with an empty list; the actor asks the collection's own record, and a name that does not exist fails instead of being reported as empty.
If Outdoor Voices changes its feed, the run fails with a message instead of returning empty rows.