Athleta Scraper - Price, Markdown & New Arrival Tracker
Pricing
from $6.30 / 1,000 product scrapeds
Athleta Scraper - Price, Markdown & New Arrival Tracker
Athleta scraper: category ids or links to one row per style-color with USD price, full price, markdown dollars and percent, price type (regular, promo, markdown), stock, rating, badges, promo lines, link and photo. For activewear price, markdown and new-arrival watching.
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
a day ago
Last modified
Categories
Share
Athleta scraper: activewear price, markdown and new-arrival tracker (USA)
This Athleta scraper reads Athleta (the US women's activewear retailer) category lists and returns one flat row per style-color: the current price in USD, the full price, the markdown in dollars and percent, whether the price is regular, promotional or a clearance markdown, stock, rating, badges, promotion lines, the product link and the photo. Run it on a schedule and diff the dataset to get an activewear price, markdown and new-arrival watch: which Elation leggings went from 89.00 to 59.97, which colors just landed in New Arrivals, which are down to "Very Low" stock.
No account, no API key, no login, no browser. One request returns up to 60 colors.
Input
| Field | Notes |
|---|---|
categoryIds | Athleta category ids, one per line. The id is the number after cid= in any athleta.gap.com browse link. Default example: 1006482 (New Arrivals). Also checked: 1023728 Sale, 3043230 Shop All Women's, 1025878 Bottoms, 1032080 Tops, 1038916 Sports Bras, 1017102 Jackets, 89745 Dresses & Jumpsuits, 1032096 Accessories. |
startUrls | Category links instead of (or as well as) ids, for example https://athleta.gap.com/browse/category.do?cid=1006482. The id is read from cid=. A product link (product.do?pid=...) or a link to another site is refused. |
maxItems | Rows to return per category (default 100, up to 10,000). |
onlyOnSale | Return only colors whose price is below their full price (on_sale). Colors at full price are read, not returned and not charged, and do not count toward maxItems. |
proxyConfiguration | Apify residential proxy by default. Needed: see "How it fetches". |
Example input:
{"categoryIds": ["1006482", "1023728"],"startUrls": [{ "url": "https://athleta.gap.com/browse/new/all-womens?cid=3043230" }],"maxItems": 300,"onlyOnSale": true}
A category id Athleta does not know (HTTP 404 from its API) or that is not a number is reported in the log and skipped at no charge. A bad id or link in the input stops the run before anything is charged.
One row is one style-color, not one style
Athleta sells a garment per color. A style (style_id, "Elation Ultra High
Rise Legging") comes in several colors, each with its own id (color_id), its
own price, its own stock and its own link, and a markdown usually hits some
colors and not others: on 2026-10-29 the same legging was 89.00 in Northern
Night and 59.97 in Morning Glory. Athleta's list also counts colors, not styles
(its own "859 colors" for New Arrivals), so a row per color is what the source
gives and what a price watch needs. color_id is the unique key of a row;
style_id repeats once per color. To get one line per style, group by
style_id.
A color that two sections of a category both list (New Arrivals shows "Featured
Styles", "All New Arrivals", then "New Tops", "New Bottoms" and so on) is listed
twice by the site: New Arrivals reports 859 entries for 537 distinct colors.
You get 537 rows, each once, under the section that listed it first (section),
and are charged for 537. The same holds across categories in one run.
Output
Prices are numbers in US dollars; currency is USD (market us).
| Field | Notes |
|---|---|
category_id, category_name, section, position | The category the row was read from, its name ("New Arrivals"), the section that listed the color first ("All New Arrivals", "New Tops"; null for a category without sections) and its place in the site's own order (1 is first, counted over every entry of the pages read, repeats included). |
style_id, color_id | Athleta's style id and color id, both strings. color_id is unique per row and is the pid of the product link. |
name, color, color_name | The style name, the color family (Purple) and the color's own name (Northern Night). |
product_type | The site's product type, for example womens pants, womens bras wireless, womens jackets. |
url | The product page of this color. |
image_url | The main photo (the site's P01 image), an absolute link on athleta.gap.com. |
price | The current price. |
regular_price | The full price. Equal to price when nothing is marked down. |
price_type | Why price is what it is: regular, promo (a promotional price such as "30% Off. Price as Marked") or markdown (a clearance markdown, usually marked Final Sale). The site's own codes are R, P and M. |
on_sale | True when price is below regular_price. |
discount_amount, percent_off | Dollars off and the site's whole-number percent off. Null when not on sale, never 0. |
rating, review_count | The style's average star rating and how many reviews it is from. Style-level: every color of a style carries the same pair. rating is null for a style with no reviews (the site sends 0, which is not a rating of 0; review_count is 0 then). Most new arrivals have none yet. |
inventory_count, inventory_status | Units in stock for this color across sizes, and the site's word for it: In Stock, Low, Very Low or Out of Stock. |
promo_flags | The color's promotion lines as sent: 30% Off. Price as Marked, 20% Off Taken at Checkout, Extra 30% Off Taken at Checkout. Final Sale., Online Exclusive. A "Taken at Checkout" discount is not in price; a "Price as Marked" one is. Empty list when none. |
badges | The card badges in the site's order: Best Seller, New In, Just Reduced, New to Sale, Selling Fast, New Silhouette, Pre-order. Empty list when none. |
excluded_from_promotion | True when the style is excluded from promotions. Null if the site sends none. |
currency | USD. |
Example row (real values, 2026-10-29, position as on the live page):
{"category_id": "1006482","category_name": "New Arrivals","section": "Featured Styles","position": 7,"style_id": "684673","color_id": "684673342","name": "Reform Adjustable Sports Bra A-C","color": "Blue","color_name": "Blue Star","product_type": "womens bras wireless","url": "https://athleta.gap.com/browse/product.do?pid=684673342","image_url": "https://athleta.gap.com/webcontent/0062/943/812/cn62943812.jpg","currency": "USD","price": 29.4,"regular_price": 49.0,"price_type": "promo","on_sale": true,"discount_amount": 19.6,"percent_off": 40,"rating": 4.6,"review_count": 606,"inventory_count": 819,"inventory_status": "In Stock","promo_flags": ["40% Off. Price as Marked"],"badges": [],"excluded_from_promotion": false}
Honest nulls
A field the source did not send is null, never 0 or "". promo_flags
and badges are empty lists when there are none.
- No sizes or per-size stock. The list carries one total per color.
- No description, materials or variants. This is the category list, one row per color.
- No coupon or loyalty price. A "20% Off Taken at Checkout" line is shown in
promo_flags; the discount itself is applied in the cart and is not inprice. - Prices are the US store's (
market=us, USD). Other markets are not read.
Pricing
Pay per event: a small fee per run (actor-start), charged only after your
input is validated, so a run that fails on bad input costs nothing, and a fee
per style-color row written (product-scraped). A row that is not written is
not charged: rows filtered by onlyOnSale, and repeats of a color another
section or category already returned, are free.
How it fetches
It calls the JSON list behind athleta.gap.com's own category pages:
https://api.gap.com/commerce/search/products/v2/cc?brand=at&market=us&cid=<cid>&locale=en_US&pageSize=60&pageNumber=<n>
Measured 2026-10-29: HTTP 200 JSON of 0.1 to 1.5 MB per page, no key or cookie needed. From Apify datacenter addresses 2 of 10 requests answered and 8 were an Akamai "Access Denied" HTTP 403; from residential addresses 10 of 10 answered, so residential is the default. A refusal (403, 429, 5xx), a 200 that is not the list, a page other than the one asked for, 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:
- Paging is
pageNumber, 0-based. Page 0 is the first. A page past the last is HTTP 200 with no entries (pageNumber=15of New Arrivals, which has 15 pages 0-14, returned an empty list), and the actor stops there. The page says which page it served; a mismatch is treated as a refusal rather than read twice. - 60 entries per page, entries not styles. The list of a page holds exactly 60 colors (the last page fewer). The response also carries the other colors of every style it touches (254 carried for 60 listed on page 0 of New Arrivals); those are not rows, so you never get a color from a page it was not listed on.
- The walk misses nothing. Bottoms (
1025878) read in 8 pages of 60 gave 467 entries and 308 distinct colors; one request withpageSize=500(the API refuses 1000 with HTTP 400) gave the same 467 and 308. 60 is what Athleta's own pages ask for, so 60 is what is sent. - Repeats cost pages, not money. New Arrivals is 15 pages for 537 rows because
the sections repeat each other.
maxItemscounts rows returned, so 100 rows may need 2 pages and the last rows of a repeated category need all 15. - Parent categories work.
1025878(Bottoms: 467 listed entries, 308 distinct colors, 8 pages),1023728(Sale: about 2,190 entries, 1,388 distinct colors, 37 pages) and3043230(Shop All Women's: about 2,130 entries, 1,281 distinct colors, 36 pages) list everything under them. Entry totals drift by one or two between requests. Read 2026-10-29 from a home connection: the 37 Sale pages took 30 seconds. - Not every id on the site is a list. Some cids that appear in links
(
1005672,1082880,1111336,1197664) are not known to the API (HTTP 404) and are reported and skipped. - Depth. At most 10,000 rows per category are read.
If Athleta changes its list format, the run fails with a message instead of returning empty rows.