Logistics Dispatch System
A regional 3PL with 400+ daily shipments ran dispatch through a spreadsheet, a call rota, and the judgement of three senior planners. We replaced the judgement with an engineered decision layer.
A mid-market Swiss investment firm sourced deals from Flatfox, Homegate, and ImmoScout24 — via inbox alerts and spreadsheets. We replaced the copy-paste layer with an orchestrated pipeline: intake, portal-specific extraction, structured normalisation, contact enrichment, and a single sheet the team could trust.
System view — not vague business talk.
Lead generation was email-native but ops-native to spreadsheets. Analysts triaged the same alert three different ways, re-opened every listing in-browser, and hand-copied fields into siloed tabs — with no deduplication, no audit trail, and no standard contact record.
Alerts from all three portals landed as email. There was no canonical event — only forwards, screenshots, and rows pasted into separate workbooks. Duplication across team members was routine.
Flatfox yielded relatively static HTML; Homegate and ImmoScout24 required rendered pages. Each portal needed a different manual path, so throughput capped on analyst attention, not market volume.
Roughly six in ten leads lacked a usable agency email. Analysts burned time on Google and LinkedIn tangents; outreach failed on incomplete rows as often as on bad deals.
Temporary and non-target listings (e.g. befristet rentals) consumed the same attention as core inventory. Formatting drift between portals made aggregation and reporting a second manual project.
End-to-end time from alert to sheet-ready lead routinely ran 24–48 hours. The firm was competing on judgement while the process guaranteed they would always be late to fresh inventory.
Workflow as it existed, with failure points marked.
A six-step ritual repeated for every batch of alerts: read mail, open each portal, extract fields by hand, chase contacts, normalise nothing, file into category-specific sheets — then argue about which version was current.
3 senders · forward / copy · no idempotency
manual8–12 min/listing · 3 UX patterns
bottleneckaddress · price · specs · CHF & DE terminology
manual5–10 min when email missing · browser sprawl
bottleneckcommercial / residential / private · 3 tabs
manualad hoc · no lineage · quarterly rebuild
brokenTrigger · Decision · Execution · Data · Observability.
One intake path from Gmail, deterministic portal routing, parallel extractors (HTTP + Apify), a structured LLM normalisation pass with explicit nulls for unknown fields, conditional enrichment with confidence scoring, and append-only audit metadata into Sheets.
Listing alerts as canonical events
API watch on three alert mailboxes; HTML body and links normalised into a single `listing.alert` payload within ~60s of arrival
Listing URL extracted reliably; downstream idempotency keyed on portal + listing id
Portal routing, classification, policy filters
Routes to Flatfox, Homegate, or ImmoScout24 pathways without human triage
Keyword and structured rules drop befristet / non-target inventory before enrichment spend
Commercial, residential, and private-rental buckets drive which Sheet tab receives the row
Extract, normalise, enrich, persist
HTTP fetch + CSS parsing for Flatfox-shaped pages
Apify actors + dataset polling for JS-rendered Homegate / ImmoScout24 content
LLM emits schema-locked JSON — addresses, CHF amounts, areas, floors (EG / OG normalisation), equipment arrays
Conditional web-assisted lookup when HTML lacks email; high / medium / low confidence recorded with source attribution
Google Sheets API writes 50+ fields per row with timestamps and processing lineage
One repository, typed columns, audit fields
Category tabs aligned to investment tiers; dashboard-ready columns
Source portal, extract method, model version, and enrichment provenance stored per lead
Operational confidence, not inbox hope
n8n execution history plus structured error paths; failed listings don't stall batch
Extraction accuracy and contact-completion tracked against targets; alerts on error-rate spikes
Polls three mailboxes, parses HTML, emits normalised alert events with stable keys for deduplication.
Sender- and pattern-based switch to Flatfox, Homegate, or ImmoScout24 extractors — parallel where possible.
Direct fetch + selector pipeline for static pages; Apify-backed headless flow for dynamic portals with async completion waits.
Schema-constrained JSON output for multilingual Swiss market copy; nulls for missing data instead of invented fields.
Skips expensive lookup when email already present; scores and attributes enriched contacts for outreach prioritisation.
Real-time sync to categorised tabs; timestamps and audit columns for compliance and replay.
Numbers out of the production system — not testimonials.
Wall-clock from mailbox delivery to enriched row available for outreach — down from one-to-two days of queued manual work.
Share of rows with actionable agency contact after enrichment, vs. manual baseline.
System sustained 300+ listings/day across portals vs. ~30 manual before process breakdown.
Analyst time reduced to monitoring and edge exceptions vs. multi-hour copy-paste cycles (measured on ~30-listing batches).
The portals were never the bottleneck — the absence of a pipeline was. Once alerts became events, extraction became a product surface, and enrichment became a gated service, the team stopped competing on who could tolerate the most tabs. They competed on which deals to call first.
A regional 3PL with 400+ daily shipments ran dispatch through a spreadsheet, a call rota, and the judgement of three senior planners. We replaced the judgement with an engineered decision layer.
A DTC health & beauty brand scaled from 50 to 500 orders a day using humans as the integration layer. We rebuilt the spine so the next 5× happened without adding headcount.
Every case on this site started as an audit. If this study described a system that looks like yours, the fastest next step is a formal operations diagnostic.