Inspiration

Selling something second hand is not hard. It is tedious, which is worse. Photograph it, work out what condition it is honestly in, research what similar things are going for, then write the description again for every marketplace because each wants a different shape.

So the thing sits in the cupboard. Not because nobody wants it, but because listing it takes more effort than it feels worth.

What it does

Snap one to eight photos of a thing you want to sell. Flotsam gives you back a listing:

  • a title, in a field that holds 65 characters
  • on Pro, a condition grade (New, Like new, Good or Fair) with the evidence it based that on
  • a low and high price estimate, with sliders to adjust
  • the copy formatted on a tab each for a generic classified (free), and for Facebook Marketplace, Kijiji and Poshmark (Pro)

You copy it and paste it yourself. The one exception is eBay: connect your own eBay account and Flotsam can post the listing for you when you tell it to. Nothing is posted anywhere unless you tell it to.

A Decluttering Shelf tracks what is listed, what sold, and how much you have actually recovered.

A quick note on the tiers. The free tier reads the text on the item right on the phone. It builds a title from the line you type or, if you leave that blank, from a phrase it reads off the item, and it picks out a brand it recognises. It then looks up a price range from similar active eBay listings, and only the item name goes out for that. It does not grade condition from the photo: the screen says Not assessed and no condition is returned. Pro adds AI vision, which looks at the photos themselves and produces the condition grade with its evidence, a fuller description and its own price range. Pro also unlocks the Facebook Marketplace, Kijiji and Poshmark formats and removes ads.

How we built it

React Native and Expo SDK 56 with Expo Router, and a design system of dynamic theme tokens. State is Zustand, persisted locally through AsyncStorage. The shelf is stored on the device and there is no user profile.

The vision call goes to a Cloudflare Worker that holds the model key, so no model key ships in the app. RevenueCat carries the Pro subscription, behind our own paywall screen. AdMob shows ads on the free tier only, and only after the consent step: an interstitial after a saved listing (at most two per session) and an app open ad when someone returns to the app (never on a fresh launch, and spaced out from other full screen ads). Subscribers see neither, and there is no rewarded ad path at all.

Challenges we ran into

Photo budget arithmetic. Good vision quality from several photos fights a payload limit, and the limit is counted in base64 characters rather than decoded bytes, which is about a third bigger than the number you would guess from the file size. Oversized first images and combined overages are rejected before the call rather than after it fails.

Proving the debug bypass was gone. A development helper could simulate Pro status. It was deleted from the source, and the production Hermes bundle was then checked for its exact name. A first version of the automated check was too loose and matched ordinary minified names, so it was narrowed to the exact identifier. The check was also tested by planting the string on purpose, to prove it fails when it should.

Accomplishments that we are proud of

The production build does not request the microphone, audio settings or draw over other apps permissions. That was checked against the manifest packaged inside the release bundle, not only the config file.

What we learned

Writing a vision prompt that produces a condition grade you would be willing to put your name to is harder than writing one that produces a paragraph that merely sounds plausible. The second is easy and useless.

What is next for Flotsam

  • Queue several items in one decluttering session
  • Background removal for clean product cards
  • Optional deep links into the upload flows of the marketplaces we do not post to directly (eBay posting is already built)

Built With

Share this project:

Updates

Submission history