Point your phone at a trading card and know what it's worth in under three seconds — without telling the app which game you're holding. CardScan is on TestFlight, scanning Pokémon and Magic on a physical device.
The problem
Every time a collector pulls a card from a binder, the same ritual: open eBay, type the name, squint at sold listings, try to work out whether their copy is the $4 one or the $40 one.
The existing apps don't really solve it. They're locked to one game, too slow, or built for professional graders.
What it does
CardScan reads a card with the camera, identifies it, and shows real market pricing across Pokémon and Magic. Cards save to a collection that tracks portfolio value over time. When the camera can't read a card cleanly, it falls back to manual search. Recognition works offline; only pricing needs the network.
The part I'm happiest with: you never pick a game. It works that out itself.
The interesting problems
Reading text off a physical card is harder than it sounds
Cards are held portrait in front of a portrait phone, but the text recognition treats them as landscape — so every coordinate comes back rotated 90 degrees. The top of the card isn't the smallest top value, it's the smallest left value. That only became obvious from testing with real cards in hand, never from the documentation.
Once I had it, I could reliably pull the name from the top third and the collector number from the bottom quarter, which is enough to uniquely identify almost any card across thousands of printings.
The best pricing data is behind a gate
I built a full pipeline for eBay sold listings — what people actually paid, not what sellers are asking. It works. But new eBay developer accounts hit an approval bottleneck that blocks access regardless of correct credentials.
Rather than wait, I shipped on TCGPlayer pricing, which comes bundled in the card data I was already fetching, and kept the eBay layer ready to switch on. The pricing is still real market transactions.
Keeping credentials off the device
The app holds no API keys. Every authenticated call goes through a small serverless proxy. It's a minor architecture decision that makes the app meaningfully more secure and gives me one place to add caching and rate limiting later.
What I'd do differently
I built the eBay pipeline first because it was the more interesting engineering problem. I should have shipped the simple pricing source on day one and added eBay as an enhancement — that would have separated "does the core app work" from "is the third-party account approved."
Designing first did work. Figma mockups for every screen before any code meant the implementation decisions happened at the right stage, and coding stayed focused on the details rather than on what the details should be.
