Bulk import — bringing your data in from CSV
Habitia’s Bulk import brings an entire portfolio in from CSV files in one sitting — useful when you’re moving from a spreadsheet, another tool, or paper records. Every upload is checked and previewed before anything is written, and every import can be undone for 24 hours.
Note: Only admin and manager roles can see the Bulk import page.
When to use bulk import
- You’re switching to Habitia from a spreadsheet or another tool.
- You have 10+ properties or 20+ units, and adding them one at a time would take all day.
- Not for day-to-day work — once you’re set up, use the regular Add buttons.
The simple way: Migrate my portfolio
From the left sidebar, click Migrate data (the upload icon). You land on a single drop zone. Drop in every CSV you have at once — a properties list, a units list, a tenant list, your leases — in any order. Habitia recognizes each file by its column headers, checks every row, and shows you one review screen:
- what it found in each file, and which files it could not read;
- Before you import notes that say what is missing and what would fix it (for example, “3 leases name a property that is in no file” or “5 tenants will be created without a phone number — upload a tenants spreadsheet with a phone column”);
- a preview per entity, and the full list of row errors.
Files in the same upload can reference each other: a leases file can point at a unit from the units file you dropped alongside it. Click Import once for everything, and Undo once if you need to.
Since October 31, 2026 the drop zone also reads lease contracts as PDF (English or Spanish) and Excel or CSV sheets of any shape, such as a rent roll exported from another tool. Those files take a few minutes: the review screen says Analyzing and fills in by itself. Each proposed value shows the passage of the contract it came from, so you can check it before you import. A sheet that does not say which property it belongs to asks you once on the review screen. The files are read inside Habitia’s own cloud by a model we run ourselves and are never sent to an outside AI service.
Scanned or photographed contracts without a text layer are not read yet; they are kept with the upload and listed as unread.
The rest of this page describes the templates and the per-entity path, which the drop zone uses underneath.
The structured way: per-entity templates
Click Per-entity templates at the bottom of the Migrate page. It walks you through six entity types in a fixed order:
properties → units → tenants → leases → spaces → assets
Each step references the previous one by name, so the order matters. Spaces and assets are optional.
2. Download the CSV template
Each entity card has a Download template button. Click it — you’ll get a <entity>_template.csv file with the header row Habitia expects, plus a comment row of hints for each column.
Open it in Numbers, Excel, Google Sheets — whatever you use.
Tip: Don’t rename or remove the header columns. Habitia matches by header name. If a required column is missing, the upload is refused with the list of missing columns.
3. Fill in your data
A few row-level rules:
- Properties first. Required. Every later CSV references properties by name. Use names you’ll recognize (“Calle Luna 12” works; “Property A” doesn’t).
- Units reference the property by name. Spelling matters; capitalization doesn’t.
- Tenants are matched by email. One row per tenant. The
id_numbercolumn is stored encrypted. - Leases reference the unit by property + unit number and the tenant by email. If the tenant isn’t in Habitia yet, fill in
tenant_full_nameand they’re created with the lease.co_tenant_emailstakes a semicolon-separated list of existing tenants. - Services, amenities and extras. Units take
amenities(pool; gym; laundry),utilities_included(water; trash) andpet_policy. Leases takepet_depositandrecurring_chargesfor fixed monthly extras billed with the rent, written aslabel:amount:category, for exampleParking:50:parking; Agua:25:water. - Spaces and assets are optional. Skip them entirely if you don’t track rooms or appliances individually.
Leases that already started
Most migrated leases started months or years ago. Habitia needs to know what to do with those past months so nobody shows a false balance:
- Paid up (the default, chosen above the Upload button): past months are recorded as paid history and the live ledger starts this month. If someone still owes rent, put the amount in the
outstanding_balancecolumn and it’s posted as a carry-over charge. - Backfill: Habitia posts a rent charge for every month since the lease started, and you enter the historical payments yourself.
The security deposit works the same way. For an active lease Habitia assumes the deposit is already in your hands (it shows as held, not owed). Set deposit_paid to false if you’re still waiting on it.
4. Upload, review, import
- Save the filled-in CSV.
- On the Bulk import page, click Upload CSV under the matching entity card.
- Habitia checks every row and shows a summary — N to create, N already in Habitia, N with errors — plus a preview of the first rows and the full list of errors with row number, field name, and message. Nothing has been written yet.
- Click Import N rows to write the valid rows, or Discard to throw the upload away. Rows with errors are skipped; fix them in your CSV and upload the file again — rows that are already in Habitia are recognized and never duplicated.
- After importing you’ll see N rows imported and an Undo import button that stays available for 24 hours.
Note: Undo removes everything that import created — including tenants auto-created from a leases file and the ledger history written for them — and marks the units vacant again. If you imported units and then leases, undo the leases import first.
5. Move to the next entity
Once properties are in, do units, then tenants, then leases. Working out of order will create errors because later CSVs reference names that don’t exist yet. The Recent imports list at the bottom of the page shows every upload with its status and an undo button while the window is open.
File size and format
- Max 5 MB per file (roughly 50,000 rows — well past any realistic single portfolio). Max 20,000 data rows per upload.
- CSV only (
.csv). Excel files don’t work — export to CSV first. - UTF-8 encoding is safest. If your CSV has accents or ñ, save as UTF-8 so the characters survive the upload.
Common errors and fixes
| Error message | What it means |
|---|---|
| “property_name ’…’ not found in your org” | The property name in this row doesn’t match any property you’ve imported. Check the spelling. |
| ”… is required” | A required column is blank. The template’s comment row marks required fields. |
| ”… must be a YYYY-MM-DD date” | Date isn’t in YYYY-MM-DD format. Use 2026-05-12, not 5/12/26. |
| “Duplicate of row N in this file” | The same property / unit / tenant appears twice in the file. Keep one. |
| “That unit already has an active lease in Habitia” | A unit can only have one active lease. End the existing one first, or import this one as expired / terminated. |
| “Your plan is limited to N units” | The upload would take you past your plan’s unit cap. Upgrade, or import fewer units. |
What’s next
- Adding a property — for adding more after the bulk import is done.
- Sending a lease for signature — for leases that came in as drafts and now need signatures.