The slowest part of selling something online is not the selling. It's the form.

A seller with a car part in their hand already knows what it is. They know it came off a Passat, they know it works, they know roughly what it's worth. Everything after that — the title in English, the category, the part number typed off a sticker, the weight, the dimensions, the same title again in German — is transcription. It's the tax you pay for the sale, and it's where people quietly give up.

AI Smart Listing exists to do the transcription. You upload photos; the wizard opens on step two already filled in. I want to explain what actually happens in between, because "we added AI" is not an explanation of anything.

It's an extraction problem, not a writing problem

The obvious way to build this is to ask a model to write a listing. That's the wrong shape.

What we ask for instead is a filled-in form. The model gets up to three photos and a schema, and has to return exactly that structure — nothing else, no prose around it:

  • title in English, under 80 characters, brand and model first
  • title_de — the same title in German, because eBay.de is our largest channel
  • description as short HTML, not a marketing paragraph
  • brand, model, part_number
  • condition — one of five fixed values — plus a free-text note about visible wear
  • category_suggestion and a German search keyword (more on that below)
  • price_eur, weight_kg, and length / width / height in centimetres
  • key_features, and a confidence rating on the whole thing

Every one of those maps to a specific field in the listing wizard. Nothing comes back that we don't have a home for, and each field either arrives or comes back null. A model allowed to be vague will be vague; a model asked for part_number: string | null either read the sticker or it didn't.

The rule that took the most iterations was language. The title has to be strictly English, the German title strictly German, and the search keyword German — models are startlingly willing to blend the two if you don't insist.

The part number is the whole feature

If AI Smart Listing only did one thing, it should be this.

Buyers of used parts do not search "brake disc". They search a code — an OEM number, a manufacturer reference, the string stamped on the casting. Get that code into the title and the listing is findable. Miss it and the item is invisible, no matter how good the photos are.

So the prompt spends most of its instruction budget on it: read all text in the images — labels, stickers, barcodes, text engraved into the body — and extract anything that looks like a part, model or serial number. That's why the flow accepts three photos rather than one. Photo one is the item. Photos two and three are usually where the label is.

This is also the reason the whole feature is worth its API cost. A human typing a 13-character alphanumeric code off a greasy sticker gets it wrong often enough to matter. A vision model reading the same sticker at high detail does not get tired at listing number forty.

Why we ask for a German search phrase

eBay's category tree has thousands of branches, and picking the wrong one buries a listing. The naive approach is to ask the model for a category — but the model has never seen eBay's internal category IDs, so what comes back is a plausible-sounding guess.

We ask a different question. The model returns a specific German search phrase for the item — something like "Bremsscheibe Vorne Audi", not "car parts" — and that phrase goes into eBay's own category search. eBay tells us which category real listings like this one live in.

The division of labour is the point. The model does what only it can do: look at a photo and describe the object precisely, in the right language. The marketplace does what only it can do: map that description onto its own taxonomy. Asking either one to do the other's job produces confident nonsense.

Weight and dimensions, estimated on purpose

The model also estimates physical size and weight from category knowledge — a brake disc is 4–8 kg and roughly 30×30×5 cm, a jacket is half a kilo, a phone is 200 grams.

These are estimates, and we treat them as estimates: the number picks the smallest packaging preset that fits, and the seller can override it in one click. But it means the shipping quote appears on screen without anyone finding a tape measure, and an approximate shipping cost shown immediately is worth more than an exact one the seller never gets around to entering.

The seller is never overruled

Every field the AI fills gets a badge and a soft glow. Touch that field and the glow disappears — it's yours now.

That behaviour is deliberate. The failure mode of an automated form isn't a wrong value; it's a wrong value that looks like something the seller typed themselves. Two months later a buyer asks why the part number doesn't match and nobody can reconstruct where it came from. The glow makes the machine's contribution visible, and the moment a human touches it, it stops being the machine's.

Nothing is published on the seller's behalf, either. The wizard just opens at step two with the boxes filled. Review, correct, continue — the same four steps as always, minus the typing.

One analyzer, three front doors

You can start a listing from the web wizard, from the mobile app, or from the Telegram bot. All three call the same function, with the same prompt, the same model, the same access rules and the same cost logging.

That's an engineering decision I'd defend loudly. The tempting version is a copy per platform — the mobile one gets a tweak, someone improves the web prompt without touching the others, and six months later three surfaces of the same product behave differently and nobody can say why. There is one prompt in this codebase. When it improves, it improves everywhere at once.

The monthly free allowance is shared the same way, and for the same reason: two free analyses a month means two, not two per device.

One honest note about that counter: it increments before the analysis runs, so an analysis that fails still costs a use. We know. It's a product decision about who absorbs the cost of a failure, not an oversight — and if we change it, it changes deliberately.

Different job, different machine

Not everything with "AI" on it should be a frontier model.

The listing analysis goes to a large vision model, because understanding an unfamiliar object from a photo is exactly what those are good at. Each analysis costs us roughly a cent, and every call is logged with its token counts and its cost, so the feature's economics are a query rather than a guess.

Watermark and background removal is the opposite case. It runs an inpainting model on our own hardware, driven by a mask the seller paints over the area to clean. No per-image API cost, and — more importantly — an inpainting model only fills the region you masked. A generative model asked to "clean up" a photo will happily repaint a label and invent characters in a part number that never existed. On a marketplace where the part number is the product, a beautiful photo with a hallucinated code is worse than a photo with a watermark.

Picking the smaller, older, cheaper model there isn't a compromise. It's the correct answer to a different question.

What it doesn't do

The price estimate is a starting point, not an appraisal — the model can't know what your local market pays this month. The category suggestion is a strong hint, not a decision. The condition assessment sees what the photo shows, which is not the same as what you know about the item.

That's why every value lands in an editable field instead of going straight to eBay. The goal was never a listing created without a human. It was a listing where the human only does the part that needs judgment.

Two free analyses a month come with every account, so it costs nothing to see whether it reads your labels correctly. If it does, the AI Smart add-on lifts the limit. If it doesn't, I'd genuinely like to know which photo it failed on — that's how the prompt gets better.