An MVP that only works in a demo isn’t an MVP; it’s a prototype with a user interface. What we build instead is small enough to ship fast and sturdy enough to run unattended every day, against real-world data that will try to break it.
JobFlow was built as a working product for a recruiting team collecting listings across eight job boards. The idea fit in one sentence: stop collecting job listings by hand. Turning that into something a recruiter opens every morning meant surviving layout changes, avoiding rate limits, and landing clean, de-duplicated data somewhere a non-technical person could actually use it.
.jpg)
Recruiters and job seekers collected listings from a dozen sites by hand. The data was stale the moment it was saved, and duplicated the moment two sites posted the same role.
JobFlow scrapes all eight sources on a schedule, catches duplicates before they land anywhere, and syncs clean records into Google Sheets automatically. It was built and tested at real volume from the first week, not as a proof of concept polished later.
.png)
A scraper that runs once and dumps a CSV is a weekend project. What makes JobFlow a product is everything that only matters once something depends on it daily: a changed selector on one site shouldn’t take down the whole pipeline, hitting LinkedIn too hard shouldn’t block the operation, and the same listing on two boards shouldn’t become two rows. n8n orchestrates the schedule and retries, the scraping is Python built per source, and new listings land in Google Sheets with a live dashboard showing what’s running, queued or synced.
Every run follows the same path: per-source scrapers collect listings, n8n paces and retries the requests, deduplication resolves repeats into one record, and clean rows sync to Google Sheets with a dashboard on top. Each stage can fail on its own without taking the others down.
Per-source Python scrapers, because a selector that works on Wellfound means nothing on Indeed.
n8n paces requests per source and retries failures, so one aggressive site doesn’t take the whole run down.
The same role posted on two boards resolves to one record, matched on company, title and location.
Clean records write to Google Sheets in real time; the dashboard shows what’s running, queued or synced.
Wellfound, Indeed and LinkedIn each get their own extraction logic rather than one generic scraper stretched across all of them.
A throttled source queues instead of failing the whole run, and shows as “Queued” on the dashboard rather than being silently dropped.
A role posted on both Wellfound and LinkedIn becomes one row, not two.
No batch export step. A new listing is in the sheet within the same run it was collected.
Tested against 14,000+ live listings before it became something a recruiter relied on daily.
When a source changes its markup, only that source’s scraper needs fixing. The other seven keep running.
The aim was clean listings in a sheet every morning, with nobody copying them. Here is how JobFlow differs from what came before it.

Cut everything that wasn’t “get clean listings into a sheet.” No login system, no user accounts, nothing the MVP didn’t need.
Started with Wellfound, made it reliable, then added each source rather than debugging eight things at once.
Ran sources hard enough in testing to trigger actual throttling, so the queueing behavior was proven before it mattered.
Matched on company, title and location after an early version matched on URL alone and missed obvious duplicates.
The pipeline worked headless first; the dashboard was built once there was real data worth looking at.
Each board broke in different ways. Writing down what broke and why meant the next source added didn’t repeat the same debugging.
.jpg)