Why We Built Caught
A spreadsheet at a busy card show wasn't cutting it, so my partner and I built the app we wanted at the table.
It started at the table
A while back I started vending Pokémon cards at shows on the weekends. If you've never done it, a card show is organized chaos: a line of people at your table, someone asking what you'd give for their binder, someone else holding up a card from your case asking for a price, and you trying to keep track of all of it at once.
I started out tracking everything in a spreadsheet. That works fine at home on a Tuesday night. It does not work on a Saturday with five people at your table. Things got missed. A sale wouldn't get logged, a trade would only get half written down, and by the end of the day my inventory and my numbers didn't match what actually happened.
The three problems
After a few shows the pain points were obvious:
- Tracking breaks down when it gets busy. A spreadsheet needs you to stop and type. At a show you never get to stop, so things slip through.
- Pricing every card is a chore. Each card meant opening a price guide, searching for it, finding the right printing and condition, and doing the math. Multiply that by every card in a trade and it adds up fast.
- Trade math happens in your head. Dealers usually offer a percentage of market value in trade. Doing that math on the fly, for a stack of cards, while someone is waiting, is how mistakes happen.
None of the apps I tried handled the whole thing. Price-lookup apps tell you what a card is worth but don't run the deal. Generic point-of-sale apps run a sale but know nothing about cards or trades. So my partner and I decided to build it ourselves.
What Caught does
Caught is a point-of-sale and inventory app for card dealers. The core idea is simple: everything that happens at the table should take a few taps and get recorded automatically.
Scan it, and the price follows
Instead of looking cards up by hand, you point your phone's camera at a card. Caught identifies it, you pick the condition, and it pulls the current market price. That's it. Sealed product works by scanning the retail barcode, and there are modes for graded slabs too.
Trades do the math for you
Trades used to cause the most mistakes, so this had to be automatic. You set your default trade percentage once, and Caught applies it to every trade.
Say I trade at 80% of market value, and someone brings me cards worth $1,000:
| Trade example | Value |
|---|---|
| Their cards (market value) | $1,000.00 |
| My trade percentage | 80% |
| Trade credit toward my cards | $800.00 |
They get $800 in credit toward the cards they want from my case, and both sides of the deal update live as cards get added. Buy offers work the same way with their own percentage, and you can control how each type of transaction rounds. Rounding buys down to whole dollars makes for clean offers at a show.
Everything gets saved
Every deal is saved to your history the moment you complete it, and your inventory updates with it. Caught records your profits and losses on sales and trades, so at the end of a show you know whether you actually made money, not just how much cash is in the box.
Inventory with live prices
Your inventory tracks real-time market prices, so your portfolio value stays current without you lifting a finger.
My two favorite features
Scan the label, pull up the card
Every item you print a price label for gets a QR code on its sticker. When someone wants to buy a card from your case, you scan the label and Caught pulls that exact item up, ready to sell. No searching, no typing, no guessing which copy it was. At a busy table that saves a lot of time, and the sale gets recorded against the right item every time.
The reprice queue
Card prices move fast. A card that was $40 last month can be $60 this week, or $25. Repricing a whole case by hand means looking up every card again, one at a time, and it takes forever, so most people just don't do it and end up underpricing or overpricing their stock.
The reprice queue does the tedious part for you. You set a threshold, and Caught shows you which cards have moved up or down by more than that percentage. You can sort by the biggest swings, then review the recent sales for each card to decide on a new sticker price. Once you've set it, you print the new label and you're done. What used to take a whole evening now takes a few minutes before a show.
The extras that came from real shows
A lot of features exist because we hit the problem ourselves at a table:
- Events: start a show, track it, and compare shows side by side to see which ones are worth going back to.
- Binders: separate your inventory from your personal collection.
- Pricing queue: cards that still need a price collect in one place so you can knock them out in one pass.
- Bluetooth label printing: print price stickers straight from your phone to a small thermal printer.
Building it with my partner
My partner and I built Caught together from start to finish. A lot of the feature ideas came from me, because I was the one standing at the table running into the problems. I tested and debugged builds on real devices, helped with development, and handled marketing and customer support. My partner did most of the security work. Between the two of us, our hands were in just about every part of the project. We also had help from another friend who pitched in on a few parts along the way, and we're grateful for it.
We ran a beta through TestFlight for about six months with real testers before going live. That beta was where the app got good. Testers used it at real shows and told us what broke and what was missing, and a lot of the app today came straight from that feedback.
How it's built
For the tech-minded, here's what's under the hood:
- Mobile app: React Native with Expo, written in TypeScript, for a single codebase across iPhone and Android.
- On-device data: a local SQLite database (via Drizzle ORM), so your inventory and deal history live on your phone.
- Backend: a FastAPI service with a PostgreSQL database, containerized with Docker.
- Subscriptions: RevenueCat, for the Caught Pro plan on both stores.
- CI/CD: GitLab CI runs type checks and the test suite on every change, builds a test version we install on a real phone before merging, and ships tagged releases to TestFlight and Google Play automatically.
A couple of numbers from the project: since development started in April 2026 we've made 876 commits and cut 74 tagged releases, backed by 187 test files.
One design rule worth calling out: rounding is display-only. Caught always stores the exact calculated value and only rounds what you see on screen. That way your profit and loss math stays accurate even when your offers are rounded to clean numbers.
The label printer was its own adventure. Getting an inexpensive Bluetooth thermal printer to print a batch of labels reliably meant digging into how it communicates. We ended up rendering each label as an image and checking the printer's status between labels, instead of firing them all at once and hoping.
What I learned
- Build for the real conditions. A show is loud, fast and distracting. Every screen had to work with one hand while talking to a customer.
- Test where it's actually used. Testing on real phones at real shows caught problems that never showed up at a desk.
- Ship small and often. Automating the release pipeline meant we could put a fix in testers' hands quickly, which kept the feedback loop tight.
- Your own frustration is a good product spec. The best features came from things that annoyed me at my own table.
Try it
Caught is free to use for inventory, deals and pricing, with a monthly scan allowance. Caught Pro adds unlimited scanning, label printing, the reprice queue, analytics and CSV export.
If you vend at shows, run a shop, or just trade on the side, give it a try at your next show. We built it from dealer feedback, so if something's missing, tell us.