One engineer. A full custom platform. 12 marketplace accounts. ~100 orders/day. 5 employees using it daily. This is the complete technical story of how I designed, built, and operated the entire production platform behind REUSALIA — from the first Selenium bot to a full ERP with reverse-engineered APIs, AI pipelines, and physical hardware integration.
The Problem: Running a Real Business on Manual Processes
In April 2023, I founded REUSALIA — an e-commerce company that buys Amazon liquidation pallets, processes the inventory, and resells individual items across multiple marketplaces (Wallapop, eBay, PortalHero). The business model is simple. The operations behind it are not.
Every pallet that arrives contains 50-200 mixed items. Each item needs to be inspected, photographed, categorized, priced, listed on multiple platforms, tracked through sales, packaged, and shipped. Multiply that by thousands of SKUs across 12 marketplace accounts, and you start to see the scale of the problem.
When I started, everything was manual. Listing a single item on Wallapop took 5-10 minutes of typing. Orders came in through multiple accounts and had to be checked one by one. Inventory was tracked in Google Sheets. There was no system — just a person with a laptop and a warehouse.
Three years later, the entire operation runs on a platform I built from scratch: a FastAPI backend with 25+ database models, a custom Retool ERP with 10+ operational modules, reverse-engineered marketplace APIs, AI-powered product enrichment, and a custom hardware bridge that connects cloud interfaces to physical label printers. This is the story of how it evolved.
Phase 1: The Selenium Era (2023)
The first technical problem I solved was the most painful one: publishing listings on Wallapop.
Wallapop has no bulk publishing API. No CSV import. No way to list products at scale. Every listing had to be created manually through their web interface — fill in the title, description, category, price, upload photos, set location, confirm. At 5-10 minutes per item, listing a catalog of 500-600 items was a full-time job.
So I built a Selenium bot that automated the entire flow. It opened a browser, navigated to the listing form, filled in every field, uploaded images, and submitted. Each listing took about 1 minute (slowed down intentionally to avoid detection).
But 1 minute per item across 600 items is still 10 hours. And I needed to re-list every 3 days to maintain marketplace positioning. So I scaled the only way I could: horizontally, across physical machines.
I set up 5-6 PCs, connected to each one remotely via AnyDesk, and launched multiple bot instances per machine. Each instance used different cookies and user agents. This way, I could publish my entire catalog in about an hour. Every 3 days, I'd spend an hour managing the distributed bot fleet.
It was ugly. It was fragile. It worked.
What I Learned
- Automation doesn't start with elegance — it starts with pain reduction
- Sometimes "scale" means 6 laptops on a desk, not Kubernetes
- Anti-detection matters from day one: user agent rotation, timing randomization, session isolation
Phase 2: Reverse Engineering Wallapop's Private API (2023-2024)
As the business grew, so did the operational complexity. We went from 10 orders a day to nearly 100. From 1 Wallapop account to 12. The Selenium approach couldn't scale anymore — not for publishing, and definitely not for order management.
The problem was that Wallapop is a closed ecosystem. No public API. No documentation. No third-party integrations. Everything happens inside their app and website. For most people, that's a wall. For me, it was an invitation.
I started intercepting network traffic. Every action I performed on the website — browsing listings, checking orders, reading chats — I captured the HTTP request, studied the headers, decoded the payloads, and mapped the response structures.
The Discovery Process
Reverse engineering a private API is detective work:
- Capture — Use browser DevTools to intercept every request during a session
- Classify — Group requests by endpoint pattern and HTTP method
- Decode — Analyze request headers (especially authorization), query parameters, and response JSON structures
- Cross-reference — Compare responses from different accounts to identify what's user-specific vs. universal
- Replicate — Build a Python client that can authenticate and make the same requests outside the browser
- Iterate — When Wallapop changes their API (which they do), update the client
Over 5 major versions of the extractor codebase, I mapped their authentication system (cookie-based with bearer tokens), their order management endpoints, their chat API, and their listing metadata system. The result: 2,100+ lines of production Python code that can:
- Orders Extractor — Pull all orders across 12 accounts, normalize the data, and feed it into our ERP. This single script replaced what would have been ~5 hours of daily manual work
- Chat Extractor — Pull conversation data to analyze sales funnel metrics: response times, conversion rates, customer behavior patterns
- Listings Extractor — Monitor which items get the most views, which need repricing, which should be promoted
The multi-account architecture was the hardest part. Each account has its own authentication lifecycle: cookies expire, tokens need refreshing, sessions get invalidated. I built a centralized auth manager that stores credentials in PostgreSQL, automatically refreshes tokens across sessions, and provides clean authentication contexts to every extractor.
Nobody else has built this. There are tools like PortalHero for bulk publishing, but nothing for extraction. Our extractors are unique — and they're what makes it possible to run a 12-account operation with a team of 5 instead of a much larger manual operations team.
Phase 3: The Core Platform — FastAPI + PostgreSQL (2024-2025)
With the extractors feeding data reliably, I needed somewhere for that data to live and something to do with it. Google Sheets wasn't going to cut it anymore (that's a whole other story).
I designed the core platform around three principles:
- Single source of truth — Every piece of data lives in PostgreSQL. No spreadsheets, no local files, no "I'll update it later"
- API-first — Every operation goes through the FastAPI backend. The custom ERP frontend built on Retool, the extractors, the sync engines — all talk to the same API
- Operational automation — If a human does something more than twice, it should be automated
Database Design
The PostgreSQL schema has 25+ models with 35+ migrations, covering:
- Inventory — Items, SKUs, categories, conditions, locations, photos
- Orders — Multi-marketplace order tracking with status workflows
- Sales & Invoicing — Revenue tracking, cost analysis, margin calculations per item and per pallet
- Authentication — Centralized credential storage for all marketplace accounts
- Scheduling — Task queues for automated operations (sync cycles, extraction runs)
- Incidents — Customer complaints, returns, shipping issues
I use SQLModel (SQLAlchemy + Pydantic) for the ORM layer, which gives me type-safe models that work both for database operations and API serialization. Alembic handles migrations, and I've never had to roll one back in production.
API Architecture
The FastAPI backend exposes ~60 endpoints covering CRUD operations, business logic, and integrations. Key design decisions:
- Dependency injection for database sessions, authentication, and rate limiting
- Background tasks for heavy operations (bulk imports, sync cycles)
- Structured error handling with business-specific error codes
- Request/response models validated at the API boundary — if bad data gets in, it fails loud and early
Phase 4: The ERP — Retool Frontend (2025)
A database and API are useless if your team can't interact with them. I needed an interface that 6 non-technical employees could use daily — for everything from processing incoming pallets to shipping orders to tracking incidents.
I chose Retool because it let me build a complex, multi-module ERP frontend in weeks instead of months. The result: a custom ERP with 10+ operational modules:
- Orders Module — Real-time view of all orders across all marketplaces. Filter by status, account, date. One-click status transitions. Shipping label generation
- Inventory Module — Full item lifecycle: intake → categorization → listing → sold → shipped. Location tracking within the warehouse
- Invoicing Module — Auto-generated invoices from sales data. Monthly reporting. Margin analysis per pallet and per marketplace
- Incidents Module — Customer issue tracking with linked orders, resolution workflows, and historical patterns
- Chat Analytics — Wallapop conversation metrics: response times, conversion funnels, customer satisfaction signals
- Mobile Scanner — Barcode scanning for warehouse operations. Workers scan items to update locations, mark as shipped, or flag issues
The key challenge with Retool was making it feel native. Default Retool apps look like admin panels. I invested significant effort in custom CSS, conditional rendering, and UX flows that feel intuitive to warehouse workers who've never used enterprise software.
Phase 5: AI Product Enrichment Pipeline
One of the most time-consuming parts of the business is product listing creation. Each item needs:
- A marketplace-appropriate title
- Accurate category classification
- A detailed description that sells
- Competitive pricing based on market data
Writing these manually for thousands of SKUs is insane. At ~15 minutes per item, that's 40+ hours per week just on descriptions. So I built an AI pipeline:
- Amazon Scraper — Identifies products from our pallet inventory on Amazon.es, extracts titles, descriptions, features, images, and pricing. Anti-detection with UA rotation and request throttling to avoid blocks
- GPT Enrichment — Feeds scraped data into GPT-4 with structured prompts. The model categorizes items, generates marketplace-specific titles (Wallapop style is very different from eBay style), writes descriptions, and suggests pricing
- Image Pipeline — Downloads product images, applies anti-duplicate transforms (OpenCV) to avoid marketplace duplicate-image filters, resizes and compresses for optimal upload
- Listing Sync — Pushes enriched data to each marketplace with format-specific adaptations
The pipeline runs autonomously. I feed it a batch of new items, and hours later I have fully enriched listings ready for publication across all marketplaces. What used to take a full-time employee's entire week now runs in the background while we process the next pallet.
Phase 6: The Cloud-Local Bridge (The Hardest Problem)
Here's a problem nobody talks about in architecture blogs: how do you print a physical shipping label from a cloud UI?
Our custom ERP frontend runs on Retool Cloud. Our label printer is a Brother QL-700 connected via USB to a warehouse PC. There's no cloud-native path between the two. I needed to bridge the gap without requiring the warehouse team to switch between applications.
The solution is what I call the Command Bridge Pattern:
- The Retool UI writes a command record to PostgreSQL (e.g., "print label for order #1234")
- A local Python daemon on the warehouse PC polls for new commands every few seconds
- When it finds one, it acquires an exclusive database lock, processes the command (generates and prints the label), and marks it complete
- The Retool UI sees the status update and reflects it to the user
The tricky part is reliability. What if the local daemon crashes? What if two instances run simultaneously? I implemented:
- Heartbeat monitoring — The daemon writes a timestamp every cycle. If the heartbeat stops for ~60 seconds, the system flags it and can restart
- Exclusive locking — PostgreSQL advisory locks prevent duplicate command processing
- Automatic failover — If a command is claimed but not completed within the timeout window, it's released back to the queue
This pattern now handles not just label printing but any operation that requires local hardware interaction from a cloud interface.
Phase 7: Multi-Marketplace Sync
With inventory in PostgreSQL, listings enriched by AI, and orders flowing through the extractors, the final piece was keeping everything synchronized across marketplaces.
The sync engine maintains PostgreSQL as the single source of truth and pushes formatted data to each platform:
- Wallapop — Via the reverse-engineered API (custom format, character limits, category mapping)
- eBay — Via the official Feed API (OAuth2 auth, CSV batch uploads of 1,000+ items)
- PortalHero — Via their integration layer (marketplace-specific formatting)
When an item sells on one platform, the sync engine pulls it from the others within minutes. When I update a price in the ERP, it propagates everywhere. When new inventory arrives, listings go to all marketplaces simultaneously.
The Full Architecture
Zooming out, the complete system looks like this:
Data Sources Processing Layer Core Outputs
───────────── ──────────────── ──── ───────
Wallapop API ──┐ ┌──────────┐
eBay API ──────┤ FastAPI Backend │PostgreSQL│ Custom ERP Frontend
Amazon Scraper ┤──→ ( extractors ) ──→ │25+ models│──→ ( Retool ERP )
PortalHero ────┤ ThreadPoolExecutor │35+ migr. │ 10+ modules
Google Drive ──┘ OpenAI GPT-4 └──────────┘
│
Command Bridge Pattern
(excl. lock + heartbeat)
│
Local Hardware
(Brother QL-700 printer)
Every component talks to the same API. Every piece of data lives in the same database. Every operation is logged, tracked, and recoverable.
Scale & Impact
Here's what this system handles in production, daily:
| Metric | Value |
|---|---|
| Orders processed/day | ~100+ |
| Active marketplace accounts | 12 |
| Team members using ERP daily | 6 |
| Marketplaces synced | 3 (Wallapop, eBay, PortalHero) |
| Manual order processing replaced | ~5h/day |
| Manual listing creation replaced | ~40h/week |
| Marketplace APIs reverse-engineered | Wallapop, eBay |
| ERP modules (Retool) | 10+ |
| Database models | 25+ |
| Database migrations | 35+ |
| Extractor versions (Wallapop) | 5 major |
This is not a demo project. This is a production system that handles real inventory, real money, and real customer operations. Every day. Built and maintained by one engineer.
What I'd Do Differently
Three years of iteration teaches you a lot about your own mistakes:
- Start with the database, not the scripts. I built automation scripts first and the database later. This meant months of Google Sheets as an intermediary, which created data integrity issues that took weeks to clean up
- Invest in monitoring earlier. I added structured logging and health checks late. For too long, I relied on "if nobody complains, it's probably working"
- Don't build the UI during the migration. I built the custom ERP frontend on Retool in parallel with the Sheets→PostgreSQL migration. My team saw half-finished interfaces during the transition, which slowed adoption
- Document API reverse engineering as you go. When Wallapop changed their API, I sometimes had to re-discover endpoints because I hadn't documented the original mapping well enough
The Takeaway
Building a production ERP as a solo engineer while running the business it's designed to automate is a unique engineering challenge. You're simultaneously the architect, the developer, the DBA, the QA, the DevOps engineer, and the product manager — plus the CEO, the warehouse manager, and the customer support lead.
The technical work is the easy part. The hard part is:
- Designing systems that non-technical teammates can use without training
- Migrating production data without losing a single order or messing up inventory counts
- Maintaining 12 marketplace account sessions that can break at any time
- Recovering from a catastrophic flood that destroyed your warehouse and still coming back stronger
- Shipping features at 2 AM because tomorrow's pallet arrives at 8 AM and the team needs the new module
I wouldn't trade it for anything. This is what real engineering looks like — not perfect code, but code that solves real problems for real people, every single day.
The platform components are open-source: github.com/AspiranteD/AspiranteD