Receipts & Failures
I didn't have a selling problem. I had a listing problem.
For a bit over a year I’ve run a small, deeply unglamorous eBay store. I buy sealed trading-card product — mostly imported anime cards, some vintage Pokémon, the odd doujin oddity — rip it, and resell the good singles. It works. It has always worked. It cleared about $20 a day, which for a hobby store I figured was just fine — and if I thought about the ceiling at all, I chalked it up to demand, or to it simply being a hobby.
It wasn’t demand. The store was fine. The bottleneck was me, standing at a desk, clicking through eBay’s dropdowns one listing at a time — and, worse, assuming that was simply how eBay worked.
That distinction is the whole post, so let me put it up front: the money in this store scales almost linearly with the number of listings I get live per day, and the number of listings I got live per day was capped by how much tedious data-entry I could stomach before I’d rather do literally anything else. The cards were sitting in boxes. The buyers were out there. The only thing between them was a form I hated filling out.
So I handed the form to an agent. Listings went from ~5 a day to 20–40 a day, and my take went from roughly ~$20/day to ~$100/day, over about three weeks. Here’s exactly how the work split — and, at the end, the actual skill file, cleaned up so you can point it at your own store.
The machine that already worked
Before any automation, the loop was completely manual and completely functional:
- Photograph a card.
- Figure out what it actually is — franchise, character, set, card number, rarity, whether it’s a licensed card or a doujin (fan-made) one.
- Research a price by digging through comparable sold and active listings.
- Write an 80-character title that front-loads whatever a buyer would actually search.
- Fill in the item specifics, pick a shipping option, set Best Offer, publish.
- Repeat.
Steps 2 and 3 are judgment. Steps 4, 5, and 6 are labor. And the labor is what set the ceiling — not because it’s hard, but because it’s soul-deadening, and a human doing soul-deadening work taps out at about five reps before quality slides. That five-a-day ceiling was the entire business, and I’d mistaken it for a market.
The one decision that made this work: labor vs. judgment
Here’s the call that everything else hangs on, and it’s the transferable part. Before I automated anything, I split the workflow into two piles:
- Labor — mechanical, rule-shaped, no taste required. Generating a title from known fields. Formatting a description. Assembling the upload file. Hosting the photos. Moving folders around. Remembering that eBay silently rejects a title over 80 characters.
- Judgment — where being wrong costs real money or gets your account in trouble. What a card actually is. What it’s worth. Whether a claim on the listing is true.
The agent gets the entire labor pile. I keep the entire judgment pile, behind a mandatory review gate. Not “the agent does it and I spot-check” — the agent is structurally not allowed to publish without me signing off on the judgment calls first.
That line is the difference between automation that compounds and automation that quietly wrecks your seller rating. The failure mode of a listing agent isn’t that it types slowly — it’s that it will confidently mislabel a card and price it wrong, at machine speed, all day. So I didn’t ask it to have taste. I asked it to do the typing and then stop and show me its work.
The build — and the duct-tape I’m weirdly proud of
Here’s the part that stings a little: I already owned the tool. For weeks I’d had an agent working on my other projects while I did eBay entirely by hand — because I’d quietly filed eBay under “not automatable.” Its listing flow is a wall of dropdowns, and I assumed clicking through them myself was just the cost of selling there.
The unlock was hiding in eBay’s own menus. You can bulk-upload listings from a CSV report — and a CSV is a file, which is exactly the kind of thing an agent is good at producing. Add one more piece — a public URL to host the photos, since eBay will pull listing images from anywhere — and the whole manual grind becomes something I can hand off. No special API required. (I’ve since applied for eBay’s proper listing API too; it’s still pending. Turns out I never needed it — the humble CSV export was the entire unlock.)
Here’s the pipeline:
- Intake (manual). I photograph cards and drop them into one folder per card. That’s my whole physical job now.
- Identify + comp + draft (agent). The agent reads the photos, identifies each card, does comp
research to ballpark a price, and writes a small structured
item.jsonper card — title, specifics, price, shipping, and aconfidenceflag plus anyopen_questionswhere it’s unsure. - Review gate (me, mandatory). The agent presents the batch as a table — card, publisher, character, price, shipping — and stops. I fix IDs, correct prices, answer its questions. Nothing proceeds until I say so. This is the judgment pile, and it takes minutes.
- Host the photos (agent). A script pushes each card’s images to a web server I already run for another project, so eBay has a public URL to fetch from.
- Generate the upload file (agent). A script turns the approved
item.jsonfiles into eBay’s bulk-listing CSV — with the hosted photo URLs, business policies, package dimensions, and Best Offer all filled in. - Upload (me, 30 seconds). I drop the CSV into Seller Hub. The listings go live immediately.
- File it (agent). Listed cards get moved to a
listed/archive and — bonus — pushed onto a companion website as browsable pages.
What it feels like now: I say “let’s do 20 for today,” walk away for ten minutes, and come back to a table of drafts. I fix whatever’s wrong, approve it, and upload one file. The chore that used to eat an afternoon is a coffee break — and it flows straight through to a companion site, where every card I list also becomes a browsable product page. None of it needed the integration I thought I was missing, which is the lesson that outlives eBay: the API you’re blocked on is rarely the thing actually blocking you. Look for the boring export button first.
The receipts
I won’t just tell you it worked — here’s the same dashboard eBay shows me, for the 30 days that span the switch. Look at the first week of June, then watch what happens mid-month:

Those bars are mostly eBay’s promoted-listing impressions, and that’s the honest mechanism, not a trick: more live listings means more inventory for eBay to promote and more organic surface area, so impressions, views, and sales all inflect on the same week. The metric I actually care about is the last one —

And it shows up in the bank, not just the dashboard:

The numbers behind the shape:
- Listings/day: ~5–6 during the manual ramp, then a steady 20/day once the photo-hosting and live-CSV steps were automated, with frequent 40/day double-batches. That ~5 → 20–40 jump is the lever; everything in those charts is what it moved.
- Take: the audited receipt is right there in the report above — June net sales up 191% over May. In daily terms that’s the difference between ~$20 in sales on a hand-listed day and north of $100 on a day the system’s fully engaged.
- Timeline: the switch landed mid-June 2026 — May was 100% by hand, which is exactly what makes that month-over-month a clean before/after (and an understated one, since June was only half-automated).
- Backlog: thousands of cards still to list. The ceiling now is how fast I can photograph, which is a much better problem to have than the one I started with.
I want to be precise about the shape of this win, because the grift version of this story would round it up and imply it’s passive. It isn’t. I still shoot every photo and I still personally approve every batch. What changed is that the part that scaled with money stopped being the part that scaled with my patience.
And here’s the strategic read the charts hand you, if you sell on eBay at all: quantity and consistency are the game, and eBay rewards them out of all proportion. I went from ~5 listings a day to 20–40 — and the traffic didn’t inch up to match, it more than doubled (impressions +134%) while sales nearly tripled (+189%). Fresh, growing inventory is apparently catnip to the algorithm. The best part is how boring and honest the win is: I’m not surfacing my rarest cards or nudging prices up — as the report above shows, my average sale price actually slipped 4.7% while total sales rose 178%. I’m winning on sheer volume of ordinary singles. The edge isn’t what I list — it’s how much, consistently.
War stories (the part nobody screenshots)
Automation is a stack of small, stupid, specific failures you only find in production. A few real ones, kept in the skill file so I never rediscover them:
- The invisible-photos bug. New listings went up with broken images. The photo-sync script copied
files with the private
0700permissions of its temp staging folder, so the web server’s user couldn’t read them and every image 404’d. One--chmod=D755,F644and they appeared. Nothing about the listing was wrong; the files were just locked. - The certificate mismatch. eBay silently refused photos served from the bare domain because its
TLS cert only covered the
wwwhost. Fix: always hand eBay thewwwURL. You will not get a useful error for this; you’ll just get no image. - eBay hotlinks your server first. I assumed eBay copied images to its own CDN on upload. It does — but not instantly. For the first few minutes-to-hours, a fresh listing hotlinks your server directly, and only later flips to eBay’s fast CDN URL. Which means: don’t let a routine site rebuild wipe that photo folder for a day or two, or brand-new listings go imageless until eBay catches up.
- The agent wanted to oversell. This is the important one. Left to its instincts, the agent would happily write “official,” “holo,” “1st edition,” “shadowless” — the high-value magic words — because those words correlate with high prices in its training data. On a fan-made doujin card, “official” isn’t a typo, it’s a trademark complaint waiting to happen. On a vintage Pokémon card, claiming a variant the photo doesn’t actually prove is how you eat a return and a defect. So the rule in the skill is blunt: only claim what the photo proves, never say “official” on doujin, and verify a vintage card from its set symbol, not its folder name. This is the judgment pile earning its keep. An agent optimizing for a good-looking title will absolutely write checks your account can’t cash.
- “Generating the file isn’t listing.” Early on a card got filed as sold-and-done the moment the upload file was generated — before it was actually live — and had to be walked back. Now the archive step only runs after I confirm the listings really posted. A tiny state-machine bug with real consequences: the system briefly believed it had done something it hadn’t.
None of these are exotic. That’s the point. This is what “I automated it” actually looks like up close: a permissions flag, a hostname, an ingestion lag, and a firm rule that the confident intern doesn’t get to make claims the camera can’t back up.
The artifact: the skill file
Here’s where “field guide” stops being a metaphor. The reason this runs the same way every day — including remembering every one of those war stories — is that it’s written down as a Claude Code skill: a plain-language procedure the agent loads when I say “list today’s cards.” The mandatory review gate, the title rules, the don’t-overclaim law, the exact photo-hosting fix — all of it lives in one file so neither of us has to re-derive it.
I’ve stripped mine down to a generic version — no store name, no server, no private details — so you can drop it into your own eBay workflow and adapt it. It encodes the split this whole post is about: the agent does intake, identification, comp research, file generation, and hosting; you own the review gate and every judgment call.
→ Download the skill file (plain Markdown; drop it in
.claude/skills/list-cards/SKILL.md).
The skeleton, so you can see the shape without downloading:
# Daily card-listing workflow
The agent does the labor; you own the judgment. It never publishes without your sign-off.
## 1. Identify each card (agent)
Read the photos. Identify franchise, character, maker, set, card number, rarity, serial.
Do a quick comp search for anything you can't ballpark. When confidence is below high,
ASK a targeted question — never guess silently.
## 2. Draft one item.json per card (agent)
Fields: identification{...}, listing{title, condition, description, item_specifics,
price_usd, price_confidence, shipping}, photos[], open_questions[].
Rules:
- Title <= 80 chars (eBay SILENTLY drops longer rows — check the skipped-rows output).
- Only claim what the photo proves. Never say "official" on fan-made/doujin items.
- Verify vintage cards from the set symbol + copyright line, not the folder name.
## 3. Review gate (HUMAN — mandatory, every time)
Present the batch as a table: # | Card | Publisher | Character | Price | Shipping.
Then STOP. Wait for corrections and go-ahead before generating anything.
## 4. Host photos + generate the upload CSV (agent)
Push images to a public URL (force world-readable perms, use the cert-valid host).
Generate eBay's bulk CSV with hosted photo URLs, policies, and Best Offer filled in.
## 5. Upload, then file (human uploads; agent files)
Human uploads the CSV in Seller Hub. ONLY after listings are confirmed live does the
agent archive the cards. Generating the file is NOT listing.
## Gotchas baked in
- Photo perms: force D755,F644 or images 404.
- Use the www (cert-valid) host for photo URLs, not the bare domain.
- eBay hotlinks your server before its CDN ingests — keep photos up a day or two.
That’s the memoir welded to the field guide: the story of why each rule exists, plus the rule itself, in a form you can actually run.
The part I didn’t expect: the floor moved too
When listing a card cost me real time and real willpower, a card had to be worth a fair bit before it earned a slot in my day. Cheap singles, oddball cards, the stuff at the bottom of the box — not worth the dropdowns. I’d have tossed them.
Now that listing a card costs me almost nothing, that math inverts. A single that clears three dollars is pure upside when the labor to list it rounds to zero. So I’m back in boxes I’d written off, listing cards I would genuinely have thrown away a month ago. Automation didn’t just make the same work faster — it lowered the bar for what counts as worth doing at all. The ceiling went up and the floor came down, and the gap between them turns out to be a lot of cards.
The takeaway
I didn’t grow this store by being smarter about cards. I grew it by noticing that the thing I’d been calling a business problem was actually a data-entry problem, and data entry is the single most automatable thing there is. The agent does the thousand boring reps; I keep my hand on the two levers — what a card is, and what’s true about it — where being wrong actually costs me.
If some corner of your own work is capped by how much tedium you can personally absorb before quitting for the day, that cap is probably not a law of your market. It’s a form you hate filling out. Hand it to the intern. Keep the gate.