Every check downloads the full page
Check Does the store have a JSON endpoint? Does it send ETag or Last-Modified?
Fix Poll the JSON endpoint and send If-None-Match; if there's no ETag, compare only the fields you need.
Poll stock every few minutes from fixed IPs at a flat price per IP — and download almost nothing when nothing changed.
A restock monitor asks the same pages the same question every few minutes. Retailers cap requests per IP and answer HTTP 429 when you go over, so one server IP watching hundreds of products ends up rate-limited at the moment a drop happens.
Ask for less. Many stores expose stock in small JSON: Shopify's product endpoint, /products/<handle>.js, returns available for the product and for each variant. If the server sends an ETag, a conditional request comes back 304 Not Modified with no body when nothing changed.
Stock can differ by region — Merchant Center lets sellers set availability per region — so check from the country whose stock you care about. Datacenter IPs keep polling cheap with a flat price per IP; move a store to rotating residential only if it blocks server IPs.
Scroll horizontally with the arrow keys to read all content.
| Criterion | Choose | Why |
|---|---|---|
| Product | Static datacenter proxy | Fixed IP, priced per IP and term — predictable cost for polling around the clock |
| If the store blocks servers | Rotating residential, Choose region / sticky IP | Household IPs in the store's country, billed per GB |
| How many IPs | Enough to keep each IP under the store's rate limit | Split your product list across IPs instead of polling everything from one |
| Country | The store's market: US, CA, GB, DE, NL, JP, KR or SG for datacenter | Availability can differ by region |
| Protocol | HTTP | Works in requests, httpx and Node.js clients without extra packages |
| IP changes | Never during the term | Renew in My assets to keep the same IPs |
The button below opens Static Datacenter Proxies with the AI and automation use case. Choose Region, Term, Protocol and Quantity (up to 100 IPs at a time) before you pay.
Scroll horizontally with the arrow keys to read all content.
| Criterion | Static ISP | Rotating residential | Datacenter |
|---|---|---|---|
| What you get | A dedicated home-broadband IP that stays yours for the whole term | Real household IPs: rotating exits, or a sticky session in a chosen country or city | Fast fixed server IPs, HTTP and SOCKS5 |
| Price | Per IP and term — live price at checkout | Budget US$1.50/GB (US$1.35/GB at 100 GB); Premium US$5.00/GB | Per IP and term — the cheapest per IP |
| Best for restock monitors | Checkout accounts that need one stable home IP | Stores that block server IPs; stock by city | Fast polling of stores and JSON endpoints that accept server IPs |
Prices in US dollars. Top up your wallet once and pay any line from it. Nothing renews automatically — renew in My assets to keep an IP.
The button below opens Static Datacenter Proxies (Per IP and term) with the AI and automation use case. Under Connection settings pick the Region, choose a Term and set Protocol to HTTP. Set Quantity to the number of IPs you'll spread products over (up to 100 at a time), then click Review cost and generate.
In My assets, Copy gives host:port:user:password. Turn it into PROXY_URL = http://USER:PASS@HOST:PORT for each monitor worker.
Use the code below: it asks for the product JSON, sends If-None-Match with the last ETag and treats only a 200 with available false as sold out.
Expected result The first check prints the sizes in stock; unchanged checks print 304 and download no body.
Send a message only when the in-stock list changes, and keep the last known state when a check errors.
Scroll horizontally with the arrow keys to read all content.
# pip install requests
import os
import time
import requests
PROXY = os.environ["PROXY_URL"] # static datacenter IP from My assets: http://USER:PASS@HOST:PORT
PROXIES = {"http": PROXY, "https": PROXY}
URL = "https://store.example.com/products/limited-sneaker.js" # Shopify product JSON
session = requests.Session()
etag, last = None, None
for _ in range(3): # in production, let your scheduler run each check
headers = {"If-None-Match": etag} if etag else {}
try:
r = session.get(URL, headers=headers, proxies=PROXIES, timeout=20)
status = r.status_code
except requests.RequestException as exc: # proxy refused (407), timeout or connection error
status = type(exc).__name__
if status == 304:
print("unchanged (304, no body downloaded)")
elif status == 200:
etag = r.headers.get("ETag")
in_stock = [v["title"] for v in r.json()["variants"] if v["available"]]
if in_stock != last:
print("in stock:", in_stock or "none")
last = in_stock
else:
print("unknown, keeping last state:", status) # never turn an error into "sold out"
time.sleep(30)Checked on 2026-10-18 (requests 2.33.1) through a local password-protected proxy, against HTTP and HTTPS store endpoints that send an ETag: the first check printed the sizes in stock and the next two came back 304 with no body; with a wrong password every check printed 'unknown' and kept the last state.
Check Does the store have a JSON endpoint? Does it send ETag or Last-Modified?
Fix Poll the JSON endpoint and send If-None-Match; if there's no ETag, compare only the fields you need.
Check Do you treat every non-200 as out of stock?
Fix Keep the last known state on errors; only a 200 response with available false means sold out.
Check How many products per IP, and how often?
Fix Add IPs and spread products across them; check slow-moving items less often.
Check Are you checking from the store's country, with the right region or store selected?
Fix Use an IP in the store's market and include the store's region or location parameter.
Fixed datacenter IPs for fast, cheap polling of stores that accept server IPs; rotating residential for stores that block them.
There's no universal safe rate. Start slow, watch for 429 responses, honour Retry-After, and give busy products their own IP.
Enough that each IP stays under the store's limit. Split your product list across IPs and add more if 429s appear.
Only where the server sends an ETag. Shopify product JSON returns availability per variant; whether a 304 comes back depends on the store's server.
Yes, on public product pages; follow each site's terms. If a site blocks or keeps challenging server IPs, move it to rotating residential.
Official documentation · Checked:
Official documentation · Checked:
Official documentation · Checked:
Official documentation · Checked:
Product observation · Checked:
Rotating residential per-GB prices as published on the pricing page and used by the console (Budget US$1.50/GB, US$1.35/GB in the 100 GB package; Premium US$5.00/GB; 1 PTC = US$1). Static ISP and datacenter IPs are quoted live per IP and term.
Product observation · Checked:
Option names, billing modes and limits as shown in the live console on 2026-10-18: Line (Premium/Budget), Exit mode, Region, State, City, Protocol (HTTP/SOCKS5), Quantity (1–500), Term, Auto-renew IP (not yet available), My assets → Copy / Rotate / Renew / Copy for AI. Rotating residential connects through proxy.proxy302.com:2222 (HTTP) and :3333 (SOCKS5). Static datacenter IPs were sold in 8 countries on 2026-10-18 (read-only check of the production catalogue): US, CA, GB, DE, NL, JP, KR, SG.
Local example · Checked:
The code block was executed on 2026-10-18 against a local password-protected HTTP proxy that answers 407 without valid credentials; requests 2.33.1 against a local store endpoint that sends an ETag: the first check printed the sizes in stock, the next two came back 304 Not Modified with no body, over plain HTTP and over HTTPS through a CONNECT tunnel. With a wrong password the proxy refused the tunnel (407) and every check printed 'unknown, keeping last state' instead of stopping.
A local check proves the configuration syntax and authentication path, not access to any specific website, country or platform.
Create an account, top up once and pick rotating residential, static ISP or datacenter. Rotating residential exits cover 195+ countries and regions.