Skip to main content

Found. Is the Company Merch Catalog I Wanted to Exist

I built FoundMerch.com to collect and preserve interesting company merch in one searchable place. This is how I curate it and how the scraper turns 42 very different stores into one catalog.

By

Some of the best company merch barely looks like company merch.

SpaceX sells an asteroid plush. Boston Dynamics once sold a baby bib with its industrial robot on it. Discord has safety tarot cards. Vercel has an Acme pacifier. WinRAR turned its archive icon into a messenger bag.

They all live in separate stores built on different platforms. Some shops are easy to find. Others sit on a company subdomain that is barely linked. A good drop can appear, sell out, and disappear before most people know it existed.

I wanted one place where I could browse all of it.

So I built FoundMerch.com.

Found. is a searchable catalog and archive of official company merch. The published snapshot from 23 August contains 1,582 products across 42 stores, including 370 archived pieces that are no longer sold. Found does not sell any of it. Every product points back to its original store.

I find and review the stores, decide what belongs in the collection, investigate the strange results, and maintain the public catalog. A scraper I built handles the repetitive work of checking 42 very different storefronts and turning them into one consistent feed.

Found. is the collection. The scraper is how I keep up with it.

Company Merch Is More Interesting Than Logo Tees

Bad company merch is easy to make. Put a logo on a blank shirt, add a mug and a tote bag, then call it a store.

The interesting pieces do something else. They make a company’s internal culture physical.

A Palantir chore coat presents the company more like a field operation than a software vendor. Duolingo can turn a streak, an owl and the threat of a missed lesson into plush toys, slippers and a small piano. OpenAI’s archive is full of model names, research references and old internal designs. The WinRAR messenger bag turns its stacked-books desktop icon into the structure of an actual object.

That is the stuff I care about: launch artifacts, internal jokes, mascots, collaborations, uniforms, strange accessories and pieces that are good enough to exist without the company logo doing all the work.

Some of it is expensive. Some of it is ridiculous. Some of it is genuinely well designed. Often it is all three.

Company stores are also unusually temporary. They move domains, change operators, hide old collections, replace their platforms and quietly remove sold-out products. Search engines usually keep a stale result for a while, then the object is gone.

Found. gives those objects somewhere to exist together.

What You Can Do on Found.

The main catalog lets you search by product or company, filter by store, category or archive state, browse my Staff Picks, and sort by newest, trending or most upvoted.

The rest of the site grew around the same collection:

  • Stores is a searchable directory of every official storefront currently tracked, with an item count for each one.
  • Updates is the weekly change log: new products, delistings, restocks, sell-outs and price movement found between catalog snapshots.
  • Leaderboard lets people upvote individual pieces. Those votes also drive the Trending and Top Voted views in the catalog.
  • Market is a moderated second-hand directory for company merch that has escaped its original store. Sellers submit a listing for review and buyers contact them through the listing; Found does not process the sale.
  • Suggest a Store is where people can send me an official shop, launch archive or limited storefront I have missed.

Individual catalog items can be shared with a Found. link, the full catalog is available as a public JSON feed, and the original source stays attached to every item. Found is a discovery layer, not another checkout.

The archive is just as important as the live catalog. If a good product sells out, it does not become less interesting. It only stops being buyable.

The First Catalog Got Bigger and Worse

The earliest tracked version of the project appeared on 24 April 2026. The scraper still lived inside the website and produced 2,331 rows across 31 stores.

Within the same burst of work, it expanded to 11,040 rows across 105 stores.

That looked impressive until I inspected it.

In that file, 7,497 rows duplicated a product URL, including 4,744 exact duplicate rows. It also contained plenty of legitimate products I did not particularly want in Found. A crawler can successfully extract a generic logo mug. That does not make the catalog better for having it.

I wrote the standard less elegantly at the time: visually check every store and make sure it is not “just random store shit.”

On 27 April, I cut the catalog from 11,040 rows and 105 stores to 661 products across 20 stores. Duplicate product URLs went to zero. More than ten thousand rows disappeared, and Found became more useful.

That reset established the real product. Found. was not going to be everything a crawler could emit. It was going to be an edited collection of official stores and interesting company objects.

That does not mean I personally bless every individual shirt in a 1,582-product feed. The curation happens at several levels. I maintain a broader registry of candidate sources, choose which stores become active, review unusual discoveries, cut obvious filler when a store needs a tighter import, choose Staff Picks, and decide which new material belongs in a release.

Boston Dynamics was an early example. I cut one import from 22 products to nine, keeping build sets, pins, patches, Plushie Spot and pewter robot replicas. Most of the generic apparel did not survive that pass. The robot bib came back later as an archived piece.

I still make the call on what belongs.

It Took a While to Become Found.

The first names were all too literal.

First it was TechSwag. Then Dropboard. I went through SwagRadar, CompanyDrops, ClotheDex and an increasingly bad pile of literal names. At one point I said they all sounded like AI-generated trash.

On 3 May, I renamed it Found. and moved it to foundmerch.com.

The name fit the product better. The useful moment is not “indexed.” It is finding a store you did not know existed or a product you assumed had vanished.

The visual direction followed the same idea. I did not want a generic SaaS directory with cheerful cards explaining the value proposition. I wanted something closer to an editorial archive: mostly monochrome, led by product imagery, dense enough to browse, and restrained enough that a strange object could carry the page.

Availability also needed restraint. A loud green In stock badge suggests a level of certainty I do not have across every size and variant in 42 independent stores. Found still tracks availability, but it keeps archived and uncertain items visible instead of turning the interface into a wall of stale promises.

The Scraper Underneath It

By the time I split it out, the scraper had grown into a roughly 2,000-line script living beside the frontend. It knew local paths, wrote large generated files straight into the web project and carried browser caches around with the public app.

That was enough to prove the idea. It was not how I wanted to run it.

At the end of April, I removed the collection process from the website. Found. became a consumer of reviewed product data. In May, I turned the scraper into its own Node.js toolkit with a store registry, isolated output snapshots, audits, tests and an explicit publication step.

That separation is still fundamental. A scrape can fail without damaging the public catalog.

Calling it “a scraper” makes it sound more uniform than it is. The stores disagree about almost everything. Some expose clean Shopify JSON. Others use JSON-LD, sitemaps, merchant feeds, GraphQL, React payloads or product data that only appears after the page renders. A few have their own extraction path because the generic methods are not enough.

The scraper brings those sources into one product shape: store, title, images, source URL, availability, variants and evidence where available. It normalises URLs and names, merges duplicate evidence, and keeps discovery separate from the question of whether something can actually be bought. The publication step reconciles that output with Found’s archive.

A normal full run now looks like this:

official stores I have approved
fresh isolated scan across every active store
normalise products, merge evidence, remove duplicates
per-store reports and human review
compare with the current Found. catalog
products feed, Updates feed, build and deployment

Found’s publication path only accepts public storefront data. The toolkit can inspect an authorised store session when I explicitly supply one, but anything marked authenticated is blocked from the public export.

Forty-Two Stores That Disagree About Everything

The web exposes plenty of convincing-looking bad data: sitemap URLs for dead products, $0 archive placeholders, related-product prices attached to the wrong item, and pages that load successfully with no useful product data.

OpenAI’s public archive made that obvious. One July import contained 135 historical products; 125 had zero-dollar placeholder prices, and none had a public cart path. Calling them free would have been technically easy and plainly wrong.

That is why Found records where a row came from and whether it appears buyable as separate facts.

This work also made the full run much faster. One 42-store scan took 23 minutes and 6 seconds. After improving connection reuse, bounded discovery and extractor selection, the same class of run completed in 3 minutes and 36 seconds.

The first fast result still did not ship. It had contaminated prices, bad classifications and one store that could have lost 46 existing products. Speed only mattered after the output described the merch correctly.

Sold Out Does Not Mean Delete

Most commerce systems are designed around what can be sold now. When a product disappears, removing it is normal.

Found. has a different reason to keep it.

The Boston Dynamics robot bib is still a good company artifact after the last one sells. An old OpenAI research tee still shows part of the company’s history. A sold-out collaboration can be the piece somebody searches for six months later when it appears second-hand.

That is why archived products stay in the catalog.

If a complete, healthy store scan no longer returns a known product, Found keeps the row and archives it. If the store is gated, partial or broken, the absence proves less. In that case, the previous row stays unchanged until I can verify the store again.

Operationally, I treat those as three different cases:

  • the store currently shows the product as available;
  • the product is known but archived or unavailable;
  • the scan cannot establish a new state, so the previous row is preserved.

In the published 23 August snapshot, 1,212 rows were not archived, but only 1,021 explicitly reported available: "yes". Found. is a dated view of what public stores showed, not a promise that every size can complete checkout right now.

What I Do After a Scrape Finishes

The scraper does not run Found. by itself. A completed scan is the start of the editorial and release work.

I review coverage for every active store, inspect the per-store changes, look at missing images and prices, check duplicate identities, and investigate large contractions. If a store needs a special extractor or a public rendered-page import, I repair the tool rather than hand-editing the final feed around it.

Then I decide the release scope. I can refresh one reviewed store, admit a new source, hold new discoveries while updating known products, or retire a store deliberately. The public feed and the weekly Updates feed are generated together, then the site is checked, built, deployed and inspected as a visitor would see it.

The admin side of Found. lets me feature or hide products, correct display details, set up leaderboard campaigns and review Market submissions.

During one July release, the scan found 48 genuinely new products, but the Updates generator also announced that 133 archived OpenAI products had come back in stock. They had not. Archive rows surviving from one snapshot to the next had been mistaken for restocks.

I fixed the comparison at its source, added a regression test, rebuilt the feeds and checked the deployed page again. I did not correct the generated JSON by hand, because the same bug would have returned on the next release.

The Collection Is the Product

Found. has grown beyond the grid I started with, but the reason I keep working on it has not really changed.

Company merch is scattered, temporary and much stranger than the usual logo tee suggests. I like finding the stores, looking through what companies decided to make, and keeping the good pieces visible after the checkout button is gone.

The scraper lets me do that across 42 stores without checking every page by hand.

When something new appears, I want people to be able to find it. When it disappears, I still want there to be a record of it.

That is what I am building at FoundMerch.com.