Accounting Data Migration Checklist: The 10-Point Plan
A 10-point accounting data migration checklist covering GL, AR/AP, CoA mapping, API rate limits, and trial balance validation — the real process, not just the steps.
Planning a migration?
Get a free 30-min call with our engineers. We'll review your setup and map out a custom migration plan — no obligation.
Schedule a free call- 1,200+ migrations completed
- Zero downtime guaranteed
- Transparent, fixed pricing
- Project success responsibility
- Post-migration support included
Almost every ERP or accounting software implementation begins with an optimistic assumption: "We'll just export the data from the old system and import it into the new one." By week six, the cutover window is blown, the trial balance is off by thousands of dollars, and the finance team is manually reconciling journal entries in Excel.
This is not hypothetical. In an August 2024 SEC filing, Valvoline disclosed that its January 2024 ERP implementation created a material weakness tied to IT general controls and disrupted invoice and billing processes. (sec.gov) That is what makes accounting migrations different from ordinary data moves: when financial data migrates badly, operational pain and control failures surface fast.
An accounting data migration checklist that only lists steps is not enough. The real challenge is knowing how to move a general ledger, chart of accounts, AR/AP aging, and years of historical transactions without breaking your books, failing an audit, or spending weeks reconciling pennies. This 10-point plan covers the specific technical constraints, API rate limits, and validation methods that separate a clean migration from a financial reporting disaster.
If you've been burned by common financial migration mistakes before, this will feel familiar. If you haven't — read it before writing a single migration script.
Why Accounting Data Migrations Are Different
Double-entry accounting makes financial data fundamentally relational. Every journal entry has at least two sides. Every invoice links to a customer, a GL account, a tax code, and potentially a payment. Every payment must reconcile to a bank transaction. Break any one of these relationships during migration, and your books won't balance — and your auditors will notice.
Standard ETL tools treat records as flat rows. Accounting data isn't flat. A single invoice in QuickBooks or Xero carries line items, tax calculations, payment allocations, and currency conversions. If an applied payment doesn't link to the correct historical invoice, your AR aging report breaks. If you misconfigure a historical exchange rate on a closed purchase order, your retained earnings won't match your audited financials.
This is why generic iPaaS tools, one-size-fits-all CSV imports, and naive migration scripts regularly fail at financial migrations.
The 10-Point Accounting Data Migration Checklist
1. Define Your Cut-Off Date and Freeze Window
The cut-off date is the exact moment when your old system stops being the system of record and your new system takes over. Every transaction before this date lives in the old system (or is migrated as history); every transaction after it goes directly into the new system.
Get this wrong, and you end up with transactions recorded in both systems, duplicate payments, and a reconciliation nightmare.
How to execute it:
- Pick a date that aligns with a natural accounting boundary: month-end, quarter-end, or fiscal year-end.
- Freeze the old system for new entries 24–48 hours before go-live. This is your hard freeze window.
- Process all pending bank reconciliations, payment runs, and journal entries before the freeze.
- Export the final trial balance from the old system on the freeze date — this becomes your golden reference document.
- Any transaction posted after the cut-off must be manually dual-entered or captured in a delta sync.
Before anyone exports data, lock down who owns the trial balance, AR aging, AP aging, bank reconciliation, tax reports, fixed asset register, and user acceptance sign-off. If nobody owns a report, it will fail silently.
Never pick a cut-off date mid-month unless you're prepared to split partial-period transactions across two systems. Month-end or quarter-end cut-offs reduce reconciliation complexity by an order of magnitude.
2. Decide How Much History to Migrate
The single biggest lever for reducing migration risk is limiting the scope of historical data. Most businesses only need 3–5 years of transaction history in the new system for operational reporting and trend analysis. Migrating 10+ years of closed purchase orders, voided invoices, and legacy journal entries inflates scope, extends timelines, and carries over years of deprecated accounts, inactive vendors, and tax codes that no longer exist in the new system's structure.
For a deeper framework on scoping ERP data, see What Data Should You Actually Migrate to Your New ERP?.
What about compliance? The IRS general statute of limitations for audits is 3 years from filing, extending to 6 years if more than 25% of gross income goes unreported, and 7 years for bad debt or worthless securities deductions. For fraudulent or unfiled returns, there is no limit.
The practical move: archive anything older than your chosen migration window in a read-only format — a compressed SQL backup, a data warehouse (Snowflake, BigQuery), or structured document archive. This satisfies retention requirements without polluting your new ledger with dead records and stale CoA structures.
Keep your archived data queryable. A BI tool connection to the old database costs almost nothing and gives auditors what they need without migrating obsolete records into an active ERP.
3. Audit and Clean Your Source Data
Your legacy system is not clean. It has duplicate vendors with slightly different names, inactive GL accounts still carrying balances, orphaned transactions, and tax codes that haven't been valid for years. Your new ERP should not inherit the sins of the old system.
Pre-migration data profiling checklist:
- Run a duplicate analysis on vendor and customer master records.
- Identify GL accounts with zero balances that haven't been posted to in 12+ months.
- Validate that all open AR/AP invoices have valid customer/vendor references.
- Confirm tax codes in the source system map to valid tax rates in the target.
- Check for negative inventory or negative AR balances that signal data quality issues.
- Flag orphaned transactions (e.g., payments not applied to any invoice).
- Identify closed periods with late adjustments and multi-entity intercompany entries that may need special handling.
Do not use your new ERP as a data cleansing tool. Cleanse the data in a staging environment or data warehouse before transforming it for the target system.
4. Map the Chart of Accounts to the New Structure
The Chart of Accounts (CoA) migration is where most teams lose weeks. Your old CoA has evolved organically — duplicate accounts, inconsistent naming, accounts created for one-off projects that are still active. Your new system is an opportunity to restructure, but you can't restructure and preserve historical reporting granularity without a rigorous mapping document.
Legacy systems often rely on massive, hard-coded account strings (e.g., 4000-10-200 for Revenue-Software-NorthAmerica). Modern ERPs use a leaner natural account (4000) combined with dimensions or tracking categories (Department: Software, Region: NorthAmerica). You must create a mapping matrix between the old account strings and the new dimensional model. Every legacy account must map to a specific natural account and set of dimensions in the target system. If you fail to map this correctly, historical reporting continuity is destroyed.
For a complete deep-dive on this step, see Your Chart of Accounts Migration Plan.
Key mapping fields:
| Mapping Field | Why It Matters |
|---|---|
| Source account code and name | Traceability back to legacy reports |
| Target account and type | Posting behavior and financial statement placement |
| Tax code mapping | Sales tax, VAT, or GST accuracy |
| Dimension or class mapping | Year-over-year reporting continuity |
| Historical remap rule | How old transactions roll into the new structure |
| Owner approval | Audit trail for sign-off |
Platform-specific constraints to know:
- NetSuite: CoA CSV import has a 25,000-row limit per file. Parent accounts must be imported before child accounts — if you enable multi-threading, you risk
Invalid parent reference keyerrors. Account balances should not be included in the CoA import; use the journal entry import process instead. (docs.oracle.com) - Xero: Limited to a flat or two-level account structure. If your legacy system has deep hierarchies (4–5 levels), you'll need to flatten them and preserve reporting continuity through tracking categories.
- QuickBooks Online: Intuit documents a 250-account limit on Simple Start, Essentials, and Plus subscriptions; Advanced removes that limit. Classes and locations — often used as CoA dimensions — are only available in Plus and Advanced plans. (quickbooks.intuit.com)
Always map old account numbers to new account numbers in a spreadsheet before touching the target system. Have your Controller or CFO sign off on the mapping. This document becomes part of your audit trail.
Master data must be migrated and validated before any transactional data moves. Invoices, bills, and journal entries enforce strict referential integrity — an invoice cannot be created via API if the associated CustomerID or ItemID does not already exist in the target system. Ensure payment terms are mapped correctly, default currency assignments are accurate, 1099 vendor flags are preserved, and active vs. inactive statuses are explicitly set.
5. Migrate Open AR/AP and Active Subledgers
Open invoices and bills are the most operationally sensitive data in the migration. If your AR aging report is wrong on Day 1 of the new system, your collections team is blind. If AP aging is wrong, you'll miss payment terms and damage vendor relationships.
The core challenge: you need open invoices to appear in the new system with their original dates, amounts, and remaining balances — so that when a payment arrives post-migration, it can be correctly applied against the right invoice.
When migrating open AR and AP, you have two approaches:
- Net Balance Approach: Migrate a single open invoice for the remaining balance only. Simpler, but you lose the audit trail of the original invoice amount and partial payments.
- Full History Approach: Migrate the original invoice, then migrate each payment, and explicitly link them in the new system via API. Preserves full document history but requires your migration script to handle payment application logic.
Regardless of approach:
- Extract all invoices and bills with an outstanding balance as of the cut-off date.
- Migrate them as open documents (not as journal entries), preserving the original invoice number, date, customer/vendor, line items, and remaining balance.
- Preserve the source-to-target legacy ID mapping for every document.
- After migration, run the AR and AP aging reports in both systems and compare them line by line. They must match.
What to leave behind: Fully paid invoices older than your chosen history window. They carry no operational value in the new system and can be accessed in your archive for audit purposes.
Do not replace open items with a single balance-forward journal unless the business has explicitly accepted the loss of document-level continuity. Aging reports may look right in total but become useless operationally when collections can't find the original invoice.
6. Handle Multi-Currency and Tax Codes Correctly
If your business operates in multiple currencies, migration complexity increases significantly. Exchange rates, unrealized gains/losses, and revaluation entries all need explicit handling.
Watch for these failure modes:
- Stale exchange rates: If you migrate a historical invoice using today's exchange rate instead of the original transaction date rate, your P&L and balance sheet will be wrong. Historical transactions must retain their original exchange rates.
- Revaluation entries: Unrealized FX gains/losses that exist in the old system may not transfer cleanly. You may need to reverse them in the old system and re-book them in the new one.
- Base currency mismatches: Some platforms (Xero, FreshBooks) restrict you to a single base currency. If your legacy system used multiple base currencies across entities, you need a consolidation strategy before migration.
Tax codes (VAT, GST, state sales tax) must be mapped explicitly. Many target ERPs will attempt to auto-calculate tax upon API insertion. Your migration payload must explicitly override auto-calculation to preserve the exact tax amount recorded in the legacy system.
Xero's API added warnings in April 2026 when supplied CurrencyRate values look suspicious on multicurrency endpoints. If FX history matters, freeze the rate logic you will use before loading open foreign-currency items. (developer.xero.com)
7. Migrate Fixed Asset Registers with Accumulated Depreciation
Fixed assets are often an afterthought in accounting migrations, but they carry significant tax and reporting implications. Each asset needs its acquisition date, original cost, depreciation method, useful life, and accumulated depreciation to date.
The trap: If you migrate an asset with its original cost but reset its depreciation schedule, your depreciation expense will be overstated going forward, and your tax filings will be wrong.
The fix: Import each asset with its accumulated depreciation as of the cut-off date. The new system should calculate remaining depreciation from the migrated accumulated amount, not from zero. During validation (Point 9), fixed asset cost, accumulated depreciation, and net book value must all tie out between the old and new systems.
8. Navigate API Rate Limits for Historical Loads
Accounting software APIs are designed for daily transactional syncs, not bulk historical data loads. If you attempt to push hundreds of thousands of historical journal entries through a standard REST API without intelligent batching, you will hit rate limits immediately. These limits are design inputs for your migration architecture, not details to solve later.
| Platform | Rate Limit | Practical Impact |
|---|---|---|
| Xero | 60 calls/min, 5,000 calls/day, 5 concurrent per tenant (developer.xero.com) | Each invoice with contacts and line items requires ~5–6 API calls. Without batching, you max out at ~833 invoices/day. Xero supports batching up to 50 items per POST (keep under 3.5 MB). Since September 2024, Xero also enforces high-volume GET thresholds on requests processing 100K+ documents. |
| QuickBooks Online | 500 req/min, 10 req/sec per realm+app, 10 concurrent (developer.intuit.com) | Higher per-minute throughput than Xero, but the concurrency ceiling causes 429 errors during parallel operations. Intuit recommends max 30 payloads per batch request. 120-second request timeouts. Native invoice import capped at 100 invoices / 1,000 CSV rows per batch. |
| NetSuite | Concurrency-based (varies by license tier) (docs.oracle.com) | CSV Import Assistant caps at 25,000 rows or 50 MB per job. Imported transactions cap at 5,000 lines; journal entries can reach 10,000 lines. Transactions over 1,000 lines may time out. |
These limits mean a migration of 10,000+ historical invoices to Xero can take multiple days of continuous API calls — or a few hours with intelligent batching and retry logic.
Your migration architecture must include:
- Exponential backoff and retry logic
- Idempotent writes (so a retry doesn't create duplicates)
- Batch endpoints where available
- Period-by-period loading (not one massive all-history dump)
- Checkpointing after partial success so you can restart without re-processing
// Example: Single invoice payload for Xero API
// Without batching, each of these consumes API calls fast
{
"Type": "ACCREC",
"Contact": { "ContactID": "12345" },
"LineItems": [
{
"Description": "Consulting Services",
"Quantity": 1.0,
"UnitAmount": 1500.00,
"AccountCode": "4000"
}
]
}A partial invoice load is worse than no migration at all. If half your invoices make it to the new system before an API rate limit kills the job, your AR aging report will be wrong, your trial balance won't tie, and you'll spend days figuring out what made it and what didn't. Always implement idempotent writes and transaction-level rollback.
9. Validate with Trial Balance Tie-Out, Not Record Counts
This is where most migrations fail silently. Teams verify that the right number of records made it to the new system — 5,000 invoices in the source, 5,000 in the target — and declare success. Record count matching tells you nothing about financial accuracy.
If your legacy system had 10,000 invoices and your new system shows 10,000 invoices, an IT engineer might call it done. But if tax lines were stripped during the API transformation, your revenue is overstated and your tax liability is understated. The pattern is well-documented across ERP implementations. For a deeper analysis of why this happens, see Why ERP Migrations Fail at the Data Layer: 9 Core Patterns.
The golden rule: opening balances in the new system must tie exactly to the closing balances of the old system, to the penny.
The correct validation sequence:
- Trial Balance comparison: Export the trial balance from both systems as of the cut-off date. Every GL account balance must match to the penny. Use a clearing account to process historical imports and ensure it zeroes out completely.
- AR Aging reconciliation: Compare the AR aging report (current, 30, 60, 90+ days) between old and new systems. Totals and individual invoice balances must match.
- AP Aging reconciliation: Same process for accounts payable.
- Bank reconciliation: Confirm that the bank balance per the new system's ledger matches the last reconciled bank balance in the old system.
- Tax liability check: Ensure tax liability reports match the legacy close.
- Retained earnings: Verify prior-year earnings roll correctly.
- Fixed asset tie-out: Cost, accumulated depreciation, and net book value must all match.
- Spot-check journal entries: Pull 20–30 random journal entries from the old system and verify they exist in the new system with identical debits, credits, dates, and references.
- Run a P&L and Balance Sheet: If you migrated historical transactions, generate these reports for a prior period in both systems and compare.
-- Example reconciliation queries
SELECT SUM(debit) AS debits, SUM(credit) AS credits
FROM gl_entries
WHERE posting_date <= DATE '2026-03-31';
SELECT SUM(open_amount_home_currency) AS ar_open_total
FROM ar_open_items
WHERE status = 'OPEN';
SELECT balance
FROM gl_trial_balance
WHERE account_code = '1200-AR';Build your reconciliation reports before the migration, not after. Know exactly which reports you'll compare and what "success" looks like before you start loading data.
10. Document Everything for Audit Trail Continuity
An accounting data migration is a change to your financial reporting system. Under SOX Section 404, public companies must assess and document any change to Internal Control over Financial Reporting (ICFR). (sec.gov) Even if you're not SOX-regulated, your auditors will want to see documentation of what was migrated, how it was validated, and who approved it.
Your audit documentation package should include:
- The signed-off CoA mapping document
- The cut-off date and freeze window log
- Trial balance comparison (old vs. new system)
- AR/AP aging comparison reports
- A record of all data transformations applied during migration
- Exception log: any records that failed migration and how they were resolved
- Retry and error logs from API loads
- Sign-off from the Controller or CFO confirming the migration is complete and accurate
If a reviewer asks why a balance changed, you should be able to answer with a document trail, not memory.
For SOX-regulated companies, this documentation feeds directly into your ICFR assessment. See SOX-Compliant ERP Migration: Maintaining Audit Trails in Dynamics 365.
Why DIY Scripts and Generic iPaaS Fail at Financial Migrations
Three common approaches to accounting data migration, and two of them fail predictably:
Native CSV imports (NetSuite Import Assistant, Xero's CSV upload, QBO's import tools) work for small, one-time loads of master data — chart of accounts, customer lists, vendor lists. They fail at transactional data because they can't preserve relational integrity between invoices, payments, line items, and GL postings in a single import. NetSuite's own documentation states that opening balances should not be included in CoA imports and should instead be loaded as journal entries. QuickBooks Online's Desktop-to-Online migration tool has its own constraints: the source file must stay under 4 million targets, and you have 60 days after creating the QBO company to move data. (quickbooks.intuit.com)
Generic iPaaS tools (Zapier, Make, Boomi) are designed for ongoing event-driven automation, not bulk historical migration. They process records one at a time, don't handle double-entry validation, and will burn through Xero's 5,000 daily API calls or QuickBooks' 500-per-minute limit within minutes when pointed at a historical dataset. They have no concept of a trial balance tie-out or financial reconciliation.
In-house scripts can work if your team has deep knowledge of both the source and target accounting APIs, understands double-entry bookkeeping logic, and can build idempotent writes with retry logic. The risk is time and domain knowledge: your engineers will spend weeks discovering that QuickBooks Online handles sub-customers differently than NetSuite, or that Xero's API silently rounds line items differently than its UI. A migration that takes a specialized team days takes an in-house team weeks, and the opportunity cost of pulling your engineers off product work is real. For more on this trade-off, see 7 Costly Mistakes to Avoid When Migrating Financial Data.
When to Bring in a Specialist
If your migration involves any of the following, you're in territory where the cost of getting it wrong far exceeds the cost of getting help:
- Multi-entity or multi-currency environments with intercompany eliminations
- More than 5,000 historical transactions that need to move via API
- SOX or SOC 1 compliance requirements that demand auditable migration documentation
- A hard go-live deadline tied to a fiscal year-end or regulatory filing
- Multiple source systems being consolidated into one target ERP
At ClonePartner, we've executed financial data migrations across QuickBooks, Xero, NetSuite, Sage, and Dynamics — including a Sage Intacct to Xero migration completed in 5 days. We handle API rate limits with intelligent batching, guarantee that opening balances tie to closing balances to the penny, and deliver the audit documentation package your Controller needs to sign off with confidence.
What a Clean Accounting Cutover Looks Like
A clean accounting migration is boring in the best possible way. The opening trial balance matches to the cent. AR/AP aging still rolls into the control accounts. Tax and FX behavior are explainable. Historical reporting is either preserved in-system or intentionally archived with documented access. Nobody is guessing where a number came from on day two.
The single highest-ROI decision you can make: validate with financial accuracy (trial balance, aging reports, bank reconciliation), not just record counts. That one practice prevents the majority of post-migration accounting disasters.
If your migration includes open AR/AP, multi-currency, or years of history that still need to reconcile on day one, treat the checklist above as the floor, not the stretch goal.
Frequently Asked Questions
- How long does an accounting data migration take?
- Timeline depends on volume and platform. Migrating 5,000 invoices to Xero via API can take multiple days due to the 5,000 daily call limit (each invoice requires 5–6 calls). With intelligent batching, the same migration can complete in hours. A full accounting migration — including CoA setup, open AR/AP, and historical transactions — typically takes 3–10 business days with a specialized team.
- How many years of financial history should I migrate to a new ERP?
- Most businesses need 3–5 years of transaction history for operational reporting and trend analysis. Older data should be archived in a read-only format (SQL backup, data warehouse, or structured documents) to satisfy IRS retention requirements (3–7 years depending on circumstances) without polluting the new ledger with outdated records and stale CoA structures.
- How do I verify an accounting migration was successful?
- Never rely on record counts alone. Run a trial balance comparison between old and new systems — every GL account must match to the penny. Then compare AR aging, AP aging, and the last reconciled bank balance. Spot-check 20–30 random journal entries. Only declare success when all financial totals tie exactly.
- Can I use Zapier or Make to migrate accounting data?
- Not recommended for bulk historical migration. These tools process records individually, lack double-entry validation, and will exhaust Xero's 5,000 daily API calls or QuickBooks' 500/min limit within minutes on historical datasets. They're designed for ongoing automation, not one-time bulk data loads with financial reconciliation requirements.
- What happens if opening balances don't match closing balances after migration?
- Your books won't balance, which means your trial balance is wrong, financial statements are unreliable, bank reconciliations will fail, and any regulatory filing based on the new system's data is at risk. This is the single most common accounting migration failure and requires re-running the migration with corrected data and transformation logic.