This document is the current source of truth for importing, migrating, and exporting HOA data in HOAfy. It covers roster, unit, accounting, billing-history, document, invoice, bank-transaction, and reconciliation data, including validation, limits, retention, and current export boundaries.
Supported Data Imports
Structured import is available for roster, units, vendors, chart of accounts, receivables, transaction history, documents, and operational invoices. Permissions and prerequisites differ by type.
Watch migration, import, and export in the demo
| Data | Entry point | Format | Limit | Existing records |
|---|---|---|---|---|
| Members, owners, residents, and units | Data > Imports: Members | CSV | 10 MB; 10,000 rows | Skip; never overwrite |
| Units only | Data > Imports: Units | CSV | 10 MB; 500 rows | Skip by unit label |
| Vendors | Data > Imports: Vendors | CSV | 10 MB; 1,000 rows | Link one exact canonical match; skip existing association links |
| Custom chart of accounts | Data > Imports: Chart of Accounts | CSV | 10 MB; 1,000 rows | Existing numbers fail validation; same-job retries skip |
| Outstanding invoices or summary balances | Data > Imports: Billing Data | CSV | 10 MB | Deterministic matches skip |
| Full accounting history with owner detail | Data > Imports: Billing Data | ZIP v2 | 25 MB compressed; 100 MB expanded | Requires no other financial activity or closed periods |
| Document library | Data > Imports: Documents | ZIP | 2 GB compressed; 10 GB expanded; 5,000 entries | Does not overwrite |
| New operational invoices | Billing: Import | CSV | Browser-loaded CSV | Skip by unit and source invoice number |
| Bank transactions | Accounting bank feed | Plaid | Provider-controlled | Synchronizes additions, changes, and removals |
| Reconciliation lines | Accounting reconciliations | Pasted CSV | One period | Used without synchronized feed activity |
Menus and job history are permission-filtered. Users see only import types and jobs they may manage.
Structured Import Workflow
Roster, unit, vendor, account, and receivables imports follow this process:
- Download the current server-generated template.
- Upload the required CSV or full-history ZIP.
- Validate without changing association data.
- Review errors, warnings, duplicates, skips, and totals.
- Correct every error and re-upload when required.
- Explicitly commit a valid job.
- Reconcile resulting records and control totals.
These imports use skip-only conflict handling; there is no overwrite mode. Any error blocks the complete structured commit. Uploads are hash-checked between validation and commit, financially sensitive data is revalidated, stable identifiers provide supported idempotency, and unit-tier capacity is enforced.
New upload records expire after 24 hours when not advanced. Canceled job metadata is retained for about 90 days and completed metadata for about one year. Canceled structured jobs delete their source and report. Completed structured jobs currently retain source and report without automatic expiration. Successful document import deletes its source ZIP after extraction.
Job history distinguishes uploading, queued, validating, ready to import, processing, canceling, canceled, completed, failed, cleaned, and expired states. Structured jobs awaiting commit can be reopened from history. Uploading a corrected source creates a new job; Retry is currently limited to failed document jobs. A commit that encounters a runtime error returns to Ready to import only where the workflow can retry safely.
Roster and Unit Imports
Roster import uses one person/unit relationship per row. Required headers are unit_label and role. Supported data includes property address and type, square feet, bedrooms, assessment amount, voting weight, primary-owner flag, person name, email, phone, mailing address, and move-in date.
| Roster column | Purpose |
|---|---|
unit_label | Association-unique unit, lot, or property label |
street_address, city, state, zip | Property address |
unit_type | Property type such as condo or townhome |
square_feet, bedrooms | Whole-number unit attributes |
assessment_amount | Numeric assessment amount |
voting_weight | Numeric ownership or voting weight |
role | Association role other than Account Owner |
is_primary_owner | yes/no, true/false, 1/0, x, primary, or blank |
first_name, last_name | Person name |
email, phone | Contact data; email is optional but validated when present |
mailing_address | Alternate or off-site mailing address |
move_in_date | Move-in date in one consistently recognized format |
The parser recognizes common header aliases, several delimiters, UTF-8 byte-order marks, common date formats, timestamps, and Excel serial dates, although the uploader requires a .csv filename. Account Owner cannot be assigned by CSV.
Recognized aliases include unit number, lot, property address, monthly dues, owner tenant, and email address. Accepted textual dates include ISO, common US and European numeric forms, and month-name dates. Use one textual layout consistently within move_in_date.
Common role aliases map owner/property owner/unit owner to Homeowner; tenant/renter/occupant/lessee to Resident; officer titles to their board roles; community manager/HOA manager/manager to Property Manager; chairperson to Committee Chair; and contractor to Vendor.
Units match case-insensitively by label. People match by normalized email or, without email, by normalized name within the unit. Existing records are skipped rather than overwritten. Duplicate unit/email rows are errors. Missing owners and ambiguous primary-owner combinations produce warnings.
Unit-only import requires unitLabel. Its complete template is unitLabel, streetAddress, city, state, zip, unitType, squareFeet, bedrooms, assessmentAmount, votingWeight, mailingAddressOverride, and notes. Duplicate labels and invalid numeric fields are errors. Square feet and bedrooms must be whole numbers; assessment and voting weight must be numeric. Existing labels are skipped, and subscription capacity is checked before commit.
Roster import never sends invitations.
Vendor Imports
Vendor import requires legal_name and country. Supported profile columns are dba, email, phone, address_line_1, address_line_2, city, state, postal_code, and semicolon-separated service_areas. Association relationship columns are status, payment_terms, default_gl_account_number, preferred, and internal_notes.
Country must be US or CA. Relationship status defaults to prospect and supports prospect, active, inactive, pending-compliance, and blocked. Preferred accepts yes/no, true/false, or 1/0. A default GL account number must identify an active expense account.
Validation searches the canonical vendor directory by normalized legal name and email. One exact match is linked to the association, a vendor already linked to the association is skipped, and conflicting matches are validation errors. New vendors are created as unclaimed canonical profiles. Import never overwrites a canonical vendor or an existing association relationship.
Chart of Accounts Import
Account import requires account_number, name, type, and fund_name; parent number, description, and status are optional. Types are asset, liability, equity, income, and expense. Status is active or archived.
| Account column | Rule |
|---|---|
account_number | Required; unique in the file and not protected or already used |
name | Required display name |
type | Required: asset, liability, equity, income, or expense |
fund_name | Required; matches exactly one active fund after normalization |
parent_account_number | Optional; references another row or active existing account |
description | Optional internal description |
status | Optional active or archived; defaults to active |
Protected system numbers and existing custom numbers cannot be created through import. A parent must have the same type and fund and must be active when already present. Parent rows may appear later in the same file.
Billing Data Migration Modes
Billing Data provides three mutually exclusive strategies:
| Mode | Use when | Result |
|---|---|---|
| Outstanding invoices | Reliable unpaid legacy invoices exist | One current invoice per open legacy invoice plus opening AR entries |
| Balances by unit | Only aging totals are reliable | Generated invoices per nonzero aging bucket and owner credit where supplied |
| Full transaction history | Opening balances, dated journals, owner detail, and ending trial balance are reliable | Historical accrual accounting with linked invoices, payments, allocations, and vendor bills |
Detailed invoices and summary balances cannot overlap the same units. Repeat summary imports for a unit must use the same conversion date. Neither CSV mode can follow a full-history migration. A closed conversion month or year blocks CSV migration.
Outstanding-invoice CSV requires unit label, external invoice ID, original and outstanding amounts, issue and due dates, and description. Unit references must exist, IDs are unique per unit, amounts are positive, and outstanding cannot exceed original. The conversion date controls opening accounting.
The exact headers are unit_label, external_invoice_id, original_amount, outstanding_amount, issue_date, due_date, and description. Dates accept YYYY-MM-DD and US MM/DD/YYYY. HOAfy generates its own invoice number and preserves the source identifier and previous-system name in migration metadata and memo text.
Balances-by-unit CSV requires unit label, current, 31-60, 61-90, 90-plus, and credit balances. Values are nonnegative, one row is allowed per unit, and each nonzero aging bucket creates an invoice. Credits create unapplied migration payments against Prepaid Assessments.
The exact headers are unit_label, current, days_31_60, days_61_90, days_90_plus, and credit_balance. At least one value must be greater than zero. Generated due dates are the conversion date minus 0, 31, 61, or 91 days for the corresponding bucket. Deterministic identifiers make a retry of the same balances idempotent.
CSV billing migration requires active Accounts Receivable 1100; owner credits require active Prepaid Assessments 2100. The selected opening offset is normally equity and must not re-recognize prior-period income or cash.
Full Transaction History Migration
New full-history migrations require ZIP schema v2. Root-level files are manifest.json, opening_balances.csv, journal_lines.csv, invoices.csv, payments.csv, allocations.csv, and trial_balance.csv. Include opening_owner_balances.csv when pre-history invoices or owner credits remain, and vendor_bills.csv for payable detail. Nested folders and adjustments.csv are rejected; adjustments belong in dated journals and are never silently skipped.
The manifest declares the complete history interval and accounting convention:
{"schemaVersion":2,"historyStart":"2026-01-01","conversionDate":"2026-09-27","currency":"USD","timezone":"UTC","basis":"accrual"}
Use calendar dates in the manifest; conversion must match the selected date. USD, UTC, and accrual are the supported conventions. Version 1 is not accepted for new history migrations.
invoices.csv headers are external_invoice_id, unit_label, issue_date, due_date, status, invoice_type, description, memo, original_amount, outstanding_amount, voided_at, and void_reason. Accepted invoice types are dues, assessment, fee, fine, and late_fee. Paid and void invoices require zero outstanding balance; void invoices require both void timestamp and reason.
payments.csv headers are external_payment_id, unit_label, received_date, status, method, amount, memo, reversed_at, and reversal_reason. Refunded and reversed records require reversed_at.
allocations.csv headers are external_payment_id, external_invoice_id, unit_label, amount, date, action, and external_journal_id. Actions are apply and reverse. The journal date and allocation date must match. Later applications debit Prepaid Assessments and credit AR. Reversing an allocation restores prepaid credit or accompanies a refund/reversal journal.
Both balance files use fund_name, account_number, debit_balance, credit_balance, and memo. Opening balances are immediately before historyStart; the ending trial balance is at conversion. Opening balances plus every dated journal must equal the ending balance for every account, including accounts omitted from the ending file because their balance is zero.
journal_lines.csv headers are external_journal_id, line_id, date, fund_name, account_number, debit, credit, source_type, source_id, unit_label, reverses_journal_id, and memo. Every journal must balance. Source types are invoice, payment, invoice-void, payment-reversal, payment-refund, allocation, adjustment, vendor-bill, vendor-bill-payment, manual, and year-end-close. Invoice, payment, and bill sources reference the corresponding external record ID. Full reversals reference the original journal. Owner sources stay within one unit and fund; manual entries cannot substitute for owner or payable detail.
opening_owner_balances.csv headers are kind, external_id, unit_label, fund_name, account_number, offset_account_number, and amount. Use invoice with AR 1100 or credit with Prepaid Assessments 2100, against same-fund equity. An opening invoice retains its original amount and the remaining balance at the history start. A pre-history payment represents only its remaining unapplied credit. Each opening owner item receives its own journal, separate from the residual opening trial balance.
vendor_bills.csv headers are external_bill_id, vendor_id, bill_date, due_date, status, amount, outstanding_amount, opening_amount, fund_name, payable_account_number, and offset_account_number. Vendors must already exist. Use AP 2010, posted for an outstanding bill, or paid for zero outstanding. Pre-history bills require an opening amount and same-fund equity offset. Dated bills and payments require linked journals; partial payments are retained, and later payment in HOAfy clears only the remaining payable.
Supported invoice statuses are sent, paid, partial, overdue, and void. Supported payment statuses are succeeded, refunded, and reversed; pending and failed activity is rejected. Supported payment methods are cash, check, money order, other, card, and US bank account.
Allocations must connect a payment and invoice for the same unit and fund and cannot exceed available payment funds or the invoice balance at the event date. Trial-balance lines resolve to active funds and accounts and contain either a debit or credit. Partial refunds use dated payment-refund journals; the payment retains its original amount, refund history, and remaining credit. Fully refunded payments use refunded status and either a full payment-reversal journal or dated refunds totaling the complete receipt, with the final refund date as reversed_at. Invoice adjustments, including credit notes and write-offs, use adjustment journals linked to the invoice. Before voiding within imported history, reverse its allocations and adjustments.
Dated journals must fall within the declared history interval; activity dates cannot exceed conversion, while due dates may. Reconstructed invoice balances must match allocations and statuses. Debits and credits must balance, AR 1100 must equal owner receivables by fund, Prepaid Assessments 2100 must equal remaining owner credits by fund, and AP 2010 must match vendor-bill detail.
Full history requires an association without existing invoices, payments, journals, vendor bills, bank transactions, reconciliations, invoice batches, or any closed accounting period. Records already written by the same import job are allowed for retry. Existing units, members, funds, and accounts are allowed.
Imported outstanding invoices retain the links needed for normal online or manual payment. Permitted invoice corrections reverse their own opening/issue and adjustment journals, not a shared opening trial balance. Imported-payment corrections reverse the receipt and its allocation/refund history locally; they do not charge or refund money through a payment provider. Imports do not send invoice notifications.
The financial-performance chart and accrual income statement exclude opening and year-end closing entries from operating activity. Months before the imported history, including an incompletely covered first month, are unavailable rather than reliable zeroes.
Imports write directly to live records. There is no staging, migration lock, atomic activation, asynchronous migration worker, or concurrent-import protection. An interruption may leave partial visible data; concurrent imports can race. Reuse the same job to resume an interrupted import, retain the original file, and inspect resulting balances. Deterministic IDs skip same-job records but do not make the entire import atomic. This workflow does not repair earlier production imports.
Document ZIP Import
Document import applies one destination and one public or board-only visibility to all extracted paths. Limits are 2 GB compressed, 10 GB expanded, 5,000 entries, 1 GB per file, 20 directory levels, 1,024 bytes per path, 255 bytes per segment, and a 100:1 expansion ratio.
Only Store and Deflate compression are accepted. Encrypted entries, links, absolute or drive paths, traversal segments, backslashes, and case-insensitive duplicate paths are rejected. Large uploads use resumable 16 MB parts. Failed jobs can be retried; cancellation removes objects created by that job.
Operational Invoice Import
Billing's separate CSV importer requires unit_label, invoice_number, invoice_type, description, amount, issue_date, due_date, and gl_account. Units and active income accounts must exist, amounts must be positive, duplicate source identities are skipped, and any row error blocks commit.
Each invoice posts a debit to AR 1100 and credit to the selected income account on its issue date. A closed period blocks issuance. Do not use this path for legacy activity already represented in an opening trial balance.
Current Import Limitations
The current import surface does not provide:
- XLSX upload or spreadsheet paste for roster, units, accounts, or billing-data jobs
- User-selectable overwrite behavior
- Partial commit when validation contains errors
- Full-history pending or failed payments
- Version 1 full-history ZIP imports, other currencies/timezones, and unsupported payment states
- Nested folders in full-history ZIP packages
- Full-history merge into existing financial activity or an association with closed periods
- Bank-statement upload as a Data import job; reconciliation accepts pasted CSV instead
Pre-Commit Checklist
- Confirm the selected association and conversion date.
- Download a fresh template or full-history sample.
- Verify unit labels are consistent and unique where required.
- Verify funds and account numbers exist and are active.
- Confirm that the selected billing mode will not duplicate another import.
- Review every warning and correct every error.
- For full history, reconcile owner balances to AR
1100, unapplied credits to Prepaid Assessments2100, and total debits to credits. - Commit before inviting homeowners when imported balances should be visible at first login.
- Retain the original source-system export as migration evidence, especially when a successful document import deletes its source ZIP.
Data Export Availability
The Data workspace's Exports tab provides durable background exports for Members, Units, Vendors, Chart of Accounts, and Billing Data at /hub/data/exports. Completed jobs remain in history for about one year. Each artifact is also published as a board-only document in the association's root /exports folder.
Members and Units exports can include inactive records. Chart of Accounts exports can include archived accounts and HOAfy system accounts. These datasets use the same CSV schemas accepted by their corresponding import workflows.
Vendor exports include canonical profile fields and the association's relationship status, payment terms, preferred flag, default GL account number, and internal notes. They use the vendor import schema and include inactive or blocked relationships so the association receives a complete directory export.
Billing Data exports use a selected cutoff date and can include void invoices and reversed or refunded payments. The current version 1 snapshot ZIP contains manifest.json, invoices.csv, payments.csv, allocations.csv, and trial_balance.csv; it does not contain the opening balances and dated journal lines required by the version 2 importer. It is not a re-importable full-history package. Retain original journals, allocation/refund events, and source exports when preparing a v2 migration. Draft invoices and pending or failed payments are omitted from the snapshot.
Downloaded names begin with the generation date in YYYY-MM-DD format, such as 2026-09-27-hoafy-members-export.csv or 2026-09-27-hoafy-billing-export.zip.
There is no one-click export of all association data and no complete cancellation archive for roster, accounting, documents, and mailbox. Scope each request to the exact dataset and available output.
Operating Guidance
- Complete imports in dependency order and reconcile control totals.
- Complete a full-history conversion before creating financial activity or closing periods. Do not run concurrent imports.
- Select and retain each required dataset before cancellation; there is no universal archive.
- Retain source exports and validation reports as migration evidence.
Support Answers
- Can import and invitations run in one step? No. The roster must be reviewed before invitations are sent.
- Does an import overwrite existing records? No. Structured imports use skip-only conflict handling.
- Can an association export everything before canceling? No universal archive exists today; available exports are dataset-specific.
- Can HOAfy import XLSX files? Not through the current structured import workflows; use the supported CSV or ZIP format for that import type.