---
title: "Dynamics GP to Sage Intacct Migration: Data Mapping & Timeline"
slug: dynamics-gp-to-sage-intacct-migration-data-mapping-timeline
date: 2026-06-22
author: Raaj
categories: [Microsoft Dynamics GP, Migration Guide, Sage Intacct]
excerpt: "Technical guide to migrating Dynamics GP to Sage Intacct: segment-to-dimension mapping, API rate limits, SQL extraction, and trial balance validation."
tldr: "Migrating GP to Intacct requires restructuring segmented accounts into dimensions, managing API rate limits by tier, and validating trial balances to the penny."
canonical: https://clonepartner.com/blog/dynamics-gp-to-sage-intacct-migration-data-mapping-timeline/
---

# Dynamics GP to Sage Intacct Migration: Data Mapping & Timeline


Migrating from Microsoft Dynamics GP to Sage Intacct is not a lift-and-shift. It is a structural transformation from an on-premise SQL Server database with segmented accounts to a cloud-native, API-driven platform built on dimensional accounting. If you treat this as a simple CSV export-and-import, your general ledger will not balance, your segment-based reports will break, and your finance team will spend weeks reconciling in spreadsheets.

The real design question is: what moves as master data, what moves as open subledger detail, what becomes summarized history, and how do GP account segments turn into Intacct dimensions without breaking the trial balance.

This guide covers the architectural differences, object-by-object data mapping from GP SQL tables to Intacct objects, API constraints, migration approaches with honest trade-offs, and the step-by-step process for extracting, transforming, and loading financial data. For the broader context of how ERP data migrations go wrong, see [Why ERP Migrations Fail at the Data Layer: 9 Core Patterns](https://clonepartner.com/blog/blog/why-erp-migrations-fail-at-the-data-layer-9-core-patterns/).

## Dynamics GP End of Life: Why Teams Are Moving Now

Microsoft Dynamics GP support for product enhancements, tax and regulatory updates, and technical support officially ends on **December 31, 2029**. Security updates will continue until **April 30, 2031**. After that, GP becomes a frozen codebase running at your own risk — no payroll updates, no tax table changes, no new features. ([learn.microsoft.com](https://learn.microsoft.com/en-us/dynamics-gp/))

Fewer consultants specialize in GP each year. As demand decreases, expertise becomes harder to find and more expensive. Waiting until 2028 to start planning means competing with every other GP shop for limited migration resources.

The three most common reasons we see teams choosing Sage Intacct over other targets:

- **Multi-entity consolidation.** GP treats each company database as isolated. Intacct provides native multi-entity consolidation with intercompany eliminations.
- **Dimensional accounting.** GP forces reporting dimensions into account segments. Intacct separates them into true dimensions — Location, Department, Project, and custom dimensions — that can be combined independently.
- **Cloud-native architecture.** No more SQL Server patching, VPN dependencies, or on-premise hosting costs.

For organizations considering the Microsoft path instead, see [Dynamics GP to Business Central: Migrating 20 Years of History](https://clonepartner.com/blog/blog/dynamics-gp-to-business-central-migrating-20-years-of-history/).

## Segmented Accounts vs. Dimensional Accounting

This is the core architectural shift that drives every decision in the migration.

Dynamics GP uses a **segmented chart of accounts**. A single account string can include up to 10 segments and 66 characters in any combination. This account framework is determined when GP is installed — Microsoft warns it is very difficult to change later. A typical GP account like `100-5010-300` embeds reporting meaning directly: segment 1 is division, segment 2 is natural account, segment 3 is department. ([learn.microsoft.com](https://learn.microsoft.com/en-us/dynamics-gp/installation/account-framework))

Sage Intacct uses a **dimensional data model**. The natural account (the GL Account ID) stands alone. Everything else becomes a separate dimension: Location, Department, Project, Class, or custom dimensions. ([developer.intacct.com](https://developer.intacct.com/api/platform-services/dimensions/)) That same GP account `100-5010-300` becomes:

- **GL Account:** 5010
- **Location dimension:** 100
- **Department dimension:** 300

This is a fundamental restructuring, not a renaming. You cannot perform a direct table-to-table copy. Every historical transaction must be parsed, split into its component parts, mapped to the correct dimension, and pushed through the Sage Intacct API.

For more on how dimensional accounting works in Intacct migrations, see [QuickBooks to Sage Intacct Migration: Multi-Entity & Dimension Mapping](https://clonepartner.com/blog/blog/quickbooks-to-sage-intacct-migration-multi-entity-dimension-mapping/).

## Migration Approaches

Engineering teams have four viable paths. Each has different scalability, risk, and engineering overhead.

### 1. Native CSV Import (Sage Intacct Templates)

**How it works:** Export data from GP using SmartLists or SQL queries into CSV files, then import using Sage Intacct's Company Setup Checklist templates.

**When to use it:** Small datasets (under 5,000 records per object), minimal historical GL, and teams with accounting staff who can manually validate.

**Pros:** Lowest build effort. No custom API code. Good for finance-led dry runs.

**Cons:** Weak for deep relational data. Manual cleanup scales poorly. Limited audit trail recreation.

**Risks:** CSV imports must be performed in a specific dependency order — if you import transactions that reference locations you have not created yet, the import fails. The maximum customer record count per CSV file is 25,000. Headers must match the Intacct template exactly, including spelling, capitalization, and spacing. Imports will reject Excel date formats that begin with an asterisk.

**Complexity:** Low.

> [!TIP]
> Normalize dates and currency values before your first mock load. GP SmartLists can export currency values with five decimal places, and Intacct import rejects Excel date formats that begin with `*`. ([learn.microsoft.com](https://learn.microsoft.com/en-us/troubleshoot/dynamics/gp/smartlist-and-navigation-lists-export-currency-values-with-5-decimals))

### 2. Direct Database to API Migration

**How it works:** Connect directly to the GP SQL Server database, extract data using SQL queries, transform in a middleware layer, and push to Sage Intacct via the XML Web Services API.

**When to use it:** Large datasets, complex segment-to-dimension transformations, repeatable mock migrations, or when you need programmatic control over data mapping.

**Pros:** Total control over data transformation. Strong repeatability. Better automated validation.

**Cons:** Highest engineering effort. Requires deep knowledge of both the GP SQL schema and the Intacct XML API. The XML API uses a highly specific schema — a single misplaced closing tag or incorrect element hierarchy returns a generic parsing error that is difficult to debug.

**Risks:** Sage Intacct requires a Web Services developer license for API access. XML calls should use sessions and the unique endpoint returned by `getAPISession`. The XML gateway enforces concurrency rules and 15-minute sender timeouts on large requests. Sage recommends keeping queries under 1,000 records and write requests under 100 affected records to avoid long-running timeouts. ([developer.intacct.com](https://developer.intacct.com/web-services/))

**Complexity:** High.

### 3. Third-Party Migration Tools

**How it works:** Use middleware tools like eOne Solutions' SmartConnect or CData connectors to map GP objects to Intacct objects with visual interfaces and pre-built templates.

**When to use it:** Mid-size migrations where the team has some technical capacity but not enough to build custom scripts from scratch.

**Pros:** Faster setup than custom code. Often includes retry and error review tools. Visual mapping reduces coding requirements.

**Cons:** Licensing costs can be high for a one-time migration. Pre-built connectors struggle with edge cases like partially applied AP payments, multi-currency revaluations, and custom GP fields that do not map to standard Intacct objects. Many vendors favor an archive-plus-opening-balance strategy rather than rebuilding every historical transaction in the target ERP — be explicit about whether you are buying a live historical reconstruction or an archive approach. ([eonesolutions.com](https://www.eonesolutions.com/solution/dynamics-gp-migration-to-oracle-netsuite/))

**Complexity:** Medium.

### 4. Custom ETL Pipeline

**How it works:** Using tools like Azure Data Factory or SSIS, data is extracted from GP, staged in a cloud data warehouse or staging schema, transformed with reusable crosswalk tables, and loaded into Intacct via APIs or import files.

**When to use it:** Multi-entity cutovers, repeated mock migrations, heavy customizations, or teams that need staging and full observability.

**Pros:** Clear separation of extract, transform, and load. Best option for rehearsals. Easier rollback logic.

**Cons:** Significant design overhead for a one-time migration asset. Still bound by Intacct's published query sizes, concurrency rules, and session handling. Over-engineering the solution delays the go-live date.

**Complexity:** High.

### Approach Comparison Table

| Approach | Best For | Scalability | Audit Trail | Engineering Effort | Risk Level |
| :--- | :--- | :--- | :--- | :--- | :--- |
| CSV Import | Master data, opening balances | Low (25K record cap per file) | Manual | Low | Medium |
| Direct SQL-to-API | Detail history, custom mapping | High | Programmatic | High | High |
| Third-Party Tools | Standard GP setups, low bandwidth | Medium | Partial | Medium | Medium |
| Custom ETL | Multi-entity, staged rehearsals | High | Programmatic | High | Medium |

**Recommendation by scenario:**

- **Summary history and open balances only:** Native CSV templates or ETL to summary journals, then keep GP read-only.
- **Open AR/AP plus recent detail history:** Direct API or managed service.
- **Low engineering bandwidth:** Third-party service or managed migration.
- **Heavy customizations or Analytical Accounting:** Custom ETL or an experienced managed team.
- **Fast, finance-grade cutover:** Managed service is usually the lowest-risk route.

## Why Choose a Managed Migration Service

Building a custom ETL pipeline for a one-time ERP migration is an inefficient use of engineering resources. A "simple" ETL script becomes a 3-month project when you factor in API error handling, retry logic, date formatting, concurrency management, sandbox testing, and the weeks of tie-out work that follow.

DIY ERP migrations fail at predictable points. The most common failures from [financial data migrations](https://clonepartner.com/blog/blog/financial-data-migration-mistakes-to-avoid/):

- **Unbalanced ledgers** from transactions that posted debits but dropped credits during transformation.
- **Broken vendor relationships** when vendor IDs in AP open transactions do not match the vendor master imported separately.
- **Compliance gaps** when audit trail detail is lost because only summary balances were migrated.
- **Orphaned references** that show up as aging reports that no longer agree to source, or journals that balance in total but not by reporting slice.

Do not build this in-house when the migration is one-time, your ERP footprint includes custom tables or add-ons, finance needs a clean cutover near month-end, or your senior engineers are already committed elsewhere. The hidden cost is not just code — it is weeks of tie-out work, re-runs, and incident handling after go-live.

ClonePartner handles complex ERP and financial data migrations as a point-in-time service. We do not build continuous sync bridges between GP and Intacct. We extract from GP, transform the data — including mapping segmented accounts to Intacct dimensions — load via the API with built-in concurrency and error handling, and validate with full trial balance tie-outs. We handle the relational complexity of AP, AR, GL, and subledger data so your engineering team stays focused on product work.

## Pre-Migration Planning

Before writing a single script, audit your GP database and lock down these decisions:

- **Chart of Accounts (GL00100):** Count active vs. inactive accounts. Identify which segments represent natural account, entity, department, project, product line, or something you should retire.
- **Vendor Master (PM00200):** Flag inactive vendors, duplicate records, vendors with zero open balances, and missing tax IDs.
- **Customer Master (RM00101):** Check for duplicate customer IDs and stale records.
- **Open AP Transactions (PM20000):** Identify partially applied payments and credit memos.
- **Open AR Transactions (RM20101):** Identify unapplied cash receipts and credit notes.
- **Historical GL (GL20000 / GL30000):** Decide how many fiscal years of detail to bring into Intacct.
- **Cutover model:** Big-bang over a weekend is standard for financial systems to prevent dual-entry errors.
- **Risk controls:** Full GP backup, sandbox dry runs, rollback criteria, named finance approvers.

> [!TIP]
> Most Intacct implementations only require 2 to 3 years of historical GL detail. Older history can be migrated as annual summary journal entries by account. Keep a read-only GP instance or SQL backup for audit access to older detail. Talk to your auditors about what they actually need before deciding scope.

**Data cleansing:** Purge obsolete records before migrating. Do not migrate vendors you have not paid in five years or inactive customers with zero balances.

**Migration scope:** Define exactly how many years of history to bring over. Most companies migrate two years of detail and five years of summary data.

For a comprehensive audit framework, see [Accounting Data Migration Checklist: The 10-Point Plan](https://clonepartner.com/blog/blog/accounting-data-migration-checklist-the-10-point-plan/).

## Data Model and Object Mapping

### Mapping GP Segments to Intacct Dimensions

A typical GP account like `6000-110-ATL-PRJ042` contains four segments:

- `6000` = natural expense account
- `110` = department
- `ATL` = entity or location
- `PRJ042` = project

In Sage Intacct, this becomes:

- **ACCOUNTNO:** 6000
- **DEPARTMENT:** 110
- **LOCATION:** ATL
- **PROJECT:** PRJ042

One GP account often becomes **one Intacct account plus several dimension values**, not one longer account string. Use a dimension only when the segment is a reporting axis the finance team will actually filter and group by after go-live. Everything else should be collapsed, retired, or preserved as reference data.

### Field-Level Mapping for Core Objects

**Customers:** GP stores customer data in `RM00101` (Customer Master) and `RM00102` (Customer Addresses). Map `CUSTNMBR` to Intacct `CUSTOMERID`, `CUSTNAME` to `NAME`. Intacct customer creation requires `NAME` and `DISPLAYCONTACT`. Preserve bill-to, ship-to, terms, currency, and tax behavior.

**Vendors:** GP stores vendor data in `PM00200` (Vendor Master) and `PM00300` (Vendor Address Master). Map `VENDORID` to Intacct `VENDORID`, `VENDNAME` to `NAME`. Preserve remit-to logic, terms, payment instructions, and 1099 type if applicable.

**Open AP:** GP's `PM20000` (Open Transactions) maps to Intacct's `APBILL` object. Each line must include the correct GL account and dimension values. Open AP records must reference vendor IDs that already exist in Intacct.

**Open AR:** GP's `RM20101` (Open Transactions) maps to Intacct's `ARINVOICE` object. Include apply-to references and preserve document numbers, due dates, and currency.

**Items:** GP's `IV00101` maps to Intacct's `ITEM`. Preserve `ITEMID`, `NAME`, and the target `ITEMTYPE` only if Intacct modules will actually use items after cutover.

**Historical GL:** GP's `GL20000` (current year) and `GL30000` (historical years) map to Intacct's `GLBATCH` and `GLENTRY` objects. If the business only needs comparative reporting, summarized monthly journals are usually the safer import shape. Large GL batches with thousands of lines can time out — split by period and reporting slice.

### Sample Data Mapping Table

| GP SQL Table | Description | Sage Intacct Object | Notes |
| :--- | :--- | :--- | :--- |
| `GL00100` | Account Master | `GLACCOUNT` | Split segments into dimensions |
| `GL00105` | Account Index Master | Staging join key | Resolve `ACTINDX` to formatted values before load |
| `GL20000` | Open Year GL Transactions | `GLBATCH` / `GLENTRY` | Current year journal entries |
| `GL30000` | Historical GL Transactions | `GLBATCH` / `GLENTRY` | Often summarized by period |
| `RM00101` | Customer Master | `CUSTOMER` | Load before open AR |
| `RM20101` | Open Receivables | `ARINVOICE` | Preserve document numbers and due dates |
| `PM00200` | Vendor Master | `VENDOR` | Load before open AP; map 1099 type |
| `PM20000` | Open Payables | `APBILL` | Must reference existing vendor IDs |
| `IV00101` | Item Master | `ITEM` | Only if Intacct modules will use items |
| `POP10100` | Purchase Order Work | `PODOCUMENT` | Only migrate open POs |

## Migration Architecture and API Constraints

The data flow is straightforward in concept: **Extract from GP SQL Server → Transform in a staging layer → Load via Intacct API.** The complexity is in the details.

### Sage Intacct API Rate Limits

Do not plan against third-party API numbers alone. Some secondary articles quote **1,296,000 requests per day** and **150 concurrent requests**. Current official Sage documentation describes **performance tiers** with monthly transaction entitlements and application/company concurrency. The default Performance Tier 1 allows **100,000 API transactions per month** and one concurrent offline process per company. Higher tiers scale up to millions of monthly transactions with increased concurrency. Treat the official tier documentation as the source of truth for planning. ([developer.sage.com](https://developer.sage.com/intacct/docs/1/sage-intacct-rest-api/api-essentials/txn-volume-concurrency-scaling))

A **429 error** indicates your API client has hit its assigned rate limit. Implement exponential backoff on 429 responses. Log every request and response for post-migration audit.

> [!WARNING]
> If you are on Performance Tier 1 (the default), 100,000 monthly transactions is not a lot for a migration that touches GL, AP, AR, vendors, customers, and items. Coordinate with Sage to temporarily upgrade your tier or schedule the migration during a low-usage window.

### Authentication and Session Management

The XML API requires two-level authentication: a **Web Services Sender ID** and password provisioned by Sage, plus a dedicated **Web Services user account** in the target company. Send a `getAPISession` request to get a session ID and unique endpoint, then make all subsequent requests with that session context. Do not mix `getAPISession` with other functions in the same request. ([developer.intacct.com](https://developer.intacct.com/api/company-console/api-sessions/))

In multi-entity setups, use `locationid` for entity-level sessions. Top-level queries do not return private-entity data unless `showprivate` is set to `true`.

### Batching and Payload Design

Batch journal entries into groups of 50 to 100 lines per request. Sage recommends keeping write requests under 100 affected records. With high concurrency, some requests will be held for approximately 5 seconds until prior requests complete, processed on a first-in, first-out basis.

Set `uniqueid` to `true` for idempotence on retried requests. Log every `controlid`, source key, payload checksum, and target record number. Do not auto-retry validation failures — route them to an exception queue.

REST is now generally available, and Sage recommends it for new client applications. For migration projects, the XML API often remains the more practical surface — it has more mature examples across sessions, GL batches, and legacy-only functions.

## Step-by-Step Migration Process

### Step 1: Extract Data from GP SQL Server

Query GP tables directly. Avoid the application layer where possible — SQL extraction is faster and more transparent for migration work. Build queries around stable keys like `ACTINDX` and `ACTNUMST`, not formatted spreadsheet text.

Extract the chart of accounts:

```sql
SELECT
  a.ACTINDX,
  a.ACTNUMST,
  a.ACTDESCR,
  a.ACCTTYPE,
  a.ACTIVE
FROM GL00100 a
WHERE a.ACTIVE = 1
ORDER BY a.ACTNUMST
```

Extract open AP transactions:

```sql
SELECT
  p.VENDORID,
  p.DOCNUMBR,
  p.DOCTYPE,
  p.DOCDATE,
  p.DOCAMNT,
  p.CURTRXAM,
  p.CURNCYID
FROM PM20000 p
WHERE p.CURTRXAM <> 0
```

Extract current-year GL detail:

```sql
SELECT
  a.ACTNUMST AS gp_account,
  t.JRNENTRY,
  t.TRXDATE,
  t.REFRENCE,
  t.DEBITAMT,
  t.CRDTAMNT
FROM GL20000 t
JOIN GL00100 a
  ON a.ACTINDX = t.ACTINDX
WHERE t.TRXDATE >= '2025-01-01'
```

### Step 2: Transform Data

- Parse GP account strings and split into natural account and candidate dimensions.
- Convert date formats to `mm/dd/yyyy`. The Sage Intacct XML API does not support ISO 8601 dates, and dates in the system do not carry timezone information.
- Map GP document types (1=Invoice, 2=Finance Charge, etc.) to Intacct transaction types.
- Remove commas from numeric fields for CSV imports.
- Sanitize special characters — Intacct XML does not support them.
- Keep crosswalk tables versioned so every dry run uses the same deterministic mapping rules.

### Step 3: Load into Sage Intacct in Dependency Order

Load in this sequence: **Dimensions and Locations → GL Accounts → Vendors and Customers → Open AP/AR Transactions → Historical Journal Entries.** Dependent objects must exist before you create the transactions that reference them.

Example XML payload for a GL batch:

```xml
<request>
  <control>
    <senderid>YOUR_SENDER_ID</senderid>
    <password>YOUR_SENDER_PASSWORD</password>
    <controlid>gp-cutover-001</controlid>
    <uniqueid>true</uniqueid>
    <dtdversion>3.0</dtdversion>
  </control>
  <operation transaction='false'>
    <authentication>
      <sessionid>YOUR_SESSION_ID</sessionid>
    </authentication>
    <content>
      <function controlid='create-glbatch-001'>
        <create>
          <GLBATCH>
            <JOURNAL>GJ</JOURNAL>
            <BATCH_DATE>06/30/2026</BATCH_DATE>
            <BATCH_TITLE>GP historical summary import</BATCH_TITLE>
            <ENTRIES>
              <GLENTRY>
                <ACCOUNTNO>6000</ACCOUNTNO>
                <TR_TYPE>1</TR_TYPE>
                <TRX_AMOUNT>1250.00</TRX_AMOUNT>
              </GLENTRY>
              <GLENTRY>
                <ACCOUNTNO>2100</ACCOUNTNO>
                <TR_TYPE>-1</TR_TYPE>
                <TRX_AMOUNT>1250.00</TRX_AMOUNT>
              </GLENTRY>
            </ENTRIES>
          </GLBATCH>
        </create>
      </function>
    </content>
  </operation>
</request>
```

Use `lookup` or `inspect` on your Intacct tenant to verify writable fields before hardcoding payloads. Add dimension elements based on the object definition in your specific company. ([developer.intacct.com](https://developer.intacct.com/api/general-ledger/journal-entries/))

### Step 4: Rebuild Open Balances

Import open AP and AR invoices as proper subledger objects — not as one lump journal entry. If finance needs aging and application behavior in Intacct, the invoices need to exist as `APBILL` and `ARINVOICE` records.

Import a **reversing journal entry** to offset the AP/AR control accounts so the GL balances correctly. Without this step, you will double-count your AP and AR balances in the general ledger.

> [!WARNING]
> Never migrate historical data and open balances in the same pass without offsetting your control accounts. Failure to do this will double-count your AP and AR balances in the general ledger.

### Step 5: Validate Financial Integrity

Run the trial balance in GP and in Intacct for the same date range. The totals must match to the penny. Any variance means a transaction was dropped, duplicated, or mapped to the wrong account.

## Edge Cases and Challenges

**Unbalanced journal entries.** GP sometimes allows out-of-balance entries — batch-level rounding, intercompany entries, or database corruption. The Intacct API will reject any journal entry where debits do not equal credits. Write logic to flag these entries and route them to a suspense account. Validate balance per batch and per reporting slice, not just at grand total. ([developer.intacct.com](https://developer.intacct.com/api/general-ledger/journal-entries/))

**Multi-currency conversions.** GP stores historical exchange rates in its multi-currency tables. If you push a foreign currency transaction into Intacct without the exact historical exchange rate, Intacct will use the current daily rate and alter your historical financials. Build your exchange rate table in Intacct before posting any foreign-currency transactions. Preserve the transaction currency, exchange rate date, and rate type.

**Multi-entity.** Entity-level sessions use `locationid`. Private entity data is excluded from top-level queries unless `showprivate` is enabled. Test this before assuming top-level API calls return all your data.

**Partially received Purchase Orders.** GP keeps PO and receipt history in separate table groups. Migrating open POs that have been partially received requires creating the PO in Intacct and immediately generating a partial receipt against it to match the GP state. Decide early whether procurement state is in scope or whether you are migrating only financial balances.

**Dirty exports.** GP SmartLists can export five-decimal currency amounts. Intacct XML does not support special characters in certain fields. Sanitize everything before loading.

## Limitations and Constraints

**API payload size.** You can encounter timeouts if you submit a particularly long request. The processing might still complete on the server side, but you will not receive an XML response. Keep payloads small and use `uniqueid=true` so you can safely retry without creating duplicates.

**Audit trail provenance.** Recreating exact GP audit trails in Intacct is not possible. GP stores a complete audit trail at the database level across work, open, and history tables. Intacct's audit trail is generated by the application layer. The Intacct record will show the API user as the creator, not the original GP user who entered the transaction in 2018. If auditors require original user attribution, append the legacy creator ID into a custom text field. You can preserve source document numbers, dates, amounts, and references, but not a byte-for-byte recreation of GP database history.

**Attachments.** The Sage Intacct API does not allow uploading attachments (like PDF invoices) in the same call as the transaction. Attachments require a separate API call to create the attachment folder and file, followed by a link to the transaction record.

Keep GP read-only for at least one full audit cycle if detail history was not fully migrated.

## Validation and Testing

The **trial balance tie-out** is the gate. If it fails, the migration is not done.

### Validation Checklist

1. **Trial balance tie-out** at the cutover date. Non-negotiable. Match to the penny by account, entity, and department.
2. **Record count comparison** for every migrated object — vendors, customers, GL accounts, open invoices. If you extracted 4,500 vendors from GP, query the Intacct API to confirm exactly 4,500 vendors exist.
3. **Hash totals** for key amount fields as a secondary check.
4. **Spot-check individual transactions.** Pick 20 random AP bills and 20 random AR invoices and verify amounts, dates, and dimensions match.
5. **Run aging reports** in both systems and compare.
6. **UAT with the finance team** in an Intacct sandbox environment before touching production. They will catch mapping errors that automated validation misses.

Run at least two full mock migrations in a sandbox environment. Validate incrementally — do not wait until all data is loaded to run the first trial balance. If UAT fails, wipe the sandbox and adjust the transformation scripts.

## Post-Migration Tasks

Once the production data is verified:

- **Lock historical periods** in Sage Intacct to prevent users from accidentally posting into closed years.
- **Set up reporting dashboards** in Intacct to replace GP Management Reporter layouts and SmartLists.
- **Train the finance team** on dimensional reporting — filtering by Location, Department, and Project instead of segment-based filtering.
- **Maintain a GP read-only instance** for at least one full audit cycle. If detail history was left behind, this is the original audit system of record.
- **Monitor downstream integrations** that read customer, vendor, item, or GL identifiers. Any system connected to GP needs to be repointed.

## Best Practices

- **Back up the GP database** before starting. Full database backup, not just table exports.
- **Run at least two mock migrations** in the Intacct sandbox before the production cutover.
- **Validate incrementally.** Validate after each object type loads, not at the end.
- **Coordinate the cutover window** with your month-end close. Do not migrate mid-month.
- **Document every mapping decision.** Your auditors will want to see how GP account `100-5010-300` became GL Account 5010 with Location 100 and Department 300.
- **Preserve source document numbers** wherever the target object allows it.
- **Split large journal history** into smaller balanced batches by period and reporting slice.
- **If detail history is not being recreated, say that explicitly in the project charter.** Do not let anyone discover this after go-live.

## Automation Script Outline

Keep the Python thin. Put business rules in versioned mapping tables, not hardcoded `if` chains. The important parts are deterministic transforms, idempotent API writes, and validation that finance can review.

```python
import pyodbc
import requests
import time
from xml.etree.ElementTree import Element, SubElement, tostring

# 1. Connect to GP SQL Server
def extract_gp_data(query, conn_string):
    conn = pyodbc.connect(conn_string)
    cursor = conn.cursor()
    cursor.execute(query)
    rows = cursor.fetchall()
    conn.close()
    return rows

# 2. Build Intacct XML payload
def build_intacct_request(sender_id, sender_pwd, session_id, functions):
    request = Element("request")
    control = SubElement(request, "control")
    SubElement(control, "senderid").text = sender_id
    SubElement(control, "password").text = sender_pwd
    SubElement(control, "controlid").text = "migration-batch-001"
    SubElement(control, "uniqueid").text = "true"
    SubElement(control, "dtdversion").text = "3.0"
    operation = SubElement(request, "operation")
    auth = SubElement(operation, "authentication")
    SubElement(auth, "sessionid").text = session_id
    content = SubElement(operation, "content")
    for func in functions:
        content.append(func)
    return tostring(request)

# 3. Send with retry logic
def post_to_intacct(xml_payload, endpoint, max_retries=3):
    for attempt in range(max_retries):
        response = requests.post(
            endpoint,
            data=xml_payload,
            headers={"Content-Type": "application/xml"}
        )
        if response.status_code == 429:
            time.sleep(2 ** attempt)  # Exponential backoff
            continue
        return response
    raise Exception("Max retries exceeded")

# 4. Validate record counts
def validate_counts(gp_count, intacct_count, object_name):
    if gp_count != intacct_count:
        raise Exception(
            f"Count mismatch for {object_name}: "
            f"GP={gp_count}, Intacct={intacct_count}"
        )

# 5. Migration orchestrator
def run_migration():
    gp_conn = "DRIVER={SQL Server};SERVER=gp_server;DATABASE=TWO;UID=user;PWD=password"

    # Extract
    accounts = extract_gp_data("SELECT * FROM GL00100 WHERE ACTIVE = 1", gp_conn)
    vendors = extract_gp_data("SELECT * FROM PM00200 WHERE VENDSTTS = 1", gp_conn)
    customers = extract_gp_data("SELECT * FROM RM00101", gp_conn)

    # Transform: split segments, map dimensions, format dates
    # Load: dimensions first, then masters, then transactions
    # Validate: trial balance tie-out
```

## What a Clean Cutover Looks Like

The cleanest GP-to-Intacct projects are rarely the ones that move the most rows. They are the ones that define scope early, separate natural accounts from reporting dimensions, load only the detail that the business will actually use, and prove the result with trial balance and aging tie-outs before go-live.

> Moving from Dynamics GP to Sage Intacct? ClonePartner handles the full migration: segment-to-dimension mapping, API payload management, trial balance tie-outs, and historical data transformation. We deliver accurate, point-in-time financial data migrations so your engineering team stays on product work. Book a 30-minute scoping call.
>
> [Talk to us](https://cal.com/clonepartner/meet?duration=30)

## Frequently asked questions

### When is the Microsoft Dynamics GP end of life?

Microsoft Dynamics GP support for product enhancements, regulatory updates, and technical support ends December 31, 2029. Security updates continue until April 30, 2031. After 2029, there will be no more payroll updates, tax table changes, or new features from Microsoft.

### What are the Sage Intacct API rate limits for data migration?

Sage Intacct uses performance tiers. The default Tier 1 allows 100,000 API transactions per month and one concurrent offline process. Higher tiers scale up significantly. Some secondary sources cite 1,296,000 requests per day and 150 concurrent requests, but the official tier documentation should be your source of truth. Exceeding your tier limit triggers a 429 error. Coordinate with Sage about a temporary tier upgrade before a large migration.

### How do you map Dynamics GP segments to Sage Intacct dimensions?

GP account segments like Division-Account-Department in format 100-5010-300 must be split apart. The natural account segment becomes the Intacct GL Account ID. Other segments like division and department become Intacct dimensions such as Location, Department, Project, or custom dimensions. This is a structural transformation, not a one-to-one rename.

### How long does a Dynamics GP to Sage Intacct migration take?

It depends on data volume and complexity. A migration with summary historical GL, under 500 vendors and customers, and no multi-currency can be completed in 1 to 2 weeks. Complex migrations with detail-level GL history, multi-entity consolidation, and open AP/AR typically take 3 to 6 weeks including testing and validation.

### Should I migrate all historical GL data from Dynamics GP to Sage Intacct?

Usually no. Most implementations migrate 2 to 3 years of detail-level journal entries. Older history is best brought over as summary annual journal entries by account. Keep a read-only GP instance or SQL backup so auditors can still access full historical detail.
