Internal · AppFolio Sync · CSV import + on-demand pulls
Admin · Staff Portal · AppFolio Sync

AppFolio Sync

The bridge that lets the internal portal speak to AppFolio without API access. Nightly CSV exports + on-demand "Refresh" + Skywalk fallback for live reads. Drives every other workflow: NOLAs, Mailings, Owner Search, Collections.

Sync healthy Last full pull: 03:14 today · Next scheduled: 03:00 tomorrow 412 owner ledgers · 18 associations

Tonight's import (preview)

Scheduled03:00 ET nightly
SourceAppFolio scheduled CSV → SFTP drop
Tables pulled8
Avg run time2m 18s
Last failure— (clean since Apr 12)

What gets imported

Owner ledgers412 rows
Recurring charges412 rows
Open work orders22 rows
Vendor list + COIs86 rows
Bank balances (per assoc)36 rows
Manager calendar events144 rows
BOD members + officer roles104 rows
Recent payments (last 90d)~3,400 rows

Recent imports · last 14 days

DateRun timeRowsStatusNotes
Apr 28 03:142m 11s4,512✓ Clean3 new owner profiles · 4 vendor COIs renewed
Apr 27 03:082m 18s4,508✓ Clean1 NOLA-eligible flagged · queued for Page-per-Page
Apr 26 03:112m 21s4,505✓ CleanEstoppel ordered Plaza Tower 304 · indexed
Apr 25 03:092m 14s4,498✓ Clean+12 work orders since prior · 9 closed
Apr 24 03:122m 25s4,487✓ Clean
Apr 23 03:082m 19s4,476✓ CleanQ1 audit financials uploaded · indexed for board access
Apr 12 03:183m 02s4,452⚠ PartialCenterville recurring-charges file truncated · auto-retried 04:00 · clean

On-demand refresh (during business hours)

For estoppel orders or NOLA prep where the nightly CSV is stale, managers can trigger a fresh pull. Average refresh time: ~14 seconds.

Per-owner refresh

Refresh single owner ledger

Used during estoppel prep — get the ledger as of right now. Fires AppFolio CSV export for one owner (or Skywalk fallback if SLA needs < 5 sec).

⚡ ~14 sec
Per-property refresh

Refresh whole association

Pull full owner ledger + recurring charges + work orders for a property. Used before board meetings + manager reports.

⚡ ~45 sec
Force full sync

Refresh everything now

Trigger the full nightly run on demand. Used after major AppFolio changes (new property added, large vendor batch update).

⚡ ~2 min

Architecture

How it works without an open AppFolio API.
  1. Nightly: AppFolio scheduled report runs at 02:55 ET, exports 8 CSVs to a sFTP/SFTP drop.
  2. Worker: Cloudflare Worker polls the SFTP at 03:00 ET, pulls the new CSVs, parses them with header-aware schema, and upserts into D1 tables.
  3. Hash compare: each row hashed; only changed rows trigger downstream events (NOLA queue, naming validation, manager notifications).
  4. On-demand: manager clicks "Refresh" → worker requests a one-row CSV export from AppFolio scheduled-report API → pulls + applies in < 14s.
  5. Skywalk fallback: for ultra-time-sensitive operations (live estoppel prep, where the manager is on the phone), Skywalk is queried as a real-time read source. Higher cost per query, used sparingly.
  6. Phase 2: if AppFolio Stack partner API approval comes through, the CSV layer is swapped for direct API reads with no architectural change to downstream tools.

Manual override · upload custom CSV

If AppFolio's scheduled export breaks or you need to test changes against a known-good dataset, drop a CSV here. Headers must match the AppFolio schema (see manual). Validation runs before write.