How to Scrape Bulgari in 2026
Bulgari is one of the crown jewels of LVMH's watches & jewelry division — a segment that turned over roughly €10.5 billion in 2025, with Bulgari posting a record year on the back of collections like Serpenti, B.zero1, Divas' Dream, and its Octo watches. If you're tracking jewellery and watch pricing, monitoring availability, or building luxury market intelligence, bulgari.com is a high-value target — and a more approachable one than it first looks, once you understand its architecture.
Unlike a site that throws a CAPTCHA wall at you, Bulgari's difficulty is structural: the data is there, cleanly, but it's gated behind a session and a short-lived token. Get that right and it's fast.
What's on bulgari.com
Bulgari runs regional storefronts (/en-us, /fr-fr, /it-it, and so on) covering jewellery, watches, accessories, and fragrances. Each product carries a name, collection, reference, per-market price, materials/variant options, and an availability flag. The catalogue is localised, so prices and assortment differ by region — which is exactly what makes cross-market price and availability analysis worthwhile.
The problem
Bulgari is built on Salesforce Commerce Cloud (SFCC). The storefront is a headless PWA that renders in the browser and pulls its data from Salesforce's Commerce (SCAPI) shopper endpoints — the same JSON API the site itself calls. That JSON is clean and structured, which is good news. The catch is how you're allowed to call it.
The shopper API doesn't take anonymous requests. Every call needs a valid, short-lived OAuth shopper access token, and that token is minted by the storefront during a normal browser session — not by an endpoint you can just POST credentials to. On top of that, the platform applies the usual edge protections: IP reputation and geo checks, so a request from a burned datacenter IP or a mismatched region gets rejected before it reaches the data.
So the hurdle isn't a slider CAPTCHA — it's: get a legitimate session, obtain the token the way the storefront does, and present it correctly. Miss any of those and you get a 401 or an empty response.
The shopper token is the whole thing
Here's the useful property of an SFCC storefront: the storefront and the shopper API are same-origin. The token minted by loading a category page is valid for the API calls that follow on the same session. Warm the session once, and the reads after it ride on the same credentials.
That means the winning pattern is:
- Warm once — load a real storefront page in a browser session so the shopper token gets minted and the session is recognised.
- Then go fast — subsequent API reads on that same session are lightweight GETs; no browser needed per request, because you're reusing the warm session's credentials.
The expensive part of a DIY build here is reproducing the token-minting flow faithfully (it's a standard OAuth authorization flow, but easy to get subtly wrong) and keeping a warm, region-correct session alive across the burst of API reads. Sessemi does both for you.
With Sessemi: warm the session, replay the token
Step 1 — warm the session. Load a category page on the regional storefront with a named session. This satisfies the edge checks, gets a valid shopper token in place, and keeps the session warm for the reads that follow.
curl -X POST https://api.sessemi.com/scrape \
-H "X-API-Key: $SESSEMI_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://www.bulgari.com/en-us/jewelry",
"stealth": true,
"country": "us",
"session": "bulgari-us"
}'
Step 2 — read product data on the fast path. Because the API is same-origin, subsequent reads on the same session don't need a full browser render — Sessemi serves them on the fast path, reusing the warm session's credentials. Keep stealth on so the request stays residential:
curl -X POST https://api.sessemi.com/scrape \
-H "X-API-Key: $SESSEMI_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://www.bulgari.com/en-us/jewelry/necklaces",
"stealth": true,
"country": "us",
"session": "bulgari-us"
}'
The country parameter sets the session's geolocation — which region of the store you get back. Keep it matched to the storefront you're targeting (US here) for the whole session.
Pace your reads. The shopper API is happy to serve pages of results, but asking for very large pages in one shot is a reliable way to get a 503 — SFCC endpoints cap page size. Request modest pages and paginate. Smaller, steadier requests are both more reliable and lighter on the target.
What you get back
The shopper API returns structured JSON. A product resolves to roughly this shape (illustrative — exact fields depend on locale and change over time):
{
"id": "...",
"name": "...",
"collection": "Serpenti",
"price": { "amount": 0000, "currency": "USD" },
"availability": "in_stock",
"variants": [ ... ]
}
Because it's JSON rather than rendered HTML, extraction is simple and stable — you're reading fields, not scraping a DOM. That's the payoff for getting the session and token right up front.
Python example
A minimal warm-then-read scrape for the US storefront:
import requests
API_KEY = "YOUR_KEY"
API_URL = "https://api.sessemi.com/scrape"
headers = {"X-API-Key": API_KEY, "Content-Type": "application/json"}
SESSION = "bulgari-us"
COUNTRY = "us"
# Step 1: warm the session (mints the shopper token, satisfies edge checks)
requests.post(API_URL, headers=headers, json={
"url": "https://www.bulgari.com/en-us/jewelry",
"stealth": True,
"country": COUNTRY,
"session": SESSION,
})
# Step 2: fast reads on the same session — token replayed automatically
for path in ["jewelry/necklaces", "jewelry/rings", "watches"]:
resp = requests.post(API_URL, headers=headers, json={
"url": f"https://www.bulgari.com/en-us/{path}",
"stealth": True,
"country": COUNTRY,
"session": SESSION,
})
print(path, resp.status_code)
Tip: Sessemi keeps the named session alive while you use it (reaped after about 5 minutes idle) and rotates the underlying IP for you under the same name — you never manage proxies. If a read does return 401 — the shopper token lapsed — re-run step 1 to re-warm, then continue. An "on-401, re-warm once, retry" loop is all a long-running Bulgari scraper needs.
Is scraping Bulgari legal?
We build infrastructure, not legal opinions, so treat this as orientation. Collecting publicly accessible product and price data is generally viewed very differently from touching anything behind a login, and price and availability monitoring is a well-established commercial practice. Still, a few things matter:
- Bulgari's Terms of Use govern automated access — scraping can breach a site's ToS even where it isn't otherwise unlawful. Read them.
- Stay on public catalogue data. Don't authenticate, don't touch checkout or account areas, don't try to reach anything a shopper wouldn't see logged out.
- No personal data. Prices and product info are fine; personal information is regulated (GDPR/CCPA) and out of scope for this kind of monitoring.
- Rate-limit. Paginate, space your requests, and keep volume low enough that real shoppers never notice. It's the courteous choice and the durable one.
Sessemi is the transport layer. Using it for legitimate market intelligence is on you.
What it costs
The warm-up request costs 5 credits (residential base plus the solve). The fast reads that follow on the same session are lighter — 3 credits each when no fresh challenge fires (residential, no solve), which is what makes Bulgari cheap to scan at scale. The free tier's 1,000 credits are enough to test the flow; for production volume, Basic ($20/mo) or Pro ($100/mo).
| Plan | Credits/mo | Warm-up | Fast reads |
|---|---|---|---|
| Free | 1,000 | 5 credits | 3 credits |
| Basic | 20,000 | 5 credits | 3 credits |
| Pro | 100,000 | 5 credits | 3 credits |
The economics favour the warm-then-read pattern: pay the render once per region per cycle, then read many category and product pages cheaply on the warm session. A full multi-region jewellery-and-watch sweep on an hourly cadence stays well inside the Pro allowance.
Try it
The free tier's 1,000 credits let you run the full warm-then-read flow against bulgari.com end to end — enough to prove it out. For production volume, move to Basic or Pro. Sign up, run the two calls above, and you'll have structured Bulgari product data in a few seconds.
The docs cover session, country, stealth, and the rest. If you're building jewellery-and-watch price monitoring, cross-region analysis, or availability tracking, this is the layer that handles the session and token — you handle the intelligence.