Ulta's in-store stock is a status, not a count, and you can check it for one shade at 10 stores at once. Scavio's Ulta Beauty API takes a product id, the shade's sku id and a US ZIP, and POST /api/v1/ulta/stores returns In Stock or Out of Stock for that shade at the 10 nearest Ulta Beauty stores, with address, distance, hours and curbside pickup, read live when you call. It costs 1 credit, about $0.002 on the Growth plan billed yearly, and needs no Ulta account. Treat the answer as a strong hint and call the store for the last unit.
The question has been asked on Reddit for years. On r/Ulta, a thread with 29 comments asks why an item marked in stock in store is not available for pickup, and whether it is actually there. On r/MakeupAddiction, the top Google result for checking Ulta stock at other stores, a shopper found the shade missing from the display even though the site said the store had it.
What the Ulta employees in those threads say
The most upvoted answer in r/Ulta, at 88 points, says an item can be in stock but not available for pickup when "the store only has one or two", when it has just arrived and is still in the back, or when an earlier pickup order was rejected because staff could not find it. The same answer advises calling, since the store can usually hold the item. Another employee adds that an item sold out online is taken off pickup at every store, even ones that have plenty. In r/MakeupAddiction, people who worked at Ulta say the website can take 24 to 48 hours to reflect a store's inventory and does not see theft or damaged returns, and their advice is to call. Any API that reads Ulta's store availability inherits those limits, Scavio included. What an API changes is the effort: one call covers 10 stores, and a script can cover every shade.
Step 1: Get the product and the shade's sku id
Every Ulta search or category row carries a url, a product_id and a sku_id. To pick a specific shade, call product with the URL and read variants[]:
curl -s https://api.scavio.dev/api/v1/ulta/product \
-H "Authorization: Bearer $SCAVIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://www.ulta.com/p/glow-reviver-lip-oil-pimprod2042290?sku=2615649"}'On November 2, 2026, e.l.f. Glow Reviver Lip Oil returned 10 shades, each with its sku_id, name, shade description and online available flag; Pink Quartz is sku 2615649. The product's availability was "InStock" online. Check it: if a product is sold out online, the employees above say pickup disappears everywhere, so an Out of Stock store label means less.
Step 2: Ask the 10 nearest stores
curl -s https://api.scavio.dev/api/v1/ulta/stores \
-H "Authorization: Bearer $SCAVIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"product_id": "pimprod2042290", "sku_id": "2615649", "zip": "10001"}'The captured answer, trimmed to the first 3 of 10 stores:
{
"product_id": "pimprod2042290",
"sku_id": "2615649",
"zip": "10001",
"count": 10,
"in_stock_count": 8,
"stores": [
{
"store_id": "1638",
"name": "2 Herald Square",
"address": "51 West 34th Street, Suite 110, New York, NY 10001",
"distance_miles": 0.17,
"open_label": "Closed",
"curbside_label": null,
"in_stock": false,
"availability": "Out of Stock"
},
{
"store_id": "1899",
"name": "Ulta Beauty",
"address": "620 Avenue of the Americas, Ste 0105, New York, NY 10011",
"distance_miles": 0.63,
"open_label": "Closed",
"curbside_label": null,
"in_stock": true,
"availability": "In Stock"
},
{
"store_id": "1402",
"name": "Upper East Side",
"address": "188 East 86th Street, New York, NY 10028",
"distance_miles": 2.81,
"open_label": "Closed",
"curbside_label": null,
"in_stock": true,
"availability": "In Stock"
}
]
}The closest store, 0.17 miles from the ZIP, was out of Pink Quartz; the one 0.63 miles away had it. in_stock is true or false from Ulta's label and null if Ulta shows anything else. open_label read "Closed" because we called late at night, and curbside_label names curbside hours where a store offers it.
Step 3: Loop over the shades you care about
Stock is per shade, so a store that has one colour can be out of the next. We ran all 10 shades of the e.l.f. lip oil and all 16 shades of Dior Addict Lip Glow Oil near ZIP 10001, one call each:
- e.l.f. Glow Reviver Lip Oil: in stock in 93 of 100 shade-store checks. The nearest store was out of 4 shades (Crystal Clear, Pink Quartz, Red Delicious and Rose Envy), and Hot As Fudge was out at the second and third nearest.
- Dior Addict Lip Glow Oil: every shade in stock at the 4 nearest stores and out at the other 6, the same split for all 16 shades, which looks like a brand some stores do not carry rather than shades selling out.
That is 26 credits for 260 shade-and-store answers. The grid is charted in the best Ulta Beauty product data APIs.
What this can and cannot tell you
- Status, not units: Ulta publishes In Stock or Out of Stock per store. No API reading it can tell you whether that means one unit or a full drawer.
- Live, but only as live as Ulta: each call reads Ulta at that moment, so you get today's label, and the label carries whatever lag the employees describe.
- Ten stores per call: the 10 nearest the ZIP, nearest first. For a wider area, call again with a second ZIP.
- One shade per call: pass the exact
sku_id; the product's default shade is not the one every shopper wants.
A shade finder that checks 20 products with 10 shades each at 3 ZIP codes every morning makes 600 calls a day, 18,000 credits a month: $36 on the Growth plan billed yearly. For the full request-by-request walkthrough, including search and category prices, see how to get Ulta Beauty product data.
Try the Ulta Beauty API free, 50 credits, no card, or run a stores call in the playground.
Reference: Ulta Beauty API overview · stores docs · product docs · search docs
Frequently asked questions
How do I check Ulta stock at other stores?
On ulta.com or the app, open the product, pick the shade and check store availability, one store list per shade. To check many shades or products at once, Scavio's /api/v1/ulta/stores takes a product_id, a sku_id and a US ZIP and returns In Stock or Out of Stock at the 10 nearest Ulta Beauty stores in one call, with distance, hours and curbside pickup.
Is Ulta's in-store availability accurate?
It is a status that can lag the shelf. Ulta employees on Reddit say the online count can take 24 to 48 hours to catch up and does not see theft or damaged returns, and that an item can show in stock while the store has only one or two. For a single scarce item, call the store before you drive.
Why is an Ulta item in stock in store but not available for pickup?
Store employees in r/Ulta give several reasons: the store has only one or two, the stock just arrived and is not on the floor, an earlier pickup order failed because staff could not find it, or the item is sold out online, which they say removes it from pickup at every store. Pickup eligibility and the in-store label are separate signals.
Does Ulta show how many units a store has?
No. Ulta shows In Stock or Out of Stock per store, not a unit count, so Scavio's stores endpoint returns in_stock as true or false with the availability label.