Amir Omidvar
← All work

Forward-Deployed · Production Systems · Ongoing

Operations platform for a short-term-rental portfolio

Embedded with an STR operator to build the software backbone their team now runs every day.

OperationsLast 30 days
Occupancy
87%
▲ 4%
RevPAR
$142
▲ 2%
Reservations
6,240
▲ 310
Revenue by month 2026
PropertyADROccStatus
Unit A-12$16891%Live
Unit B-04$14284%Live
Unit C-21$15578%Live

Representative UI, abstract, with no client data.

147
rental properties operated
$94K
recoverable revenue surfaced by a reconciliation engine
12 systems
Guesty, PriceLabs, QuickBooks, Plaid, Stripe, Wise, Monday and others on one pipeline

How it works

112 integrated systems

Guesty · PriceLabs · QuickBooks · Plaid · Stripe · Wise · Monday · others

↓
2Token-budgeted sync

15-min pipeline, header-adaptive back-off, file locking

↓
3Postgres + views

materialized views compute metrics server-side

↓
4Dashboard + LLM

live ops UI plus message-to-task classification

↓
5Reconcile + alert

payout matching, anomaly + failure alerts

Architecture

Frontend
Next.js dashboard
17 live views
↓
Backend
FastAPI
Sync engine
Reconciliation
LLM task classifier
↓
Data
PostgreSQL 16
Materialized views
↓
External
Guesty
PriceLabs
QuickBooks
Plaid
Stripe
Monday

By the numbers

Where the reconciliation engine paid off

Revenue recovered (missed / mismatched)~$94K
Uncollected taxes surfacedsix figures
Ops time saved~15 hrs/wk

Context

A growing short-term-rental portfolio was running on manual spreadsheets and disconnected tools. Revenue leaked through unreconciled payouts, and the team had no single source of truth across listings, reservations, pricing, and cleaning.

What I did

  • Built an operations dashboard unifying listings, reservations, calendars and pricing across twelve integrated systems.
  • Designed a reconciliation engine that cross-checks payouts against reservations to flag missing and mismatched money.
  • Engineered a token-budgeted sync engine (header-adaptive back-off, DB-cached OAuth, file locking) to stay under strict provider rate limits.
  • Added an LLM layer that classifies guest messages/reviews into an operational task queue, plus monitoring and alerting so failures surface before they hit operations.

Outcome

  • Surfaced a six-figure pool of recoverable revenue that manual review had missed.
  • Replaced spreadsheet operations with a live dashboard the team runs daily.
  • Reconciliation and sync run continuously instead of as occasional manual audits.

Under the hood

The sync engine

  • Runs every 15 minutes across two Guesty accounts and multiple providers, but must live inside a hard rate-limit budget (one provider caps OAuth at ~5 tokens/day).
  • DB-cached OAuth, header-adaptive back-off, and file-based locking prevent overlapping runs and token exhaustion; a four-layer reliability design self-heals from partial failures.

The reconciliation engine

  • Cross-checks bookings, payouts and bank/Stripe/QuickBooks transactions across two currencies to find money that manual review missed.
  • Recovered ~$94K of missed and mismatched revenue and eliminated a large double-count that had distorted the P&L.

The LLM operations layer

  • Every guest, owner and staff message and review runs through an LLM pipeline that routes it into the right maintenance or service task.
  • Turnover and inspection automation across the portfolio feeds a downstream payroll pipeline and saves the ops team ~15 hours a week.

Finding the failures that never raise an error

  • Monday.com's items(ids:) field paginates with an undocumented default page size of 25. Code asking for 100 ids received the first 25, with no error and no truncation flag, and six call sites had been reading a fraction of the portfolio for an unknown period.
  • It was found by measuring requested-versus-returned counts rather than by reading the code, and only after a first fix that was correct in itself failed to move the symptom. That negative result is what located the real cause.
  • The same pass caught a cancellation path reporting success without verifying its own writes, and a sync reporting zero changes while reading under a third of its population. All three now fail loudly rather than silently.

Stack

Next.jsFastAPIPostgreSQLCron pipelines12 integrated systemsAnthropic