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) |
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 |
| 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 |
| 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 |
| 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 |
getNewUsersFromOffice365 operations — these require SUPER permission set which cannot be assigned to application users. [src3]Set-NAVServerConfiguration -EnableApiServices $true to enable API access. [src3]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
| 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 |
| 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" |
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.
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.
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.
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.
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".
// 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;
# 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
# 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}'
| 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) |
| 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 |
true/false or 1/0, not "Yes"/"No". [src5]| 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 |
Always validate package before applying. [src5]Exclude blank columns by deselecting in Fields page before import. [src7]Never delete columns — hide unwanted columns or exclude in Config. Package Fields. [src7]Adjust "Processing Order" in Config. Package Fields. [src7]Implement polling loop — check status every 2-5 seconds. [src3]Import No. Series table first or clear auto-numbering before master data import. [src8]// 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
// 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
// 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
// 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
// BAD — Apply without validate
// 500 records fail with cryptic errors, some partially applied
// Hours spent fixing data inconsistencies
// 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
Only use during initial company setup. For production, use XMLport or API v2.0. [src2]Always export current package as .rapidstart backup before applying. Test in sandbox first. [src5]Enable "Create Missing Codes" in Config. Package Fields for lookup fields. [src7]Import No. Series table first with appropriate starting numbers. [src8]Test final migration in production-equivalent environment. [src3]After applying, navigate to each journal and post imported entries. [src2]# 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*" }
| 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 |
| 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 |