The problem
In 2021, we launched a lockbox lending program for MLS subscribers, letting agents borrow a lockbox for listings they wanted to secure. The problem was operational, not technical: every request was tracked in a spreadsheet, with administrators manually copying listing and agent data in by hand.
That meant no reliable way to know which listings had gone off-market while their lockbox was still checked out, no easy way to see which agents had used the program, and no visibility into which satellite pickup locations had lockboxes on hand. My manager asked me to evaluate off-the-shelf options, but nothing fit how the program actually worked, so we built one instead.
The approach
I built the tool in Django with PostgreSQL, structured around five core models: Requests, Listings, Agents, Lockboxes, and Satellite Locations.
- A backend process runs every 10 minutes, pulling new and updated listing and agent data from the MLS's RETS feed using Python and Pandas, then upserting it into Postgres via SQLAlchemy.
- Every listing that opts into the lockbox program automatically becomes a request, with agent and listing data attached — no one types it in by hand.
- When a listing's RETS status flips to off-market, the tool flags the associated request as overdue if the lockbox hasn't been marked returned, so admins know exactly what to chase down.
- Day-to-day work — reviewing new requests, marking returns, checking the overdue list — happens on the front end. Anything more structural, like adjusting lockbox inventory or managing satellite locations, goes through the Django admin, since only two administrators use the tool and they're comfortable there.
The dashboard surfaces overdue requests, an index of agents who've used the program, lockbox counts by satellite location, and basic utilization numbers.
What I'd do differently
Two things I'd tackle first: the codebase itself needs a cleanup pass — it grew quickly to solve an urgent operational problem, and structure took a back seat to shipping. I'd also build out more self-service tooling on the front end so fewer edge cases require a trip into the Django admin.
Result
Since launch, the tool has processed lockbox requests for more than 1,200 agents and over 6,000 loaned lockboxes, with 550–600 requests active at any given time. It's a clear upgrade over the spreadsheet it replaced, and the two administrators who run the program use it daily.