Every limited release, whether it is a sneaker collab, a Pokémon TCG Elite Trainer Box, or a designer toy, follows the same pattern. A store sells it at retail. It sells out in minutes. Then some of it shows up on eBay and StockX above retail, sometimes well above, sometimes barely enough to cover fees. The people who catch the retail units are usually not smarter than you. They just found out about the restock sooner, often by seconds to a few minutes.

(Leave alcohol off your list. Reselling liquor without a license is illegal in most US states, and eBay bans most alcohol listings.)

Reseller groups (“cook groups”) charge $20 to $60 a month for that early warning. The tool behind most of those alerts is a restock monitor: a script that polls store inventory and posts to Discord the moment something comes back in stock. You can build one yourself in an afternoon. A large share of independent drop shops (sneaker boutiques, hobby and card stores, streetwear brands) run on Shopify, and almost every Shopify store exposes a public, unauthenticated product feed at /products.json.

This guide covers how that feed works, a ~90-line Python monitor that sends you a Discord ping with a one-click cart link, a profit calculator, real fees and capital numbers, and the grey part: what full-time resellers do to get past purchase limits, and why it gets their orders cancelled and accounts banned.

How the money works

The trade is simple: buy at retail, sell at market. The edge is speed and information.

  • Shopify’s public feed. Visit https://anystore.com/products.json on a Shopify store and you get JSON with every product, every variant, its price and an available true/false flag. No login and no API key. It is the same data the storefront uses to render the page.
  • Cart permalinks. Shopify supports https://store.com/cart/VARIANT_ID:1. Opening that URL drops the item straight into a cart. Your monitor can hand you a link that skips the product page, the size picker and the “add to cart” click. That saves 5 to 15 seconds, and on a 40-unit restock that is often the whole difference.
  • Resale comps. eBay sold listings show what the item actually sells for, not what people are asking. Your alert includes a pre-built sold-comps link so you can decide in two seconds whether a restock is worth buying.

A realistic per-unit example with a sealed TCG box that retails around $60 and has been selling for $110 on eBay:

LineAmount
Buy price + ~8% sales tax−$64.79
eBay sale price+$110.00
eBay final value fee (13.25% on sale + tax, trading card category) + $0.40 order fee−$16.14
Shipping label (padded box, USPS Ground Advantage)−$10.00
Net profit≈ $19 (≈29% ROI)

That is the honest unit economics of most hype items: $15 to $40 per unit, with occasional $100 to $300 hits on true limited collabs. Keep that number in mind. It drives everything in the earnings section.

What you need

  • Python 3.10+ and the requests library (free)
  • A Discord server + webhook (free). Server Settings → Integrations → Webhooks → New Webhook → Copy URL
  • A small always-on machine, ideally on your home connection. A Raspberry Pi or an old laptop at home is the best choice. Many Shopify stores rate-limit datacenter IPs on this feed. When we tested from a cloud server, four out of four Shopify stores returned 429 Too Many Requests on the very first request. A $4 to $6/month VPS (DigitalOcean, Hetzner, Vultr) can work, but run curl -I https://STORE/products.json from it before you build on it
  • A list of Shopify stores that drop what you want to flip. Test each one by opening /products.json in a browser. If you get JSON, it works
  • Capital: $1,000 to $3,000 to start. Less than that and one bad flip that sits for two months freezes your whole bankroll
  • An address in the store’s shipping region. Most US drop stores ship US-only or charge a lot for international shipping, and many cancel orders going to known package-forwarder addresses. If you are outside the US, run the monitor on stores in your own region. The code does not care which country the store is in
  • eBay seller account (and optionally StockX for sneakers)

Step 1: Pick stores and keywords

Create two text files next to the script.

stores.txt, one per line. You can point at the whole store or at a single collection, which matters on big stores because /products.json returns at most 250 products per page:

examplesneakers.com
examplecards.com/collections/pokemon
examplehobby.com/collections/new-arrivals

keywords.txt, one rule per line. All words on a line must appear in the product title:

elite trainer box
booster bundle
jordan 4
dunk low

Also open https://STORE/robots.txt. If it contains Disallow: /*.json or similar, the store has asked bots to stay off this feed, so leave it out.

Start with 10 to 20 stores. More stores means more requests, and that is how you get rate-limited (see Step 4).

Step 2: The monitor

Save as monitor.py:

#!/usr/bin/env python3
import os, random, sqlite3, sys, time
import requests

STORES = [s.strip() for s in open("stores.txt") if s.strip() and not s.startswith("#")]
KEYWORDS = [k.strip().lower() for k in open("keywords.txt") if k.strip()]
WEBHOOK = os.environ["DISCORD_WEBHOOK"]
POLL_SECONDS = 45
UA = ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
      "(KHTML, like Gecko) Chrome/129.0 Safari/537.36")

db = sqlite3.connect("seen.db")
db.execute("CREATE TABLE IF NOT EXISTS variants (id INTEGER PRIMARY KEY, available INTEGER)")
session = requests.Session()
session.headers["User-Agent"] = UA


def fetch_products(store):
    r = session.get(f"https://{store}/products.json?limit=250", timeout=15)
    if r.status_code == 429:
        raise RuntimeError("rate limited (429), slow down")
    r.raise_for_status()
    return r.json()["products"]


def matches(title):
    t = title.lower()
    return any(all(w in t for w in rule.split()) for rule in KEYWORDS)


def ebay_sold_url(title):
    q = requests.utils.quote(title)
    return f"https://www.ebay.com/sch/i.html?_nkw={q}&LH_Sold=1&LH_Complete=1"


def alert(store, product, variant, kind):
    domain = store.split("/")[0]
    handle = product["handle"]
    title = product["title"]
    vid = variant["id"]
    vtitle, price = variant.get("title", ""), variant["price"]
    desc = (f"**{vtitle}**  |  ${price}\n"
            f"[ADD TO CART](https://{domain}/cart/{vid}:1)  |  "
            f"[eBay sold comps]({ebay_sold_url(title)})")
    embed = {
        "title": f"{kind}: {title}"[:256],
        "url": f"https://{domain}/products/{handle}",
        "description": desc,
        "color": 0x2ECC71 if kind == "RESTOCK" else 0x3498DB,
        "footer": {"text": domain},
    }
    if product.get("images"):
        embed["thumbnail"] = {"url": product["images"][0]["src"]}
    session.post(WEBHOOK, json={"content": "@here", "embeds": [embed]}, timeout=10)


def scan(store, seed):
    for p in fetch_products(store):
        if not matches(p["title"]):
            continue
        for v in p["variants"]:
            now = 1 if v.get("available") else 0
            row = db.execute("SELECT available FROM variants WHERE id=?", (v["id"],)).fetchone()
            if now and not seed:
                if row is None:
                    alert(store, p, v, "NEW")
                elif row[0] == 0:
                    alert(store, p, v, "RESTOCK")
            db.execute("INSERT OR REPLACE INTO variants VALUES (?, ?)", (v["id"], now))
    db.commit()


def main():
    seed = "--seed" in sys.argv
    while True:
        for store in STORES:
            try:
                scan(store, seed)
            except Exception as e:
                print(time.strftime("%H:%M:%S"), store, "ERR", e, flush=True)
            time.sleep(random.uniform(1, 3))
        if seed:
            print("Seeded current stock. Run again without --seed.")
            return
        time.sleep(POLL_SECONDS + random.uniform(-10, 10))


if __name__ == "__main__":
    main()

What it does:

  • Pulls each store feed, keeps only products matching your keywords
  • Remembers every variant’s stock state in SQLite
  • Fires NEW when a matching variant appears in stock for the first time, and RESTOCK when something that was sold out flips back to available
  • Each alert has the price, a cart permalink and an eBay sold-comps link, and pings @here so your phone actually buzzes
  • Jitters timing so you are not hitting stores on a perfectly regular clock

Step 3: Run it 24/7

mkdir -p ~/monitor && cd ~/monitor
python3 -m venv venv && venv/bin/pip install requests
# put monitor.py, stores.txt, keywords.txt here
export DISCORD_WEBHOOK="https://discord.com/api/webhooks/XXXX/YYYY"
venv/bin/python monitor.py --seed   # record current stock, no alerts
venv/bin/python monitor.py          # start watching

Always seed first, or the first run alerts on every in-stock item and floods your channel. If the seed run prints ERR for a store (for example a 429), that store was not recorded. Fix it or remove it and seed again, or its whole catalog will fire as NEW on the first real run. To keep it alive after you close SSH, create /etc/systemd/system/monitor.service:

[Unit]
Description=Shopify restock monitor
After=network-online.target

[Service]
WorkingDirectory=/home/ubuntu/monitor
Environment=DISCORD_WEBHOOK=https://discord.com/api/webhooks/XXXX/YYYY
ExecStart=/home/ubuntu/monitor/venv/bin/python monitor.py
Restart=always
RestartSec=30

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload && sudo systemctl enable --now monitor
journalctl -u monitor -f    # watch for ERR lines

Step 4: Do not get your monitor blocked

Shopify and the bot-protection layers in front of big stores do rate-limit this feed. Signs you are pushing too hard: 429 errors, 403 pages, or JSON suddenly replaced by a challenge page.

  • 45 seconds per store is a sane default. Polling every 2 seconds will not make you money. It gets your IP blocked for the one drop that matters
  • Point at collections, not whole stores. A 250-product feed can be 100 to 300 KB even gzipped. Twenty stores every 45 seconds works out to several GB a day. That is fine on a home connection and expensive on paid proxies
  • Residential proxies (roughly $2 to $8 per GB pay-as-you-go, depending on provider and volume) let you poll faster without one IP taking all the heat. Do the bandwidth math above before you buy them. Most solo flippers do not need them
  • Some stores lock the feed down or hide drop products until launch. For those, follow the store’s Instagram or Discord. No script fixes that

Step 5: The buy decision (10 seconds, not 10 minutes)

When the phone buzzes:

  1. Glance at the price in the alert
  2. Tap eBay sold comps and look at the last 10 sold prices, ignoring the outliers
  3. Run the number in your head, or keep this function handy:
def net_profit(sale, cost, tax=0.08, fee=0.1325, order_fee=0.40, label=10.0, supplies=1.0):
    landed = cost * (1 + tax)
    ebay = sale * (1 + tax) * fee + order_fee   # eBay charges FVF on the total incl. tax
    return round(sale - ebay - label - supplies - landed, 2)

print(net_profit(110, 59.99))   # ~18.07
print(net_profit(85, 59.99))    # ~-3.35  -> skip
  1. Rule of thumb: buy only if the expected net is above $15 per unit or 25% ROI. Below that, one return or one price dip wipes out the profit
  2. Tap ADD TO CART and check out with autofill and a saved card. Shop Pay with a saved card is the fastest checkout on Shopify stores

Fees differ by category. eBay charges 13.25% on most trading card sales and 13.6% on most other categories, plus $0.30 to $0.40 per order. Sneakers sold for $150 or more have a reduced fee (8%, no per-order fee). StockX takes a transaction fee of roughly 7 to 9% depending on seller level, plus 3% payment processing. Check the current fee pages before you trust any number here, because both platforms change them.

Step 6: Sell

  • Sealed TCG product, toys, collectibles: eBay. List within a day, because hype prices decay fast after a restock wave
  • Sneakers: StockX or GOAT for zero customer-service hassle, eBay Authenticity Guarantee for slightly better net
  • Bulk exits: local card shops and Facebook groups pay 70 to 85% of market, in cash, the same day. That is useful when a price is collapsing

Honest cost breakdown

ItemCost
VPS or Raspberry Pi$4 to $6/month (or ~$80 one-off for a Pi)
Discord, Python, Shopify feedsFree
Shipping supplies$0.50 to $1.50 per unit
Residential proxies (optional)~$2 to $8/GB
Cook group (optional, for drop calendars)$20 to $60/month
Working capital$1,000 to $3,000 to start, $8,000+ to scale
Time~1 hour to set up, then 5 to 20 hours/week buying, packing, shipping

The script is effectively free. Capital and time are the real costs.

Realistic earnings

Be honest with yourself about the per-unit number. At $15 to $40 net per unit, income is just units × margin, and purchase limits cap the units.

The table below is arithmetic, not a promise: units you might realistically buy × the $15 to $40 margin above. These are not tracked results from real sellers. Your first month may well be close to zero while you tune stores and keywords.

SetupUnits/month (if you hit)Net/month (math)Capital tied up
Part-time, one account, manual checkout, 15 stores10 to 40$150 to $1,200$1,000 to $3,000
Serious: 40+ stores, several categories, plus in-store retail100 to 200$1,500 to $5,000$8,000 to $20,000 rotating
Occasional true hype collab (one pair or box)0 to 3+$100 to $300 each—

The top row is the honest starting point. The middle row is a full-time job, and with one account and one card, purchase limits usually stop you before you reach it. That brings us to the grey part.

The grey area: how big resellers get past limits

Stores cap orders at 1 to 2 per customer per drop. Full-time resellers get around the cap with:

  • Multiple accounts and payment cards. Family members’ cards, virtual cards (Privacy.com in the US and similar services) and several email aliases
  • Address “jigging.” Small variations of the same address (Apt 4 / #4 / Unit 4, extra characters in line 2) so the store’s duplicate-order filter misses them
  • Checkout bots. Paid software that fills in and submits checkout in under a second across dozens of profiles. Licenses usually cost a few hundred dollars plus renewals, and aftermarket prices for popular bots swing much higher
  • Raffle multi-entry. Many boutiques sell hype releases through raffles instead of first-come. Entering 20 times under different names is the norm in reseller circles

Is it illegal? In the US and most of Europe, buying sneakers, cards or toys with bots or multiple accounts is not a crime. It breaks store terms of service. The big exception is event tickets: the US BOTS Act of 2016 makes using bots to get around ticket purchase limits illegal, and the FTC has enforced it. Several other countries and US states have similar ticket rules. Do not point any of this at tickets. Also note the line between grey and criminal. Using your own or your family’s real cards with their permission is ToS evasion. Using cards, identities or accounts that are not yours is fraud. There is no grey area there.

What actually happens to people who push it:

  • Mass cancellations. Stores run post-drop audits that match addresses, cards, IPs and device fingerprints. Jigged orders often get cancelled in batches hours later. Your card was authorized and then refunded, and you lost the chance to buy elsewhere
  • Account and address bans. Bans are permanent at some retailers and cover every name at that address
  • Card issuer flags. Dozens of rapid declines and authorizations across stores can trigger fraud locks on your own cards right in the middle of a drop
  • Shopify checkout queues and bot protection on hype releases make cheap bots useless, so the arms race costs money every season

The monitor in this guide stays on the safe side of all this. It reads public data at a polite rate and hands a human a link. Everything past that is a risk you choose to take.

Other risks (even if you play clean)

  • Price collapse. Restocks and reprints crush resale prices. Many TCG products that sold at 2x retail in launch week sold near retail a few months later after reprints. Sneaker resale has cooled since 2022, and plenty of general releases now sell below retail
  • eBay payment holds. New sellers can have funds held for up to about 30 days, or until delivery is confirmed. Budget your capital for that delay
  • Return and “resealed” claims. Buyers of sealed products sometimes claim tampering. Film yourself packing high-value items
  • Store ToS on the feed. Reading a public JSON endpoint is generally treated like reading the website. Hammering it until the store has to block you is not. If a store blocks you, take the hint and drop it from stores.txt. Do not rotate IPs to get around an explicit block
  • Taxes. Resale profit is taxable income. In the US, platforms issue a 1099-K above the federal $20,000 / 200-transaction threshold, but you owe tax on profit either way. Keep every receipt

Reality check: what does not work

  • Monitoring Nike, Walmart or Target with this script. They do not run Shopify, and their bot defenses are a different league. This is a tool for independent stores
  • Buying everything that restocks. Most restocks are restocks because demand is weak. Without the sold-comps check you are just collecting inventory
  • Polling every 2 seconds. You get blocked, and the real bottleneck is your thumbs at checkout, not the monitor
  • Expecting first-week prices to hold. List fast. Hype decays in days, not months
  • Scaling capital before you have a hit rate. Track every buy in a spreadsheet: cost, sale, fees, days to sell. If your average is under $15 net per unit after a month, fix your store and keyword list before you add money
  • Selling alerts before you have results. Running a paid cook group off this monitor ($20 to $60/month per member) is a real side business, but nobody pays for a channel that cannot show checkouts

Start today

  1. Open /products.json on 15 Shopify stores in your niche and keep the ones that return JSON
  2. Write keywords.txt with 5 to 10 products that sell above retail right now (check eBay sold listings)
  3. Create a Discord webhook, deploy monitor.py on a Pi at home (or a $5 VPS that passed the curl test), then seed and start it
  4. For the first two weeks, buy only alerts that pass the $15 / 25% ROI rule, list within 24 hours, and log every number
  5. Once you see your real hit rate and margin, decide whether to scale with capital, more stores, or a paid alert group, and decide how much ToS risk you are willing to carry