{"slug": "lego-reselling-market-scanner", "title": "Lego Reselling Market Scanner", "summary": "A developer with no prior Python experience built a free tool that scans a BrickLink inventory against European sold and current-stock prices, outputting a spreadsheet identifying overpriced, underpriced, and correctly priced lots. The tool, part of an AI experiment on a LEGO business, requires Python 3, a BrickLink API account, and about 60-90 minutes to run due to BrickLink's rate limits.", "body_md": "This is the free tool from the \"AI experiment on my LEGO business\" video series. It scans your entire BrickLink inventory against real European sold and current-stock prices, and hands you back a spreadsheet telling you exactly which lots are overpriced, underpriced, or fine as-is.\n\nI had zero Python experience before building this — it was explained to me step by step until it worked. This manual is written the same way: assume nothing, explain everything.\n\n**No 1:1 support is offered for this tool.** I read every comment, but I can't debug everyone's individual setup. If you'd rather have a supported, polished tool instead of a free DIY script, BrickEconomy and Bricqer both offer similar market-pricing features as paid services.\n\n**A Windows, Mac, or Linux computer.**(Setup steps below are written for Windows since that's what I used — Mac/Linux steps are similar but the Python installer looks different.)**Python 3** installed on that computer.**A free BrickLink API account**(separate from your normal BrickLink login).** A current inventory export from your BrickLink store**, as a CSV file.** About 60-90 minutes**where your computer stays awake and connected to the internet — the scan itself takes this long due to BrickLink's own rate limits, not anything you can speed up.\n\n- Go to\n**python.org/downloads** and click the big \"Download Python\" button. - Run the installer.\n**This is the step people get stuck on:** on the first screen, look for a checkbox that says**\"Add python.exe to PATH\"** or**\"Add Python to environment variables.\"** Check it. If you don't see it on the first screen, click**\"Customize installation\"** instead of \"Install Now\" — you'll find the checkbox on the \"Advanced Options\" page instead.- Click Install, wait for it to finish.\n\n**If Windows says \"Python was not found\" when you try to run something later:** this usually means the PATH checkbox above got missed, or Windows' own \"app execution alias\" is intercepting the command instead of using your real Python install. If you see a message mentioning \"app execution aliases,\" go to **Settings → Apps → Advanced app settings → App execution aliases**, and turn OFF the entries for \"python.exe\" and \"python3.exe\" if any are turned on pointing to the Microsoft Store. Then close and reopen your terminal and try again.\n\n- Open a terminal:\n**Windows:** open the folder where you'll keep the script in File Explorer, click the address bar at the top, type`cmd`\n\n, press Enter. This opens a terminal already pointed at the right folder.**Mac:** open Terminal from Applications → Utilities.\n\n- Type this exactly and press Enter:\n\n```\npip install requests requests-oauthlib openpyxl\n```\n\n- Let it install. You'll see a bunch of text scroll by — that's normal. When it stops and gives you a new blank line, it's done.\n\n- Go to\n**partner.bricklink.com/api** and log in with your normal BrickLink seller account. - Register as an API consumer — this is free.\n**Important:** when it asks for an IP address to lock the key to, use`0.0.0.0`\n\ninstead of your actual IP. Your home internet's IP address changes periodically, and if it changes after you've locked the key to it, the API stops working with a confusing error.`0.0.0.0`\n\navoids that problem permanently.- You'll end up with\n**four separate values**: a Consumer Key, a Consumer Secret, a Token Value, and a Token Secret. Keep this page open — you'll need to copy all four into the script next.\n\n- Download\n`bricklink_market_scan.py`\n\nand put it in its own folder somewhere easy to find (e.g. Desktop → BrickLink Scanner). - Right-click the file and open it with Notepad (Windows) or TextEdit in plain-text mode (Mac).\n- Find these four lines near the top:\n\n```\nCONSUMER_KEY    = \"PASTE_YOUR_CONSUMER_KEY_HERE\"\nCONSUMER_SECRET = \"PASTE_YOUR_CONSUMER_SECRET_HERE\"\nTOKEN_VALUE     = \"PASTE_YOUR_TOKEN_VALUE_HERE\"\nTOKEN_SECRET    = \"PASTE_YOUR_TOKEN_SECRET_HERE\"\n```\n\n- Replace the text between the quotation marks with your real values from Step 3.\n**Keep the quotation marks**— this is the single most common mistake. If you accidentally delete a`\"`\n\nwhile pasting, you'll get an error like`SyntaxError: invalid decimal literal`\n\nwhen you try to run it. If that happens, reopen the script and check that all four lines still have a`\"`\n\nright before and right after your key. - Save the file (Ctrl+S / Cmd+S), keep it as a\n`.py`\n\nfile — don't let Notepad save it as`.txt`\n\n.\n\n- Log into BrickLink, go to your store inventory, and export it as a CSV file (BrickLink's own export tool handles this — look for \"Download\" or \"Export\" in your inventory management page).\n- Move that CSV file into the\n**same folder** as the script. - Open the script again in Notepad, find this line:\n\n```\nINVENTORY_FILE = \"invcsv_3.csv\"\n```\n\n- Change\n`\"invcsv_3.csv\"`\n\nto match your actual downloaded file's name, exactly — including capitalization. Keep the quotation marks. - Save the file again.\n\n- Open a terminal in the script's folder (same trick as Step 2: address bar → type\n`cmd`\n\n→ Enter, on Windows). - Type:\n\n```\npython bricklink_market_scan.py\n```\n\n- Press Enter. You should see a banner, then \"Connecting to BrickLink API... Connected!\", then it'll start working through your inventory, printing a progress update every 50 items.\n**Leave the window open and your computer awake.** For a store around 10-11k lots, expect roughly 60-90 minutes.**If anything interrupts it**— your connection drops, you close the terminal by accident, anything — just run the exact same command again. The script automatically picks up exactly where it left off instead of starting over. You will not lose progress.- When it finishes, you'll see \"DONE\" and a summary of how many lots landed in each category. A new file called\n`market_scan_results.xlsx`\n\nwill appear in the same folder.\n\nOpen `market_scan_results.xlsx`\n\n. Each row is one of your lots. The important columns:\n\n| Column | What it means |\n|---|---|\nYour Eff Price |\nYour actual price after your own discount is applied |\nSold 6m Avg / Min / Max |\nWhat this exact item (same part, color, condition) actually sold for on the European market over the last 6 months |\nStock Avg / Min / Max |\nWhat it's currently listed for by other EU sellers right now |\nvs Sold Avg % |\nHow far your price is from the recent average sold price |\nVERDICT |\nThe one you actually care about — see below |\nSuggested Price |\nA calculated suggestion based on the verdict |\n\n**How VERDICT is decided:**\n\n**OVERPRICED**— your price is more than 20% above the recent average sold price. Suggested price: 5% below that average.** UNDERPRICED**— your price is more than 15% below the recent average sold price. Suggested price: left as your current price (the tool flags it, it doesn't auto-raise it for you).**ABOVE MARKET**— no recent sales data exists, but your price is more than 30% above the cheapest current listing. Suggested price: 5% above that cheapest listing.**COMPETITIVE**— none of the above triggered. You're in a reasonable range.** NO DATA**— no sold history and no current stock data exists for this exact combination anywhere in Europe. Usually means a rare item, an unusual color, or something genuinely hard to price-check.\n\nThe spreadsheet is colour-coded to match (red = overpriced, yellow = underpriced, green = competitive, grey = no data) and has filters enabled on every column, so you can sort straight to your OVERPRICED rows first.\n\n**What to do with it:** this spreadsheet is a data source, not a final answer. I upload mine to Claude afterward and work through an actual repricing strategy from there — the script's only job is gathering honest market numbers, not deciding what to do with them.\n\n**\"Python was not found\" / installer prompt about app execution aliases**\nSee the note at the end of Step 1.\n\n** SyntaxError: invalid decimal literal**\nA quotation mark got deleted around one of your API keys. Recheck all four lines from Step 4.\n\n**\"[ERROR] Fill in your API keys\" even though you did**\nMake sure you saved the file after editing (Ctrl+S), and that Notepad didn't save it with a `.txt`\n\nextension added onto the end (check the actual filename in File Explorer, not just the Notepad title bar).\n\n**\"[ERROR] 'yourfile.csv' not found!\"**\nThe filename on the `INVENTORY_FILE`\n\nline doesn't exactly match your actual CSV file's name, or the CSV isn't in the same folder as the script. The error message will list every `.csv`\n\nfile it can actually see in that folder — check the name matches one of those exactly.\n\n**It seems stuck / not moving**\nIt's normal for there to be no visible output between the \"every 50 items\" progress updates — it's still working, just pacing itself to respect BrickLink's rate limits. If it's been stuck with zero output for several minutes with no progress update at all, something's actually wrong — close it and run it again, it'll resume from where it left off.\n\n**Rate limited message appears**\nThis is expected occasionally on larger stores — the script automatically waits and retries on its own. No action needed from you.\n\n**A lot of NO DATA verdicts**\nNormal for rare parts, unusual colors, or minifigs/sets with very little trading history. Not a sign anything's broken.\n\nThe script's only job is gathering honest market data — it never touches your BrickLink prices directly. To turn the spreadsheet into real changes, upload `market_scan_results.xlsx`\n\nto Claude (or your AI tool of choice) and ask it to generate BrickLink inventory-update XML files from it.\n\nA working starting prompt:\n\n```\nHere's my BrickLink market comparison spreadsheet (from the price scanner\nscript). Please:\n\n1. Exclude any item where Type = SET from all price cuts — retired sets\n   appreciate over time and shouldn't be discounted like commodity parts.\n   Also exclude MINIFIGS from price cuts for the same reason — retired\n   and rare minifigs tend to hold or gain value rather than behaving like\n   commodity parts.\n2. Generate BrickLink Mass Inventory Update XML — formatted so it can be\n   pasted directly into BrickLink's \"Update existing inventory\" box\n   (the bottom box on the Mass Inventory Update page, not the top one\n   used for adding new stock).\n3. Split into raises and cuts as separate files. If the total number of\n   lots exceeds BrickLink's per-upload limit, split further into\n   multiple sequential files instead of one.\n4. Round all prices to 2 decimal places.\n5. Flag any individual price change that looks like a potential data\n   anomaly (e.g. a jump of several times the current price) in a separate\n   list, so I can manually verify it against BrickLink's own price guide\n   before uploading anything.\n```\n\n**Three things worth knowing before you do this yourself:**\n\n**Exclude sets and minifigs from cuts.** Retired LEGO sets and rare/retired minifigs tend to appreciate rather than depreciate — treating them like commodity parts and discounting them because they haven't sold recently is usually the wrong call.**BrickLink caps how many lots you can update in a single upload file.** Check BrickLink's own upload page for the current exact limit — it can change over time. If your store is large, expect the output to come back as several files instead of one, and that's expected, not an error.**Always spot-check large suggested price jumps before uploading**, especially anything jumping several times its current price. Look the specific item up on BrickLink's own Price Guide page directly and compare. Occasionally an item code gets mismatched, or the market data is genuinely thin for a rare part — either way, a 30-second manual check before a bulk upload is worth it. Upload raises first (pure upside, no risk), verify they look right, then upload cuts.\n\n**How the upload actually works — there's no direct file upload button.** BrickLink doesn't let you attach or import the XML file directly. Instead:\n\n- Open the XML file in Notepad (or any plain text editor).\n- Select all the text and copy it.\n- Go to BrickLink's\n**Mass Inventory Update** page in your seller account. - You'll see two separate boxes: a\n**top box for adding brand new stock**, and a** bottom box for updating stock you already have listed**. Since you're changing prices on existing lots, paste into the** bottom box**. Pasting into the wrong one will attempt to create new inventory instead of repricing what you've already got — double-check which box you're in before pasting. - Do your raises first (pure upside, no risk of losing money), confirm they applied correctly, then do your cuts.\n\nThis script only ever touches your inventory data and BrickLink's public market pricing data. It never reads or transmits customer names, addresses, emails, or any other personal buyer information — the only customer-related value used anywhere in this whole process (across the video series, not just this script) is the order number, and only for counting/matching purposes, never displayed or exported.\n\nYour API keys and your data stay on your own computer the entire time. Nothing is uploaded anywhere unless you choose to upload the resulting spreadsheet somewhere yourself.\n\n*Not affiliated with or endorsed by BrickLink, BrickEconomy, or Bricqer. Use at your own risk — always double-check suggested prices before applying them to your store.*", "url": "https://wpnews.pro/news/lego-reselling-market-scanner", "canonical_source": "https://gist.github.com/svbrickshop-droid/2f5ae1ea7fa3aa405691814c20dc8c68", "published_at": "2026-07-25 13:11:32+00:00", "updated_at": "2026-07-26 07:58:13.110821+00:00", "lang": "en", "topics": ["developer-tools"], "entities": ["BrickLink", "BrickEconomy", "Bricqer", "Python"], "alternates": {"html": "https://wpnews.pro/news/lego-reselling-market-scanner", "markdown": "https://wpnews.pro/news/lego-reselling-market-scanner.md", "text": "https://wpnews.pro/news/lego-reselling-market-scanner.txt", "jsonld": "https://wpnews.pro/news/lego-reselling-market-scanner.jsonld"}}