Inspiration

What actually makes a shopping website a scam? We've all had that moment scrolling through Instagram where an ad catches your eye, the clothes look great, so you order it. Then it shows up looking nothing like the photos, or it just... never shows up at all. By then it's too late, you've already paid. So we built Sham to catch that before you order, not after.

What it does

Sham gives you a quick read on whether a store and its products can actually be trusted, right before you buy. It digs through Reddit and Instagram using Backboard.io to surface any scam reports or genuine good experiences tied to the company. It also checks the reviews sitting right on the product page and flags whether they read like they were written by an AI instead of a real customer using GPTZero.

How we built it

Sham is a Chrome extension (built with WXT) paired with a FastAPI backend. When you're on a store's page, the extension reads whatever it can off the live page: the URL, any Instagram links on the page, and the actual review text rendered by the store's review widget (Judge.me, Loox, Yotpo, Amazon, etc.). It then sends it to our backend to be scored.

The backend then runs a few checks in parallel and combines them into one overall risk score:

  • Reddit research, via Backboard.io's web search tool. We ask it to search Reddit for scam reports or genuine praise about the brand, then have it extract its own findings into structured data we can score and verify (we double-check every URL it returns actually resolves, so we're not trusting a hallucinated Reddit link).
  • Instagram social proof, via Apify's instagram-scraper actor. Once we've found the store's Instagram handle, we pull the account's profile info and its recent posts' comments, then have an LLM flag any comments where customers are complaining about non-delivery, counterfeits, or refund problems plus a separate check for duplicate comments across accounts, a sign of bot engagement.
  • Review authenticity, via GPTZero. This was the trickiest piece: most stores load their reviews in with JavaScript after the page loads, so a normal backend fetch just sees an empty box. Instead, the extension reads the reviews directly out of the page in the user's own browser, after the widget has already done the work of rendering them so no scraping infrastructure needed. Critically, we never let an LLM touch that text before scoring it, since even a light AI rewrite of a genuine review gets flagged by GPTZero as 100% AI-written and ruins the signal.

Challenges we ran into

Fetching reviews turned out to be harder than expected. Most stores load their reviews in through third-party widgets that render on the client side, so our backend would just hit an empty page with nothing there to scrape. We had to get creative and read the reviews straight out of the page in the user's own browser instead.

We also struggled with figuring out what actually defines a scam. Domain age felt like an obvious signal at first, since surely a brand-new domain is riskier, but that assumption fell apart once we realized plenty of scam sites just buy older, cheaper domains specifically to look established.

Accomplishments that we're proud of

We're proud of incorporating social media insights from Reddit and Instagram to provide better context for the user to prevent getting scammed.

We also created a way to get access to the reviews from websites without fetching the website from the backend. Most review widgets (Judge.me, Loox, Yotpo, and others) only load the actual review text into the page after the page has already loaded in a browser, so a backend server trying to fetch the page directly just gets an empty container, and a lot of these stores block scripted requests anyway. Our workaround was to have the extension read the reviews straight out of the live page, inside the user's own browser, after all that JavaScript has already run and any anti-bot walls are already behind us. Turns out that's way more reliable than any server-side fetch could ever be.

What we learned

A lot of "obviously a scam signal" ideas fall apart the moment you test them against real data, domain age being the big one, since scammers now just buy older domains because they're cheaper than new ones. We also learned the hard way that letting an LLM touch a review before scoring it completely destroys the signal: the exact same reviews that scored as 0% AI-written flipped to 100% AI-written after a single LLM pass, because at that point GPTZero is just scoring the LLM's writing, not the customer's. That's what pushed us to keep the review pipeline strictly deterministic scraping with no LLM anywhere near the review text. Beyond that, we learned a lot about stitching together multiple third-party APIs (Backboard, Apify, GPTZero) into one coherent risk score, and how much anti-bot protection you have to work around just to get real data off the open web.

What's next for Sham

We want to properly validate our AI-review-detection thresholds against a much bigger labeled set of real scam and legit stores, instead of the estimated cutoffs we're shipping with now. We'd also like to expand review extraction beyond Shopify-style widgets to platforms like WooCommerce, and add Trustpilot as a secondary review source when a storefront's own widget is thin. On the infra side, per-domain caching would make repeat checks near-instant, and once the Instagram and Reddit signals are validated the same rigorous way, we'd give them more weight in the overall score. Longer term, we'd love for Sham to grow beyond clothing storefronts into anywhere people get talked into buying something they'll regret.

Built With

Share this project:

Updates

Submission history