Segundista — Smarter Listings for Wallapop Sellers

active
Python FastAPI PostgreSQL Redis Celery HTMX Alpine.js Anthropic DeepInfra

Segundista

Segundista is a market-intelligence tool for second-hand sellers on Wallapop, Spain’s largest marketplace. Type the name of what you want to sell — say, “Lenovo ThinkPad X270” — and Segundista pulls real active listings, analyzes price distributions and the titles that actually convert, and returns a tailored recommendation: a listing title, a price tier (rapid sale / balanced / premium), and the city to post in.

The pitch line: “Dime qué vendes. Te decimos el precio justo y el título que convierte — en 10 segundos.”

Why this exists

Wallapop is full of casual sellers pricing by feel. The good listings — clear titles, sensible photos, condition stated up front, prices that match the market — sell quickly. The bad ones sit. Segundista does the boring market-research bit so the seller can focus on actually moving the item.

It’s also a fun problem: scraping the market, modelling price distributions by condition, and using an LLM as a transient analysis tool without persisting any of the scraped content (which keeps it on the right side of copyright).

How it works

  1. Scrape — a custom async scraper (httpx + tenacity) hits the Wallapop search API for the user’s keyword and pulls live listings.
  2. Bucket by condition — listings are grouped by the four standard Wallapop condition labels (nuevo, como_nuevo, buen_estado, usado). Pricing recommendations come from these buckets, not raw averages.
  3. Analyze titles + descriptions — the LLM (Gemma via DeepInfra for cheap pattern extraction; Claude for the hard cases) reads the listings in memory and reports back what the converting titles have in common: keywords, length, what details sellers emphasize.
  4. Recommend — the user gets three suggested prices (one per tier), a converting title, a draft description tuned to their answers, and a recommended city based on where similar items move fastest.
  5. Track — Celery beat takes periodic snapshots so we can show price history per keyword over time.

Stack

Backend — FastAPI 0.115 on Python 3.12, fully async. SQLAlchemy 2.0 + asyncpg against PostgreSQL 16. Redis 7 for cache + Celery broker. Celery 5.4 with beat scheduler for the periodic market updates.

Frontend — server-rendered Jinja2 + HTMX + Alpine.js + Tailwind. Chart.js for the price distributions. No SPA, no bundler, no Node — fast to ship, easy to deploy.

Auth — fastapi-users with Google OAuth.

LLM layer — Anthropic SDK for Claude on the harder questions; DeepInfra (Gemma) for the high-volume cheap stuff. The boundary between them was tuned by cost-per-analysis, not capability.

Observability — Sentry + structlog for JSON-formatted logs.

Infrastructure — Docker Compose, deployed via Coolify behind Traefik on a Hetzner VPS. Let’s Encrypt for TLS.

Things I’m proud of

Vendored vendor JS. Everything in /static/vendor/ is committed into the repo. No CDN. Tighter Content Security Policy, better load time, survives third-party outages. A small choice with outsized payoff.

Redis-backed global rate limiter. 120 requests/min burst, 30/sec sustained, per IP. Implemented at the application layer so it counts even when the request hits the cache.

Condition-aware pricing. A “nuevo” iPhone 12 doesn’t share a price distribution with a “usado” one. The recommendation engine respects that — it doesn’t average across conditions.

LLM as a transient tool. None of the scraped descriptions get persisted. The LLM sees them only during a single analysis pass, returns its summary, and the source data is discarded. Solves the legal question by design rather than hoping nobody asks.

Status

Open beta at segundista.com. Built on top of an earlier prototype called Skaut, fully rebranded in April 2026. Codebase is private (ignaciold/segundista) but the deployment infrastructure and patterns are reusable.

Roadmap: more marketplaces (Vinted, eBay-ES), better cross-platform price comparison, and richer historical charts.