How I went from spending 10 minutes per listing, to running Selenium bots across 6 remote PCs, to reverse engineering a private API and building extraction systems that nobody else has built — all because Wallapop doesn't have a public API.
A note on scope. Everything here was built to run my own business: the seller accounts, the inventory and the order data are all mine. These are internal operations tools that manage my own listings and orders — with conservative, rate-limited, human-paced requests — because the platform exposes no public API for sellers. It's infrastructure for a business I operate, not tooling pointed at anyone else.
Chapter 1: The Manual Hell
Wallapop is Spain's largest second-hand marketplace. Millions of users. Billions in transaction volume. And in 2023, they had no way to publish listings in bulk.
Every single listing had to be created manually through their web interface. Upload photos. Write a title. Write a description. Set a price. Choose a category. Set the location. Click publish. 5 to 10 minutes per item.
When you're running an e-commerce business selling Amazon liquidation, you might have 500-600 items in your catalog at any given time. Do the math: 600 items × 7 minutes = 70 hours of manual work just to list everything once. And you need to re-publish every few days to stay visible in search results.
That's not a business model. That's a data entry job.
Chapter 2: The Selenium Bot
So I built a bot. A Selenium-based browser automation system that could navigate Wallapop's web interface, fill in all the fields, upload images, and publish — automatically.
The architecture was straightforward but required solving several non-trivial problems:
- Dynamic XPaths — Wallapop's React frontend generates different DOM structures depending on the category, condition, and shipping options. I created a configurable
xpaths.jsonfile that mapped each field to its selector, so when Wallapop changed their UI (which happened regularly), I only had to update the config - Image randomization — Uploading the exact same product images across multiple accounts would trigger duplicate detection. I built an OpenCV pipeline that applied subtle transformations to each image: micro-rotation, noise injection, brightness variation, slight stretching. Enough to fool perceptual hashing, invisible to the human eye
- Anti-detection timing — A bot that fills forms in 0.5 seconds looks like a bot. I added randomized delays between actions (typing speed variation, pause before clicking, scroll behavior) to mimic human interaction. Each listing took about 1 minute — slower than a machine could go, but fast enough to be useful
Chapter 3: The 6-PC Farm
One minute per listing. 600 items. That's 10 hours on one machine. Still too slow, especially when you need to re-publish every 3 days for SEO positioning.
My solution was brute force: I set up 5-6 PCs, connected to all of them remotely via AnyDesk, and ran multiple instances of the bot simultaneously on each machine. Each PC had its own Wallapop account, its own browser profile, its own IP (different networks).
The workflow looked like this:
Me (AnyDesk) ──→ PC 1 (Office): 2 browser instances × Account A, B
──→ PC 2 (Warehouse): 2 browser instances × Account C, D
──→ PC 3 (Home): 2 browser instances × Account E, F
──→ PC 4 (Employee 1): 1 browser instance × Account G
──→ PC 5 (Employee 2): 1 browser instance × Account H
──→ PC 6 (Laptop): 1 browser instance × Account I
Result: ~600 listings published in ~1 hour
Frequency: Every 3 days (re-publish for positioning)
Was this elegant? Absolutely not. Was it effective? It let me operate at a scale that would have been impossible manually. While competitors were spending their entire day posting items one by one, I had my full catalog live across multiple accounts in an hour.
Chapter 4: The Pivot — From Publishing to Operations
As the business grew, external tools like PortalHero appeared that could handle bulk publishing. I delegated that part entirely. But a new, bigger problem emerged: order management.
When you have 10 orders a day from one account, you manage them manually from the Wallapop app. Open the app, check for new orders, write down the item code, go to the warehouse, find it, pack it, print the label, ship it. Fine.
But we were scaling. Fast. We went from 10 orders/day to nearly 100 orders/day across 12+ accounts. Each account had its own inbox, its own orders, its own shipping labels. My warehouse team needed a unified view of all pending orders. I needed analytics on which accounts performed best. I needed to track which items had been sold, which were pending shipment, which were returned.
Wallapop's web interface doesn't give you any of this. No exports. No API. No bulk operations. Just a mobile-first app designed for individuals selling their old shoes.
I needed data. And Wallapop wasn't going to give it to me.
Chapter 5: Opening the Hood
I opened Chrome DevTools on the Wallapop web app and started watching the Network tab.
Every click, every page load, every scroll — the browser was making HTTP requests to api.wallapop.com. And the responses were clean, structured JSON. The endpoints followed patterns. The authentication was a bearer token in the header. The pagination was cursor-based.
I started mapping everything:
/bff/delivery/orders/ongoing— all active orders for an account/bff/delivery/orders/{id}— order details including shipping label URLs/bff/messaging/inbox— all conversations (useful for validation AND analytics)/bff/sales/as_seller— completed sales history/api/v3/user/items— all published listings with stats
I spent days exploring. Every request, every response, every header. I'd change parameters, see what happened. I'd try calling endpoints with different authentication tokens. I'd trace the flow of a complete order lifecycle: creation → acceptance → shipment → delivery → completion.
And I found gold. Not just the obvious endpoints, but undocumented ones. Bundle order details. Wallet transactions. Account-level statistics. Shipping label download URLs. Chat message history with timestamps.
Nobody had published any of this. There was no Wallapop API documentation anywhere on the internet. I was building this map from scratch.
Chapter 6: Building the Extractors
With the API mapped, I started building extraction systems. Not quick scripts — production-grade data pipelines that would run every 15 minutes, 24/7, across all 12+ accounts.
The Orders Extractor (2,100 lines)
This is the core of my business operations. It extracts every order across all accounts and persists them in PostgreSQL with full state tracking:
- 20+ order states — pending, accepted, shipped, in_transit, delivered, completed, cancelled, returned, disputed... each with different data available and different actions required
- Bundle detection — Wallapop bundles (multi-item orders) have a completely different API response structure. The extractor detects these, decomposes them into individual items, and extracts the LPN code from each product description using regex
- Sale creation — When an order reaches "completed", automatically creates a sale record with: item price, platform fee, net revenue, payment date, buyer info
- Return tracking — Detects returns and creates withdrawal records that update inventory status
This single extractor replaced what would have been 2-3 full-time employees manually checking 12 Wallapop accounts every hour.
The Chats Extractor
Every conversation with every potential buyer, extracted and stored. This gives me something Wallapop never provides: sales funnel analytics.
- How many conversations per day?
- What's the conversation-to-sale conversion rate?
- Which accounts generate the most engagement?
- What times of day do buyers message most?
- Average response time per account (are my employees responding fast enough?)
None of this data exists in Wallapop's interface. I built it.
The Listings Extractor
Tracks every published item across all accounts: views, favorites, conversations, price, status. This reveals which products perform well and which are invisible.
A key engineering challenge was anti-oscillation for product IDs. When Wallapop's systems re-index a listing, the product_id can change temporarily. Naive tracking would create duplicate records. I built detection logic that recognizes these oscillations and maintains consistent tracking.
The Evolution: V1 → V3
The extractors went through 5 major versions as the business scaled and I learned more about the API:
V1 (2023)
└─ Hardcoded bearer tokens in JSON files
└─ Single account, sequential processing
└─ Manual token refresh every few hours
V2 (2023)
└─ Bearers stored in Google Sheets (shared across scripts)
└─ Multi-account with user_hash tracking
└─ Tkinter UI for employees to paste new bearers
└─ Validation before each extraction run
V2.5 (2024)
└─ Cookie-based auth (no more manual bearer management)
└─ Automatic accessToken refresh via session cookies
└─ JWT decoding for expiration checking
└─ Accounts stay authenticated for weeks
V2.6 (2024)
└─ ThreadPoolExecutor for parallel multi-account extraction
└─ Each account gets its own thread and rate limiting
└─ 12 accounts extracted in parallel instead of sequential
V3 (2024-2025)
└─ Bundle order support (multi-item orders)
└─ LPN extraction from descriptions via regex
└─ Warehouse location enrichment
└─ Cross-reference with preparation Excel from Drive
└─ ~2,100 lines for orders alone
Anti-Detection at Scale
Making thousands of API calls per day across 12+ accounts requires serious anti-detection work. Get caught, and accounts get banned — which means lost inventory, lost sales, lost revenue.
- User-Agent rotation — Pool of 50+ real browser UAs stored in PostgreSQL, rotated per session
- Request timing — Randomized delays between requests. Not
sleep(1)— butsleep(random.uniform(0.8, 2.3)). Fixed intervals are a detection signal - Header fingerprinting — Exact replication of browser request headers including order, casing, and optional headers. A request from Python's
requestslibrary looks different from Chrome unless you match every header - Session consistency — Same UA, same cookies, same header set for the duration of a session. Switching mid-session is suspicious
- Image perturbation (for the Selenium publisher) — OpenCV transformations: Gaussian noise, micro-rotation (0.1-0.5°), brightness variation (±3%), slight stretch. Defeats perceptual hashing while being invisible to humans
The Duplicate Wars
When you operate 12+ accounts on the same marketplace, you inevitably run into duplicate listing detection. Wallapop's systems flag listings that appear identical across accounts and can shadow-ban or delete them.
I built a complete anti-duplicate investigation and mitigation suite:
- Shadow listing detection — Scripts that check if listings are actually visible in search results (a listing can exist in your profile but be invisible to buyers)
- Wallapop deletion email parser — Parses MBOX files from Gmail to identify which listings were removed and why
- Policy sanitizer — Scans listing titles and descriptions for "trap words" that trigger automated removal (certain product categories, restricted terms)
- Title de-duplication — Ensures no two accounts have listings with identical titles, using generated variations
This was a constant arms race. Wallapop would update their detection, I'd investigate the new patterns, build countermeasures, and adapt. 15+ scripts dedicated entirely to this problem.
What This System Enables
Today, my extractors run automatically every 15 minutes via APScheduler. The data flows into PostgreSQL, where Retool dashboards give my team real-time visibility into:
- All pending orders across all accounts in one unified view
- Sales analytics — revenue per account, per day, per product category
- Chat response times — are employees responding within our SLA?
- Listing performance — views, favorites, conversation rate per item
- Wallet reconciliation — does the money in Wallapop's wallet match our sale records?
This system is unique. Nobody else has built this level of automation for Wallapop. There are companies with hundreds of listings that manage everything manually because "there's no API." I proved that there is — you just have to find it yourself.
The Full Arc
2023 Q1: Publishing manually → 10 min/item, max 50 items/day
2023 Q2: Selenium bot → 1 min/item, 1 machine
2023 Q3: 6-PC farm via AnyDesk → 600 items/hour across 12 accounts
2023 Q4: Delegated publishing → Focus shifted to operations
2024 Q1: First API reverse engineering → Manual bearer tokens, 1 account
2024 Q2: Multi-account extractors → Bearers in Sheets, UI for team
2024 Q3: Cookie-based auth → No more manual token management
2024 Q4: Parallel extraction → 12 accounts in <5 minutes
2025: Bundles + full ERP integration → 2,100-line orders extractor
Anti-duplicate suite → 15+ investigation scripts
Production scheduler → Automatic every 15 minutes
From 10 minutes per listing to a fully automated, multi-account, anti-detection extraction system running 24/7. Not by reading documentation — by reading network packets.
The extractors are open-source: github.com/AspiranteD/wallapop-data-extractors