Skip to main content

CSV Import Wizard

The Import page (/import) is the fastest way to get a new agency live. A typical 150-door portfolio finishes all three imports in 10-15 minutes.

How it works

Three cards, one per entity type. Each card:

  • Has a Download sample CSV button that produces a valid header + one example row
  • Has a Choose file picker accepting .csv or text/csv
  • Parses row-by-row; a bad row is skipped with an error line, the rest still land
  • Returns { createdCount, errors: [{ row, message }] } on completion

Properties (+ owners)

street,suburb,state,postcode,property_type,owner_approval_threshold,owner_name,owner_email,owner_mobile
45 Bourke St,Melbourne,VIC,3000,APARTMENT,50000,Jane Montgomery,jane@example.com,0400 111 222
  • state — VIC / NSW / QLD / WA / SA / TAS / ACT / NT
  • property_typeAPARTMENT / HOUSE / TOWNHOUSE / UNIT / STUDIO
  • owner_approval_threshold — dollars × 100 (cents). 50000 = $500.
  • owner_email — find-or-create. If an owner with that email exists in your agency, the property links to them. If not, a new owner is created.
  • All owner fields are optional except owner_email. A blank email creates a no-owner property (edge case — use sparingly).

Endpoint: POST /api/v1/properties/import-csv (multipart).

Tenants

full_name,email,mobile
Alex Nguyen,alex@example.com,0411 100 001
  • Either email or mobile required.
  • Leases are not part of this CSV — we'll add that in a second pass once tenants are loaded. Today, link leases via the property detail page or API.

Endpoint: POST /api/v1/tenants/import-csv.

Contractors

business_name,abn,trades,email,mobile,insurance_expires_on
Harbour Plumbing,53 004 085 616,PLUMBER;GAS_FITTER,ops@harbour.example,0411 222 333,2027-06-30
  • trades — semicolon-separated. See Trade enum.
  • insurance_expires_on — ISO date (YYYY-MM-DD). Drives the CONTRACTOR_INSURANCE_EXPIRING scanner + ranked-picker score.
  • abn — free text, no validation today. Future: ABN lookup.

Endpoint: POST /api/v1/contractors/import-csv.

Common errors you'll see

ErrorFix
row 4: invalid state 'Victoria', expected VICUse the 2-3 letter code, not full name
row 7: trades field emptyContractor must have at least one trade
row 12: mobile and email both missingTenant / contractor needs one reachable contact
row 15: owner_approval_threshold must be integer cents50000 not 500.00

The errors panel in the UI shows the first 20; the rest are available in the response payload.

Atomicity

Each row is processed in its own transaction. A bad row does not rollback earlier good rows. This is intentional — a 500-row CSV with 3 bad rows should leave you with 497 loaded rows and a list of the 3 to fix and re-upload.

Safe to re-upload: properties dedupe on (agency, street, suburb, state, postcode); tenants dedupe on (agency, email); contractors dedupe on (agency, business_name).

See also