Business Central Data Migration via RapidStart Services
How does Business Central data migration via RapidStart Services work?
TL;DR
- Bottom line: RapidStart Services is Business Central's built-in tool for initial company setup and data migration — use configuration packages to export/import setup tables and master data via Excel or .rapidstart files, but ONLY for new company initialization, never on production companies.
- Key limit: No hard record cap, but packages over ~50K records cause severe performance issues; importing blocks all users from the company during processing.
- Watch out for: Importing into a production company with active users will lock everyone out and can corrupt data — RapidStart is for greenfield setup only. Use XMLport for production data operations.
- Best for: New company setup, configuration replication across tenants, master data migration (customers, vendors, items, GL accounts) during initial go-live.
- Authentication: Configuration Worksheet and Package pages are in-app (BC client). Automation API uses OAuth 2.0 Bearer token for programmatic package upload/import/apply.
System Profile
Microsoft Dynamics 365 Business Central includes RapidStart Services as a built-in data migration and company configuration tool. It is available in both SaaS (Essentials and Premium editions) and on-premise deployments. RapidStart operates through configuration packages — bundles of table data that can be exported as .rapidstart compressed files or Excel workbooks, modified externally, and re-imported to populate a new company.
The tool consists of three core components: the Configuration Worksheet (organizes tables into areas and groups), Configuration Packages (the data containers exported/imported), and Configuration Templates (default field values applied to imported master data records). For automated multi-tenant provisioning, the Automation API (microsoft/automation namespace) provides REST endpoints to upload, import, and apply RapidStart packages programmatically.
| Property | Value |
|---|---|
| Vendor | Microsoft |
| System | Dynamics 365 Business Central v25/v26 (2024-2026) |
| Tool | RapidStart Services (Configuration Packages) |
| Automation API | microsoft/automation/v2.0/configurationPackages |
| Editions Covered | Essentials, Premium (SaaS); all on-premise editions |
| Deployment | Cloud (SaaS) + On-Premise |
| API Docs | Set Up Company Configuration Packages |
| Status | GA (General Availability) |
API Surfaces & Capabilities
RapidStart is not a traditional API — it is a data migration framework with multiple access surfaces.
| Surface | Protocol | Best For | Max Records/Batch | Rate Limit | Real-time? | Bulk? |
|---|---|---|---|---|---|---|
| Configuration Package (UI) | In-app (BC client) | Interactive setup, Excel-based migration | No hard limit (~50K practical) | N/A | No | Yes |
| .rapidstart File | XML compressed | Reusable package distribution between tenants | No hard limit | N/A | No | Yes |
| Excel Export/Import | XLSX via BC | Manual data entry/editing by consultants | No hard limit | N/A | No | Yes |
| Automation API (REST) | HTTPS/JSON + octet-stream | Automated tenant provisioning, CI/CD | Package-level | BC API limits | No (async) | Yes |
| AL Code (Codeunit 8620) | In-process | Extension-driven package application | Package-level | N/A | Sync or async | Yes |
| PowerShell (On-Prem) | Import-NAVConfigurationPackageFile | On-premise automation | Package-level | N/A | Sync | Yes |
Rate Limits & Quotas
Per-Operation Limits
| Limit Type | Value | Applies To | Notes |
|---|---|---|---|
| Max package file size (Automation API) | 350 MB | Automation API PATCH | BC max request body size |
| Max entities per OData page | 20,000 | Automation API GET | For status polling |
| Concurrent OData requests | 5 processing per user | Automation API | Queued requests wait up to 8 min |
| Operation timeout | 8 minutes | Import/Apply operations | 504 at 10 minutes |
| Practical record limit per package | ~50,000 | All surfaces | Performance degrades severely above this |
Session / Environment Limits
| Limit Type | Value | Window | Notes |
|---|---|---|---|
| Automation API rate limit | 6,000 requests per 5-min window | Rolling per user | Shared with all OData API calls |
| Speed limit (production) | 600 requests/minute | Per user | Applies to Automation API calls |
| Speed limit (sandbox) | 300 requests/minute | Per user | Lower in sandbox environments |
| Async task scheduler | 1 import/apply at a time | Per company | Subsequent calls fail until previous completes |
Authentication
| Flow | Use When | Token Lifetime | Refresh? | Notes |
|---|---|---|---|---|
| Interactive (BC Client) | Manual setup via Configuration Worksheet/Package pages | Session-based | Session | Most common for consultants |
| OAuth 2.0 Client Credentials (S2S) | Automated provisioning, CI/CD pipelines | ~1h | Yes | Requires Entra ID app; must be in AdminAgents group |
| OAuth 2.0 Authorization Code | User-context Automation API calls | Access: 1h, Refresh: until revoked | Yes | For interactive automation tools |
| PowerShell (On-Prem) | Server-side administration | Windows auth session | N/A | Import-NAVConfigurationPackageFile cmdlet |
Authentication Gotchas
- Automation API for delegated admins requires the Entra ID application to be added to the AdminAgents group — without this, the consent flow returns "Need pre-consent" error. [src3]
- S2S authentication does NOT support
getNewUsersFromOffice365operations — these require SUPER permission set which cannot be assigned to application users. [src3] - On-premise PowerShell requires
Set-NAVServerConfiguration -EnableApiServices $trueto enable API access. [src3]
Constraints
- Initial setup only: Configuration packages are NOT for production companies with active users — they block all user sessions during import. Use XMLport or API for production data operations.
- Posted entries excluded: You cannot import into tables containing posted entries (customer/vendor/item ledger entries, G/L entries). Journal lines can be imported but must be manually posted afterward.
- Schema match required: Source and target databases must have the same table structure, primary keys, field IDs, and data types.
- Special character limitation: The XML processor that generates .rapidstart files only accepts certain special characters — if removing a character creates duplicate names, export fails.
- Blank values overwrite: When updating existing records, blank columns in the import file REPLACE existing values with blanks.
- Async task serialization: Automation API import and apply operations are asynchronous; calling import while a previous apply is still running returns HTTP 400.
- No partial import: A package import is all-or-nothing at the table level.
- Direct permissions required: Import user must have Direct Insert and Direct Modify permissions on all target tables. Indirect permissions are insufficient.
Integration Pattern Decision Tree
START — User needs to migrate data into Business Central
|-- What's the scenario?
| |-- New company setup (greenfield)
| | |-- Data volume < 5,000 records?
| | | |-- YES -> Configuration Package via Excel (simplest)
| | | +-- NO -> Data volume < 50,000 records?
| | | |-- YES -> Configuration Package (.rapidstart file)
| | | +-- NO -> XMLport (RapidStart will be too slow)
| | +-- Need to replicate setup across multiple companies?
| | |-- YES -> Export .rapidstart, apply via Automation API
| | +-- NO -> Single package import via BC client
| |-- Multi-tenant provisioning (automated)
| | |-- Use Automation API workflow:
| | POST configurationPackages (create)
| | PATCH .../file/.../content (upload .rapidstart)
| | POST .../Microsoft.NAV.import (import — async)
| | Poll status until importStatus = "Completed"
| | POST .../Microsoft.NAV.apply (apply — async)
| | Poll status until applyStatus = "Completed"
| |-- Production company (already live)
| | +-- DO NOT use RapidStart -> Use XMLport or API v2.0
| +-- Legacy ERP migration (NAV, GP, SL, QuickBooks)
| |-- Supported migration tool available?
| | |-- YES -> Use cloud migration tools (not RapidStart)
| | +-- NO -> Export to Excel/CSV, map fields, import via Config Package
|-- Which data?
| |-- Setup tables -> Configuration Package (designed for this)
| |-- Master data -> Configuration Package + Configuration Templates
| |-- Opening balances -> Import journal lines via Config Package, then post
| +-- Transaction history -> CANNOT import via RapidStart
+-- Error tolerance?
|-- Zero-loss -> Validate Package before Apply, export backup first
+-- Best-effort -> Apply with Skip Table Triggers, fix errors post-import
Quick Reference
Configuration Package Workflow
| Step | Action | Page/Tool | Key Setting | Notes |
|---|---|---|---|---|
| 1 | Define package scope | Config. Worksheet or Config. Package Card | Table + field selection | Use "Get Tables" to auto-add by type |
| 2 | Add related tables | Config. Worksheet | "Get Related Tables" action | Conditional relations not auto-added |
| 3 | Select fields per table | Config. Package Fields | "Set Included" / "Clear Included" | Exclude calculated/system fields |
| 4 | Create templates | Configuration Templates | Default field values | Auto-applies defaults to imported records |
| 5 | Export to Excel | Config. Package Card | "Export to Excel" | One worksheet per table in package |
| 6 | Populate data in Excel | External (Excel) | Match column headers exactly | Do NOT add/remove/reorder columns |
| 7 | Import from Excel | Config. Package Card | "Import from Excel" | File must originate from BC export |
| 8 | Validate package | Config. Package Card | "Validate Package" action | Check for type mismatches, missing relations |
| 9 | Apply package | Config. Package Card | "Apply Package" action | Inserts/updates records into target tables |
| 10 | Post journals | General/Item/FA Journals | Manual posting | Opening balances require manual post |
Automation API Workflow
| Step | HTTP Method | Endpoint | Payload | Status Field |
|---|---|---|---|---|
| 1. Create package | POST | /configurationPackages | {"code":"PKG","packageName":"PKG"} | — |
| 2. Upload file | PATCH | /configurationPackages({id})/file('{code}')/content | Binary .rapidstart (octet-stream) | — |
| 3. Import | POST | /configurationPackages({id})/Microsoft.NAV.import | None | importStatus |
| 4. Poll import | GET | /configurationPackages({id}) | None | "Completed" / "InProgress" / "Error" |
| 5. Apply | POST | /configurationPackages({id})/Microsoft.NAV.apply | None | applyStatus |
| 6. Poll apply | GET | /configurationPackages({id}) | None | "Completed" / "InProgress" / "Error" |
Step-by-Step Integration Guide
1. Create and configure a configuration package
Open the Configuration Package page in Business Central (search for "Configuration Packages"). Create a new package with a code and add the tables you need to migrate. [src1]
// In Business Central client:
// 1. Search for "Configuration Packages"
// 2. Click + New
// 3. Set Code = "MIGRATE01", Package Name = "Initial Data Migration"
// 4. In Lines section, add tables:
// Table 18 (Customer), Table 23 (Vendor), Table 27 (Item),
// Table 15 (G/L Account), Table 308 (No. Series)
// 5. For each table, click Fields to select/deselect columns
// 6. Set "Skip Table Triggers" = Yes for legacy data
Verify: In the Config. Package Card, check that "No. of Tables" shows your expected count and "No. of Records" shows 0.
2. Export to Excel and populate data
Export the empty package structure to Excel, populate each worksheet with your migration data, then import back. [src4]
// Export:
// 1. On Config. Package Card, click Actions > Package > "Export to Excel"
// 2. Save the .xlsx file
// 3. Open in Excel — one sheet per table
// 4. Fill in rows (one row per record)
// IMPORTANT: Do NOT change column headers, order, or add new columns
// Import:
// 1. On Config. Package Card, click Actions > Package > "Import from Excel"
// 2. Select your populated .xlsx file
// 3. Check "No. of Package Records" to confirm import count
Verify: After import, "No. of Records" should match your Excel row counts. "No. of Package Errors" should be 0.
3. Validate the package
Before applying, always validate to catch data type mismatches, missing foreign key references, and constraint violations. [src2]
// 1. On Config. Package Card, click Actions > Functions > "Validate Package"
// 2. Wait for validation to complete
// 3. Check "No. of Package Errors" column
// 4. If errors exist, drill down on the error count
// 5. Common fixes:
// - Missing lookup values: enable "Create Missing Codes"
// - Type mismatches: fix in Excel and re-import
// - Length violations: truncate text fields
Verify: "No. of Package Errors" = 0 for all tables before proceeding to Apply.
4. Apply the package
Apply inserts/updates records into actual Business Central tables. Always export a backup first. [src2]
// 1. BACKUP: Export current package to .rapidstart file first
// 2. Click Actions > Functions > "Apply Package"
// 3. Confirm the apply action
// 4. Monitor progress — large packages may take several minutes
// 5. Check "No. of Package Errors" after apply completes
// 6. For any errors, drill down and fix inline or re-import
Verify: Navigate to Customer/Vendor/Item List to confirm records were created.
5. Automate via Automation API
For automated provisioning of multiple companies, use the Automation API. [src3]
# Step 1: Create the configuration package record
curl -X POST \
"https://api.businesscentral.dynamics.com/v2.0/{env}/api/microsoft/automation/v2.0/companies({companyId})/configurationPackages" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"code":"SETUP01","packageName":"Standard Setup"}'
# Step 2: Upload the .rapidstart file
curl -X PATCH \
"https://api.businesscentral.dynamics.com/v2.0/{env}/api/microsoft/automation/v2.0/companies({companyId})/configurationPackages({pkgId})/file('SETUP01')/content" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/octet-stream" \
-H "If-Match: *" \
--data-binary @setup01.rapidstart
# Step 3-6: Import, poll, apply, poll (see Quick Reference table)
Verify: GET the package status — both importStatus and applyStatus should be "Completed".
Code Examples
AL: Load and apply a RapidStart package from extension code
// Input: InStream containing a .rapidstart file
// Output: Package imported and applied to current company
procedure ImportAndApplyPackage(PackageStream: InStream)
var
ConfigPackageImport: Codeunit "Config. Package - Import";
ConfigPackage: Record "Config. Package";
ConfigPackageMgt: Codeunit "Config. Package Management";
TempBlob: Codeunit "Temp Blob";
OutStream: OutStream;
begin
TempBlob.CreateOutStream(OutStream);
CopyStream(OutStream, PackageStream);
ConfigPackageImport.ImportRapidStartPackageStream(TempBlob);
if ConfigPackage.FindLast() then begin
ConfigPackageMgt.ApplyPackage(ConfigPackage, ConfigPackage, true);
Message('Package %1 applied successfully.', ConfigPackage.Code);
end;
end;
PowerShell: On-Premise automated package import
# Input: .rapidstart file path, BC server instance
# Output: Package imported into target company
Import-Module "C:\Program Files\Microsoft Dynamics 365 Business Central\250\Service\NavAdminTool.ps1"
$BCServerInstance = "BC250"
$CompanyName = "CRONUS International Ltd."
$PackageFile = "C:\Migration\setup-package.rapidstart"
Set-NAVServerConfiguration -ServerInstance $BCServerInstance `
-KeyName ApiServicesEnabled -KeyValue true
Import-NAVConfigurationPackageFile -ServerInstance $BCServerInstance `
-CompanyName $CompanyName -Path $PackageFile -Force
cURL: Check Automation API package status
# Input: Valid OAuth 2.0 Bearer token, company ID
# Output: JSON with package import/apply status
curl -s -X GET \
"https://api.businesscentral.dynamics.com/v2.0/{env}/api/microsoft/automation/v2.0/companies({companyId})/configurationPackages" \
-H "Authorization: Bearer $TOKEN" \
| jq '.value[] | {code, packageName, importStatus, applyStatus, numberOfTables, numberOfErrors}'
Data Mapping
Mapping Resolution Priority
| Priority | Mapping Type | Description | Example |
|---|---|---|---|
| 1 | Direct field mapping | Explicit mapping on the field itself | Source "CustNo" -> BC "No." |
| 2 | Related table mapping | Mapping via primary key in related table | Source "PayTerms30" -> BC "30 DAYS" |
| 3 | Configuration template | Default values applied when no mapping exists | Country/Region Code defaults to "US" |
| 4 | No mapping | Field imported as-is (must match BC format) | Names, addresses (direct copy) |
Common Field Mapping Reference
| Source (Legacy/Excel) | Target (BC Table.Field) | Type | Transform | Gotcha |
|---|---|---|---|---|
| Customer Number | Customer."No." (18.1) | Code[20] | Direct | Max 20 chars — truncated silently |
| Customer Name | Customer.Name (18.2) | Text[100] | Direct | Max 100 chars in BC |
| Payment Terms | Customer."Payment Terms Code" (18.15) | Code[10] | Lookup | Must exist in Payment Terms table or enable "Create Missing Codes" |
| Currency | Customer."Currency Code" (18.26) | Code[10] | Lookup | Must exist in Currency table; blank = LCY |
| Item Number | Item."No." (27.1) | Code[20] | Direct | No. Series may conflict |
| Unit Price | Item."Unit Price" (27.18) | Decimal | Direct | Decimal separator must match BC locale |
| GL Account No | G/L Account."No." (15.1) | Code[20] | Direct | Chart of accounts must be set up first |
Data Type Gotchas
- Date formats: Excel date cells must use a recognized date format. Text-formatted dates cause "is not a valid date" errors. [src7]
- Decimal separators: BC uses the locale's decimal separator. Mismatched regional settings between Excel and BC corrupt amounts. [src5]
- Option fields (enums): Must import the integer value, not the display text (e.g., "Blocked" expects 0/1/2, not ""/Ship/All). [src7]
- Boolean fields: Import as
true/falseor1/0, not "Yes"/"No". [src5] - BLOB/media fields: Base64 encoded by default. If you edit in Excel, must manually convert back to base64 before import. [src1]
Error Handling & Failure Points
Common Error Codes
| Error | Meaning | Cause | Resolution |
|---|---|---|---|
| "XX is not a valid option" | Invalid option/enum value | Text value instead of integer | Use integer value from field metadata |
| "The field value is too long" | Field length exceeded | Source data exceeds BC field max length | Truncate data before import |
| Duplicate table/field name | XML serialization conflict | Special char removal creates name collisions | Rename conflicting fields before export |
| "The record already exists" | Primary key conflict | Record with same key already exists | Use "Delete Table Records Before Processing" or update |
| Validation sequence errors | Unexpected validation failures | Fields validated in wrong order | Uncheck "Validate Field" on problematic fields |
| HTTP 400 on API import/apply | Async task still running | Previous operation not completed | Poll status until "Completed" before next step |
| "Need pre-consent" | Missing admin group | Entra ID app not in AdminAgents group | Add app to AdminAgents group in Partner Center |
Failure Points in Production
- Silent value truncation: If "Validate Field" is unchecked, BC silently truncates long text. Fix:
Always validate package before applying.[src5] - Blank columns overwrite existing data: When updating records, blank cells replace existing values with blank/zero. Fix:
Exclude blank columns by deselecting in Fields page before import.[src7] - Deleted Excel columns cause import errors: Removing columns from the template breaks the expected schema. Fix:
Never delete columns — hide unwanted columns or exclude in Config. Package Fields.[src7] - Validation sequence causes cascading errors: Dependent fields validated before their dependencies trigger false errors. Fix:
Adjust "Processing Order" in Config. Package Fields.[src7] - Async API operations incomplete: Calling apply before import finishes returns HTTP 400. Fix:
Implement polling loop — check status every 2-5 seconds.[src3] - Number series conflicts: Imported master data numbers overlapping existing series ranges. Fix:
Import No. Series table first or clear auto-numbering before master data import.[src8]
Anti-Patterns
Wrong: Using RapidStart for ongoing production data loads
// BAD — RapidStart locks out all users during import
// Using configuration packages for weekly data loads in a live company
// Users can't log in, apply takes hours for large datasets, no rollback
Correct: Use XMLport or API v2.0 for production data operations
// GOOD — Use the right tool for production data
// XMLport: bulk, scheduled, runs via Job Queue, non-blocking
// API v2.0: real-time individual records, rate limited but non-blocking
Wrong: Importing all Excel columns including unused blanks
// BAD — All columns including blanks overwrites existing data
// Export 50 columns, fill only 10, leave 40 blank
// Result: 40 fields on every record are now blank/zero
Correct: Select only needed fields before export
// GOOD — Minimize field selection before export
// 1. Open Config. Package Fields, click "Clear Included"
// 2. Select ONLY the fields you will populate
// 3. THEN export to Excel — only selected fields are affected
Wrong: Skipping validation and applying directly
// BAD — Apply without validate
// 500 records fail with cryptic errors, some partially applied
// Hours spent fixing data inconsistencies
Correct: Always validate before applying
// GOOD — Validate first, fix errors, then apply
// 1. Validate Package 2. Review errors 3. Fix in Excel
// 4. Re-import and re-validate until 0 errors
// 5. Export backup .rapidstart 6. THEN Apply Package
Common Pitfalls
- Applying to production companies: RapidStart blocks all user sessions during import/apply. Even "small" imports lock users out. Fix:
Only use during initial company setup. For production, use XMLport or API v2.0.[src2] - No backup before apply: Apply is destructive with no built-in undo. Fix:
Always export current package as .rapidstart backup before applying. Test in sandbox first.[src5] - Ignoring "Create Missing Codes": Importing records referencing non-existent lookup values causes validation errors. Fix:
Enable "Create Missing Codes" in Config. Package Fields for lookup fields.[src7] - Number Series conflicts: Pre-assigned numbers overlapping existing series ranges. Fix:
Import No. Series table first with appropriate starting numbers.[src8] - Treating sandbox as production: Sandbox has lower speed limits (300 vs 600 req/min). Fix:
Test final migration in production-equivalent environment.[src3] - Forgetting to post journals: RapidStart imports journal lines but does NOT post them. Fix:
After applying, navigate to each journal and post imported entries.[src2]
Diagnostic Commands
# Check all configuration packages and their status
curl -s -X GET \
"https://api.businesscentral.dynamics.com/v2.0/{env}/api/microsoft/automation/v2.0/companies({companyId})/configurationPackages" \
-H "Authorization: Bearer $TOKEN" \
| jq '.value[] | {code, packageName, importStatus, applyStatus, numberOfErrors}'
# Check specific package status
curl -s -X GET \
"https://api.businesscentral.dynamics.com/v2.0/{env}/api/microsoft/automation/v2.0/companies({companyId})/configurationPackages({pkgId})" \
-H "Authorization: Bearer $TOKEN" \
| jq '{importStatus, applyStatus, importError, applyError}'
# Test authentication (list companies)
curl -s -X GET \
"https://api.businesscentral.dynamics.com/v2.0/{env}/api/microsoft/automation/v2.0/companies" \
-H "Authorization: Bearer $TOKEN" \
| jq '.value[] | {id, name, displayName}'
# PowerShell (on-premise): Check API settings
# Get-NAVServerConfiguration -ServerInstance BC250 | Where-Object { $_.Key -like "*Api*" }
Version History & Compatibility
| BC Version | Release Date | Status | RapidStart Changes | Notes |
|---|---|---|---|---|
| v26 (2025 Wave 1) | 2025-04 | Current | Automation API v2.0 improvements | Latest recommended |
| v25 (2024 Wave 2) | 2024-10 | Supported | Security groups replace user groups | AdminAgents group required |
| v24 (2024 Wave 1) | 2024-04 | Supported | Performance improvements | — |
| v22 (2023 Wave 1) | 2023-04 | EOL 2025-10 | — | Minimum for Automation API v2.0 |
| v16 (2020 Wave 1) | 2020-04 | EOL | Config. XML Exchange codeunit added | Key for AL-based package loading |
| v13 (2018) | 2018-10 | EOL | Codeunit 8620 refactored for InStream | Breaking change for existing AL code |
When to Use / When Not to Use
| Use When | Don't Use When | Use Instead |
|---|---|---|
| Setting up a new company for the first time | Company already in production with active users | XMLport or API v2.0 |
| Migrating master data during go-live | Migrating transaction history or posted entries | Journal imports for opening balances |
| Replicating setup across multiple companies | Ongoing scheduled data synchronization | API v2.0 webhooks + scheduled jobs |
| Automated tenant provisioning via Automation API | Real-time record-level integration | API v2.0 OData endpoints |
| Data volume under ~50,000 records per table | Data volume over 50,000 records per table | Custom XMLport |
| Legacy ERP migration (no direct tool exists) | Migrating from NAV, GP, SL, QuickBooks | Built-in cloud migration tools |
Important Caveats
- RapidStart Services blocks ALL other users from the company during package import and apply operations. Plan migration windows carefully.
- Configuration packages must match the target database schema exactly — different BC versions, extensions, or field IDs cause silent failures or data corruption. Always test in sandbox.
- Automation API import and apply operations are asynchronous. Calling the next step too early returns HTTP 400. Always poll status before proceeding.
- Blank cells in imported Excel files overwrite existing field values with blanks/zeros. Deselect fields you don't intend to update.
- RapidStart does NOT validate business logic if "Skip Table Triggers" is enabled. Data violating business rules will import without error but cause failures during normal operations.
- Opening balances imported via journal lines are NOT automatically posted. You must manually post after the package is applied.