---
# === IDENTITY ===
id: business/erp-integration/dynamics-365-dmf-import-export/2026
canonical_question: "What is the Dynamics 365 Data Management Framework (DMF/DIXF) - file size limits, parallel processing?"
aliases:
  - "Dynamics 365 DMF data import export framework"
  - "D365 F&O DIXF data entities staging tables"
  - "Dynamics 365 Finance Operations data packages composite entities"
  - "D365 DMF recurring integrations REST API endpoints"
entity_type: erp_integration
domain: business > erp-integration > dynamics-365-dmf-import-export
region: global
jurisdiction: global
temporal_scope: 2024-2026

# === SYSTEM PROFILE ===
systems:
  - name: "Microsoft Dynamics 365 Finance & Operations"
    vendor: "Microsoft"
    version: "10.0.x (continuous release)"
    edition: "Finance, Supply Chain Management, Commerce, HR"
    deployment: cloud
    api_surface: "DMF/DIXF (Data Import/Export Framework)"

# === VERIFICATION ===
last_verified: 2026-03-01
confidence: 0.92
version: 1.0
first_published: 2026-03-01

# === TEMPORAL VALIDITY ===
temporal_validity:
  status: volatile
  last_breaking_change: "10.0.36 — user-based service protection API limits disabled by default and option removed"
  next_review: 2026-08-28
  change_sensitivity: high

# === CONSTRAINTS ===
constraints:
  - "Export file size: default 256 MB; increase to 5,000 MB by updating AzureStorageServiceVersion to 2019-12-12 in DMFPARAMETERS table"
  - "Parallel processing conflicts: files processed in parallel by default — enable sequential processing to avoid duplicate record lock errors"
  - "Composite entity import: ImportFromPackage supports composite entities but package must contain only ONE composite entity"
  - "Blob storage retention: exported files auto-deleted after 7 days from Azure Blob storage"
  - "Batch threads per AOS: default 8, max recommended 16 — exceeding 16 requires significant performance testing"
  - "DIXF/DMF exempt from service protection API limits — but OData endpoints used alongside are NOT exempt"
  - "SSIS dependency: DMF uses SQL Server Integration Services for staging — apostrophes in data project names cause failures when SSIS runs out-of-process"

# === SKIP CONDITIONS ===
skip_this_unit_if:
  - condition: "User needs real-time individual record operations via OData REST API"
    use_instead: "business/erp-integration/dynamics-365-web-api-capabilities/2026"
  - condition: "User needs bidirectional sync between F&O and Dataverse"
    use_instead: "business/erp-integration/dynamics-365-dual-write-capabilities/2026"
  - condition: "User needs virtual entity queries from Power Platform into F&O"
    use_instead: "business/erp-integration/dynamics-365-virtual-entities/2026"

# === AGENT HINTS ===
inputs_needed:
  - key: integration_pattern
    question: "What integration pattern do you need?"
    type: choice
    options:
      - "real-time sync (individual records, <1s latency)"
      - "batch/bulk (scheduled, high volume)"
      - "event-driven (webhook, CDC, platform events)"
      - "file-based (CSV/XML import/export)"
  - key: data_volume
    question: "What's your daily data volume?"
    type: choice
    options:
      - "< 1,000 records/day"
      - "1,000-100,000 records/day"
      - "> 100,000 records/day"
  - key: direction
    question: "What's the data flow direction?"
    type: choice
    options:
      - "inbound (writing to D365 F&O)"
      - "outbound (reading from D365 F&O)"
      - "bidirectional sync"

# === DISTRIBUTION ===
canonical_source: "https://knowledgelib.io/business/erp-integration/dynamics-365-dmf-import-export/2026"
suggested_citation: "Source: knowledgelib.io — AI Knowledge Library (verified 2026-03-01)"

# === RELATED UNITS ===
related_kos:
  depends_on:
    - id: "business/erp-integration/dynamics-365-authentication/2026"
      label: "Dynamics 365 authentication flows (OAuth 2.0, Entra ID)"
  related_to:
    - id: "business/erp-integration/dynamics-365-web-api-capabilities/2026"
      label: "D365 F&O OData/REST API for real-time individual record operations"
    - id: "business/erp-integration/dynamics-365-dual-write-capabilities/2026"
      label: "Dual Write for bidirectional F&O-Dataverse sync"
  solves: []
  alternative_to:
    - id: "business/erp-integration/dynamics-365-dataverse-api-capabilities/2026"
      label: "Dataverse Web API — for Dataverse-native operations, not F&O data entities"
  often_confused_with:
    - id: "business/erp-integration/dynamics-365-dual-write-capabilities/2026"
      label: "Dual Write is real-time bidirectional sync; DMF is batch/file-based import/export"

# === SOURCES ===
sources:
  - id: src1
    title: "Data management overview - Finance & Operations"
    author: Microsoft
    url: https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/data-entities-data-packages
    type: official_docs
    published: 2026-01-14
    reliability: authoritative
  - id: src2
    title: "Data management package REST API - Finance & Operations"
    author: Microsoft
    url: https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/data-management-api
    type: official_docs
    published: 2026-01-20
    reliability: authoritative
  - id: src3
    title: "Recurring integrations - Finance & Operations"
    author: Microsoft
    url: https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/recurring-integrations
    type: official_docs
    published: 2026-01-20
    reliability: authoritative
  - id: src4
    title: "Service protection API limits - Finance & Operations"
    author: Microsoft
    url: https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/service-protection-api-limits
    type: official_docs
    published: 2026-01-20
    reliability: authoritative
  - id: src5
    title: "Data management error descriptions and known limitations"
    author: Microsoft
    url: https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/dm-error-descriptions
    type: official_docs
    published: 2025-10-15
    reliability: authoritative
  - id: src6
    title: "Throttling prioritization - Finance & Operations"
    author: Microsoft
    url: https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/priority-based-throttling
    type: official_docs
    published: 2026-01-20
    reliability: high
  - id: src7
    title: "Data task automation - Finance & Operations"
    author: Microsoft
    url: https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/data-task-automation
    type: official_docs
    published: 2025-09-01
    reliability: high
  - id: src8
    title: "Optimize data migration for finance and operations apps"
    author: Microsoft
    url: https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/sysadmin/optimize-data-migration
    type: official_docs
    published: 2025-08-15
    reliability: high
---

# Dynamics 365 Data Management Framework (DMF/DIXF): Import/Export Capabilities

## TL;DR

- **Bottom line**: DMF (Data Management Framework, formerly DIXF) is the primary batch/file-based integration mechanism for D365 F&O — use it for data migration, configuration transfer, and recurring file-based integrations via data entities and data packages. [src1]
- **Key limit**: Export file size caps at 256 MB by default (expandable to 5 GB); batch threads default to 8 per AOS (max 16 recommended); exported blobs auto-delete after 7 days. [src1, src5]
- **Watch out for**: Parallel processing is the default — multiple files with the same record cause lock conflicts; enable sequential processing for recurring jobs with overlapping records. [src3]
- **Best for**: High-volume batch imports/exports (thousands to millions of records), data migration projects, cross-environment configuration copy, and scheduled recurring integrations with external systems. [src1]
- **Authentication**: OAuth 2.0 via Microsoft Entra ID (formerly Azure AD) for cloud; AD FS for on-premises deployments. [src2]

## System Profile

Microsoft Dynamics 365 Finance & Operations (F&O) encompasses Dynamics 365 Finance, Supply Chain Management, Commerce, and Human Resources. The Data Management Framework (DMF) — historically known as DIXF (Data Import/Export Framework) — is the standard tool for bulk data import, export, and configuration transfer across these applications. DMF operates on a continuous release cadence (version 10.0.x) with monthly updates. [src1]

This card covers the cloud-deployed version of F&O. On-premises deployments support the same DMF Package REST API with minor differences (AD FS authentication, `/namespaces/AXSF` appended to base URL). The card does NOT cover Dynamics 365 Business Central, which has its own separate API surface. [src2]

| Property | Value |
|---|---|
| **Vendor** | Microsoft |
| **System** | Dynamics 365 Finance & Operations (10.0.x continuous release) |
| **API Surface** | DMF/DIXF — Data entities, Data packages, Recurring Integration REST API, Package REST API |
| **Current API Version** | Continuous (tied to platform updates, currently PU64+) |
| **Editions Covered** | Finance, Supply Chain Management, Commerce, Human Resources |
| **Deployment** | Cloud (primary), On-Premises (supported with limitations) |
| **API Docs URL** | [Data management overview](https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/data-entities-data-packages) |
| **Status** | GA — actively maintained, exempt from service protection API throttling |

## API Surfaces & Capabilities

D365 F&O provides multiple integration surfaces. DMF is the file/batch-oriented surface. This table maps where DMF fits alongside other APIs. [src1, src2, src3, src4]

| API Surface | Protocol | Best For | Max Records/Request | Rate Limit | Real-time? | Bulk? |
|---|---|---|---|---|---|---|
| DMF Package REST API | HTTPS/JSON + data packages | Large batch import/export via external scheduling | Unlimited (package-based) | Exempt from service protection limits | No | Yes |
| Recurring Integration API | HTTPS/REST (enqueue/dequeue/ack) | Scheduled recurring file exchange | Unlimited (file-based) | Exempt from service protection limits | No | Yes |
| OData v4 REST API | HTTPS/JSON | Individual record CRUD, queries | 10,000 per page ($top) | User-based: 6,000 req/5 min; Resource-based: dynamic | Yes | Limited |
| Dual Write | Real-time sync | Bidirectional F&O-Dataverse sync | Per-record event | N/A (infrastructure-managed) | Yes | No |
| Business Events | HTTPS webhook | Event-driven notifications | Per event | N/A | Yes | N/A |
| Virtual Entities | Dataverse API | Power Platform querying F&O data | Dataverse limits apply | Exempt from F&O limits when integration enabled | Yes | No |

## Rate Limits & Quotas

### DMF-Specific Limits

DMF and DIXF operations (including recurring integrations) are **exempt from service protection API limits**. However, OData endpoints used alongside DMF are subject to throttling. [src4]

| Limit Type | Value | Applies To | Notes |
|---|---|---|---|
| Export file size (default) | 256 MB | Data package exports | Default Azure Storage service version limitation [src5] |
| Export file size (max) | 5,000 MB (5 GB) | Data package exports | Set AzureStorageServiceVersion to 2019-12-12 in DMFPARAMETERS table [src5] |
| Blob storage retention | 7 days | All DMF exported/imported files | Files auto-deleted from Azure Blob after 7 days [src2] |
| Max batch threads per AOS | 8 (default), 16 (max recommended) | Parallel batch processing | Values above 16 require significant performance testing [src8] |
| Composite entity per package | 1 | ImportFromPackage API | Package with composite entity must contain only that one entity [src2] |
| SSIS memory | Process-dependent | Staging table operations | SSIS runs out-of-process by default to optimize memory; can be toggled via DMFExecuteSSISInProc flight [src1] |

### OData Service Protection Limits (for comparison)

These apply to OData REST operations but NOT to DMF/DIXF. [src4]

| Limit Type | Value | Window | Notes |
|---|---|---|---|
| Requests per user per web server | 6,000 | 5-min sliding window | Per user, per application ID, per web server |
| Combined execution time per user | 1,200 seconds (20 min) | 5-min sliding window | Across all requests from that user |
| Concurrent requests per user | 52 | Instantaneous | Maximum simultaneous requests |
| Resource utilization | Dynamic threshold | Instantaneous | CPU/memory-based; returns 429 when server resources exceeded |

### Priority-Based Throttling

For OData/custom service integrations (not DMF), administrators can set throttling priority (Low, Medium, High) per integration. Low-priority integrations throttle first. Configured via **Throttling configuration** in System Administration. [src6]

## Authentication

DMF uses the same authentication as all D365 F&O service endpoints. [src2, src3]

| Flow | Use When | Token Lifetime | Refresh? | Notes |
|---|---|---|---|---|
| OAuth 2.0 Client Credentials | Server-to-server integration (no user context) | Session-dependent | New token per request cycle | Register app in Entra ID; add to System admin > Microsoft Entra applications |
| OAuth 2.0 Authorization Code | User-context operations | Access: 1h, Refresh: until revoked | Yes | For interactive flows; less common with DMF |
| AD FS | On-premises deployments | AD FS-configured | Yes | Append `/namespaces/AXSF` to base URL |

### Authentication Gotchas

- **Client Credentials mapping**: When using Client Credentials Grant flow, the application must be registered in **System administration > Setup > Microsoft Entra applications** with appropriate user security mapping. Without this, API calls return 401. [src2]
- **Recurring job Entra ID binding**: Each recurring data job must have the Entra AD application ID explicitly configured and enabled in the job's authorization policy. The app ID is bound at job creation time. [src3]
- **On-premises URL difference**: On-premises deployments must append `/namespaces/AXSF` to the base URL for all DMF Package API calls. API names remain identical. [src2]

## Constraints
<!-- Agents: read this section before recommending any integration approach from this unit.
     These are hard constraints that must not be violated. -->

- **Export file size**: Default 256 MB cap. Must modify DMFPARAMETERS table to increase to 5 GB — no UI toggle exists. [src5]
- **Parallel processing default**: DMF processes files in parallel unless sequential processing is explicitly enabled. This causes record locking errors when multiple files contain the same record. [src3]
- **ImportFromPackage is NOT thread-safe**: Do NOT call ImportFromPackage() in parallel threads. It uses batch processing internally and parallel calls cause failures. [src2]
- **Composite entity limitation**: A data package containing a composite entity can only contain that single composite entity — no other entities allowed in the same package. [src2]
- **SSIS project name restriction**: DMF data project names containing apostrophes (') cause SSIS failures when running out-of-process. Remove apostrophes from project names. [src1]
- **Enhanced parallel package import**: Parallel package imports via recurring integration or package REST APIs require enabling the **Enhanced parallel package import** option in Data Management > Framework Parameters > Compatibility Options. [src3]
- **No on-premises support for recurring integration**: The recurring integration REST API (enqueue/dequeue/ack) is NOT supported on Dynamics 365 Finance + Operations (on-premises). Package API works on-premises. [src3]

## Integration Pattern Decision Tree

```
START -- User needs to exchange data with D365 F&O
|-- What's the integration pattern?
|   |-- Real-time (individual records, <1s latency)
|   |   |-- Need Dataverse bidirectional sync?
|   |   |   |-- YES -> Dual Write
|   |   |   '-- NO -> OData v4 REST API (individual record CRUD)
|   |   '-- Need event notifications?
|   |       |-- YES -> Business Events (webhook to Azure Service Bus, Event Grid, etc.)
|   |       '-- NO -> OData REST API polling (not recommended for high volume)
|   |-- Batch/Bulk (scheduled, high volume)
|   |   |-- Scheduling managed in F&O?
|   |   |   |-- YES -> Recurring Integration API (enqueue/dequeue/ack)
|   |   |   '-- NO -> DMF Package REST API (ImportFromPackage/ExportToPackage)
|   |   |-- Need XSLT transformation?
|   |   |   |-- YES -> Recurring Integration API (supports XSLT for XML)
|   |   |   '-- NO -> Either API works
|   |   '-- Data volume > 5 GB per file?
|   |       |-- YES -> Split into multiple packages; apply entity filters to reduce per-export size
|   |       '-- NO -> Single package sufficient
|   |-- Configuration copy
|   |   '-- Use DMF Data Packages (export from source environment, import to target)
|   '-- Data migration (initial load)
|       |-- < 100 entities -> Manual DMF import with data packages
|       '-- > 100 entities -> Data Task Automation with manifests via LCS
|-- Which direction?
|   |-- Inbound (writing to F&O) -> enqueue (Recurring) or ImportFromPackage (Package API)
|   |-- Outbound (reading from F&O) -> dequeue (Recurring) or ExportToPackage (Package API)
|   '-- Bidirectional -> separate inbound and outbound jobs; or consider Dual Write
'-- Need change tracking (delta only)?
    |-- YES -> Enable change tracking on data entities; use incremental export
    '-- NO -> Full export each run
```

## Quick Reference

### DMF Package REST API Endpoints

| Operation | Method | Endpoint | Payload | Notes |
|---|---|---|---|---|
| Get writable blob URL | POST | `/data/DataManagementDefinitionGroups/Microsoft.Dynamics.DataEntities.GetAzureWriteUrl` | `{"uniqueFileName":"<string>"}` | Returns BlobId and BlobUrl with SAS token [src2] |
| Import from package | POST | `/data/DataManagementDefinitionGroups/Microsoft.Dynamics.DataEntities.ImportFromPackage` | `{"packageUrl","definitionGroupId","executionId","execute","overwrite","legalEntityId"}` | Async version: ImportFromPackageAsync [src2] |
| Export to package | POST | `/data/DataManagementDefinitionGroups/Microsoft.Dynamics.DataEntities.ExportToPackage` | `{"definitionGroupId","packageName","executionId","reExecute","legalEntityId"}` | Async version: ExportToPackageAsync [src2] |
| Get export URL | POST | `/data/DataManagementDefinitionGroups/Microsoft.Dynamics.DataEntities.GetExportedPackageUrl` | `{"executionId":"<string>"}` | Returns BlobUrl with SAS token [src2] |
| Check execution status | POST | `/data/DataManagementDefinitionGroups/Microsoft.Dynamics.DataEntities.GetExecutionSummaryStatus` | `{"executionId":"<string>"}` | Returns: NotRun, Executing, Succeeded, PartiallySucceeded, Failed, Canceled [src2] |
| Get execution errors | POST | `/data/DataManagementDefinitionGroups/Microsoft.Dynamics.DataEntities.GetExecutionErrors` | `{"executionId":"<string>"}` | Returns JSON array of error messages [src2] |
| Get staging error file | POST | `/data/DataManagementDefinitionGroups/Microsoft.Dynamics.DataEntities.GetImportStagingErrorFileUrl` | `{"executionId","entityName"}` | Error file URL for source-to-staging failures [src2] |
| Generate target error keys | POST | `/data/DataManagementDefinitionGroups/Microsoft.Dynamics.DataEntities.GenerateImportTargetErrorKeysFile` | `{"executionId","entityName"}` | Returns true if errors exist; then call GetImportTargetErrorKeysFileUrl [src2] |

### Recurring Integration REST Endpoints

| Operation | Method | Endpoint | Notes |
|---|---|---|---|
| Enqueue (import) | POST | `/api/connector/enqueue/<activityID>?entity=<entityName>` | Pass data file as memory stream in body [src3] |
| Dequeue (export) | GET | `/api/connector/dequeue/<activityID>` | Returns data package; must acknowledge after download [src3] |
| Acknowledge | POST | `/api/connector/ack/<activityID>` | Include dequeue response body; unacknowledged messages re-appear every 30 min [src3] |
| Get message status | POST | `/data/DataManagementDefinitionGroups/Microsoft.Dynamics.DataEntities.GetMessageStatus` | `{"messageId":"<string>"}` | Statuses: Enqueued, Dequeued, Acked, Preprocessing, Processing, Processed, PreProcessingError, ProcessedWithErrors, PostProcessingFailed [src3] |

## Step-by-Step Integration Guide

### 1. Obtain an OAuth 2.0 Access Token

Register an application in Microsoft Entra ID and add it to D365 F&O via System administration > Microsoft Entra applications. Then obtain an access token using the Client Credentials flow. [src2]

```bash
# Input:  Entra ID tenant ID, client ID, client secret, D365 F&O resource URL
# Output: OAuth 2.0 access token

curl -X POST "https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "client_id={clientId}" \
  -d "client_secret={clientSecret}" \
  -d "scope=https://{d365-environment}.operations.dynamics.com/.default" \
  -d "grant_type=client_credentials"
```

**Verify**: Response contains `access_token` field with a JWT token.

### 2. Upload Data Package to Azure Blob Storage

Get a writable blob URL with an embedded SAS token, then upload your .zip data package. [src2]

```bash
# Input:  Access token, unique file name
# Output: BlobId and writable BlobUrl

# Step 2a: Get writable URL
curl -X POST "https://{d365-env}.operations.dynamics.com/data/DataManagementDefinitionGroups/Microsoft.Dynamics.DataEntities.GetAzureWriteUrl" \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{"uniqueFileName":"import-customers-2026-03-01.zip"}'

# Step 2b: Upload package to the returned BlobUrl
curl -X PUT "{BlobUrl}" \
  -H "x-ms-blob-type: BlockBlob" \
  --data-binary @import-customers-2026-03-01.zip
```

**Verify**: HTTP 201 response from Azure Blob upload.

### 3. Trigger Import from Package

Call ImportFromPackage with the package URL and data project name. The data project must be pre-created in the Data Management workspace. [src2]

```bash
# Input:  Access token, packageUrl (from step 2), data project name, legal entity
# Output: executionId (Job ID)

curl -X POST "https://{d365-env}.operations.dynamics.com/data/DataManagementDefinitionGroups/Microsoft.Dynamics.DataEntities.ImportFromPackage" \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "packageUrl": "{BlobUrl_from_step2}",
    "definitionGroupId": "CustomerImport",
    "executionId": "",
    "execute": true,
    "overwrite": true,
    "legalEntityId": "USMF"
  }'
```

**Verify**: Response returns `executionId` string. Use this to poll status.

### 4. Poll Execution Status

Poll GetExecutionSummaryStatus until the job completes. Implement exponential backoff between polls. [src2]

```bash
# Input:  Access token, executionId from step 3
# Output: Execution status (Succeeded, Failed, PartiallySucceeded, etc.)

curl -X POST "https://{d365-env}.operations.dynamics.com/data/DataManagementDefinitionGroups/Microsoft.Dynamics.DataEntities.GetExecutionSummaryStatus" \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{"executionId":"{executionId}"}'
```

**Verify**: `value` returns `Succeeded` when complete. If `Failed` or `PartiallySucceeded`, retrieve errors in step 5.

### 5. Retrieve Errors (if any)

Use GetExecutionErrors for general errors, or GetImportStagingErrorFileUrl for entity-specific staging failures. [src2]

```bash
# Input:  Access token, executionId
# Output: JSON array of error messages

curl -X POST "https://{d365-env}.operations.dynamics.com/data/DataManagementDefinitionGroups/Microsoft.Dynamics.DataEntities.GetExecutionErrors" \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{"executionId":"{executionId}"}'
```

**Verify**: Empty array `[]` means no errors. Non-empty array contains error descriptions per entity.

## Code Examples

### Python: Batch Import via DMF Package REST API

```python
# Input:  D365 F&O credentials, .zip data package file
# Output: Import execution result (success/failure with error details)

import requests
import time
import json

# Configuration
TENANT_ID = "your-tenant-id"
CLIENT_ID = "your-client-id"
CLIENT_SECRET = "your-client-secret"
D365_URL = "https://your-env.operations.dynamics.com"
LEGAL_ENTITY = "USMF"
DATA_PROJECT = "CustomerImport"

def get_access_token():
    """Obtain OAuth 2.0 token via Client Credentials flow."""
    url = f"https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token"
    data = {
        "client_id": CLIENT_ID,
        "client_secret": CLIENT_SECRET,
        "scope": f"{D365_URL}/.default",
        "grant_type": "client_credentials"
    }
    resp = requests.post(url, data=data)
    resp.raise_for_status()
    return resp.json()["access_token"]

def import_package(token, package_path):
    """Upload and import a data package via DMF REST API."""
    headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}

    # Step 1: Get writable blob URL
    unique_name = f"import-{int(time.time())}.zip"
    resp = requests.post(
        f"{D365_URL}/data/DataManagementDefinitionGroups/"
        "Microsoft.Dynamics.DataEntities.GetAzureWriteUrl",
        headers=headers,
        json={"uniqueFileName": unique_name}
    )
    resp.raise_for_status()
    blob_info = json.loads(resp.json()["value"])
    blob_url = blob_info["BlobUrl"]

    # Step 2: Upload package to blob
    with open(package_path, "rb") as f:
        upload_resp = requests.put(
            blob_url,
            headers={"x-ms-blob-type": "BlockBlob"},
            data=f
        )
        upload_resp.raise_for_status()

    # Step 3: Trigger import
    resp = requests.post(
        f"{D365_URL}/data/DataManagementDefinitionGroups/"
        "Microsoft.Dynamics.DataEntities.ImportFromPackage",
        headers=headers,
        json={
            "packageUrl": blob_url,
            "definitionGroupId": DATA_PROJECT,
            "executionId": "",
            "execute": True,
            "overwrite": True,
            "legalEntityId": LEGAL_ENTITY
        }
    )
    resp.raise_for_status()
    execution_id = resp.json()["value"]

    # Step 4: Poll for completion with exponential backoff
    wait_seconds = 5
    max_wait = 120
    while True:
        status_resp = requests.post(
            f"{D365_URL}/data/DataManagementDefinitionGroups/"
            "Microsoft.Dynamics.DataEntities.GetExecutionSummaryStatus",
            headers=headers,
            json={"executionId": execution_id}
        )
        status = status_resp.json()["value"]
        if status in ("Succeeded", "PartiallySucceeded", "Failed", "Canceled"):
            break
        time.sleep(min(wait_seconds, max_wait))
        wait_seconds *= 2

    # Step 5: Get errors if failed
    if status in ("Failed", "PartiallySucceeded"):
        err_resp = requests.post(
            f"{D365_URL}/data/DataManagementDefinitionGroups/"
            "Microsoft.Dynamics.DataEntities.GetExecutionErrors",
            headers=headers,
            json={"executionId": execution_id}
        )
        return {"status": status, "errors": err_resp.json()}

    return {"status": status, "execution_id": execution_id}

# Usage
token = get_access_token()
result = import_package(token, "customer-data.zip")
print(f"Import result: {result['status']}")
```

### cURL: Export Data Package

```bash
# Input:  Access token, pre-configured export data project name
# Output: Downloaded .zip data package

# Step 1: Trigger export
EXEC_RESPONSE=$(curl -s -X POST \
  "https://{d365-env}.operations.dynamics.com/data/DataManagementDefinitionGroups/Microsoft.Dynamics.DataEntities.ExportToPackage" \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "definitionGroupId": "CustomerExport",
    "packageName": "customer-export-2026-03.zip",
    "executionId": "",
    "reExecute": true,
    "legalEntityId": "USMF"
  }')

EXEC_ID=$(echo $EXEC_RESPONSE | jq -r '.value')

# Step 2: Poll status until Succeeded
while true; do
  STATUS=$(curl -s -X POST \
    "https://{d365-env}.operations.dynamics.com/data/DataManagementDefinitionGroups/Microsoft.Dynamics.DataEntities.GetExecutionSummaryStatus" \
    -H "Authorization: Bearer {access_token}" \
    -H "Content-Type: application/json" \
    -d "{\"executionId\":\"$EXEC_ID\"}" | jq -r '.value')
  echo "Status: $STATUS"
  [ "$STATUS" = "Succeeded" ] && break
  [ "$STATUS" = "Failed" ] && echo "Export failed" && exit 1
  sleep 10
done

# Step 3: Get download URL
DOWNLOAD_URL=$(curl -s -X POST \
  "https://{d365-env}.operations.dynamics.com/data/DataManagementDefinitionGroups/Microsoft.Dynamics.DataEntities.GetExportedPackageUrl" \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d "{\"executionId\":\"$EXEC_ID\"}" | jq -r '.value')

# Step 4: Download package
curl -o "customer-export.zip" "$DOWNLOAD_URL"
```

## Data Mapping

### DMF Architecture: Source to Target Flow

| Stage | What Happens | Format | Error Recovery |
|---|---|---|---|
| **Source file** | External system generates CSV/XML/Excel file | CSV, XML, Excel (14 formats supported) | Fix source file and re-upload |
| **Upload to blob** | File uploaded to Azure Blob storage via SAS URL | .zip data package | SAS token valid for limited time window |
| **Source to staging** | SSIS extracts data from file into staging tables | SQL staging tables | View staging errors via GetImportStagingErrorFileUrl |
| **Staging validation** | DMF validates data types, required fields, constraints | In-database | Edit staging records directly in UI, then re-run |
| **Staging to target** | Data entities map staging to production tables | Production tables | View errors via GenerateImportTargetErrorKeysFile |

### Entity Sequencing

Entities within a data package are organized into execution units, levels, and sequences. [src1]

| Concept | Purpose | Parallel? | Example |
|---|---|---|---|
| **Execution unit** | Independent processing groups | Yes — different execution units process in parallel | Unit 1: Tax codes; Unit 2: Tax exempt numbers |
| **Level** | Dependency ordering within an execution unit | No — levels process sequentially | Level 1: Sales tax codes; Level 2: Sales tax groups |
| **Sequence** | Order within a level | Sequential | Sequence 1: Tax code A; Sequence 2: Tax code B |

### Data Type Gotchas

- **Excel column type inference**: SSIS infers column types from the first few rows. If early rows have numeric strings (e.g., "001"), SSIS sets the column as numeric and strips leading zeros. Solution: use CSV format or set all Excel columns to Text. [src5]
- **Dummy cell padding**: Excel exports sometimes insert a dummy text cell to support >255 characters per column. This extra row causes import failures. Delete the dummy row before re-importing. [src1]
- **Formula-derived data**: Data derived from Excel formulas generates errors. Copy-paste as values before importing. [src5]
- **Date format sensitivity**: DMF respects the user's date format setting. Mismatched date formats (e.g., MM/DD/YYYY vs DD/MM/YYYY) cause silent data corruption, not errors. Always verify the import user's date format settings. [src5]

## Error Handling & Failure Points

### Common Error Codes

| Error | Meaning | Cause | Resolution |
|---|---|---|---|
| Failed to insert into staging | Duplicate record in staging table | Source file contains duplicate records | Remove duplicates from source file before import [src5] |
| Data value violates integrity constraints | Field validation failure | Required field missing, wrong data type, or referential integrity violation | Check field mapping and source data against entity schema [src5] |
| 429 Too Many Requests | Service protection limit exceeded | Too many OData API calls (NOT DMF — but common when mixing approaches) | Implement Retry-After backoff; DMF itself is exempt [src4] |
| SSIS failure with apostrophe | SSIS cannot parse project name | Data project name contains apostrophe (') | Remove apostrophe from project name or enable DMFExecuteSSISInProc flight [src1] |
| Entity not found | Entity not in selected files | Missing entity in data package manifest | Verify entity name matches manifest; regenerate mapping [src1] |
| Mapping mismatch after entity refresh | Auto-generated mapping is stale | Entity was extended (new fields added) but mapping not regenerated | Use Generate source mapping to rebuild mapping [src1] |

### Failure Points in Production

- **Parallel record lock conflicts**: When sequential processing is disabled (default), multiple files updating the same records cause lock contention errors. Fix: `Enable "Process messages in order" on the recurring data job`. [src3]
- **SAS token expiration**: GetAzureWriteUrl returns a time-limited SAS token. If upload takes too long, the token expires silently. Fix: `Request new SAS URL immediately before upload; don't cache URLs`. [src2]
- **Staging table data orphaning**: If an import fails at the staging-to-target step, records remain in the staging table. Subsequent reimports may create duplicates. Fix: `Clear staging data before reimporting, or use View staging data to edit and retry`. [src1]
- **OLEDB driver missing**: Excel-format imports fail silently if the Access Database Engine 2010 Redistributable (AccessDatabaseEngine_x64.exe) is not installed. Fix: `Install the OLEDB driver or use CSV format`. [src1]
- **Change tracking not enabled**: Incremental exports return full data sets if change tracking is not enabled on the data entity before the first export. Fix: `Enable change tracking on each entity AND select incremental push before the first run`. [src3]
- **Blob auto-deletion**: Exported files are auto-deleted from Azure Blob storage after 7 days. Fix: `Download exported packages promptly; implement automated download in integration pipeline`. [src2, src3]

## Anti-Patterns

### Wrong: Calling ImportFromPackage in Parallel Threads

```csharp
// BAD -- ImportFromPackage uses batch internally; parallel calls cause failures
Parallel.ForEach(packages, package => {
    client.ImportFromPackage(package.Url, projectName, "", true, true, "USMF");
});
```

### Correct: Sequential ImportFromPackage with Parallel Internal Processing

```csharp
// GOOD -- call ImportFromPackage sequentially; it handles parallelism internally via batch
foreach (var package in packages) {
    var executionId = await client.ImportFromPackageAsync(
        package.Url, projectName, "", true, true, "USMF");
    await PollUntilComplete(executionId);
}
```

[src2]

### Wrong: Ignoring Dequeue Acknowledgment

```python
# BAD -- without ack, same message re-appears every 30 minutes
response = requests.get(f"{base_url}/api/connector/dequeue/{activity_id}",
    headers=headers)
data = response.content
process_data(data)
# Missing: acknowledge the message
```

### Correct: Always Acknowledge After Successful Dequeue

```python
# GOOD -- acknowledge immediately after successful download
response = requests.get(f"{base_url}/api/connector/dequeue/{activity_id}",
    headers=headers)
data = response.content
process_data(data)
# Acknowledge to remove from queue
requests.post(f"{base_url}/api/connector/ack/{activity_id}",
    headers=headers, data=response.content)
```

[src3]

### Wrong: Using DMF for Real-Time Individual Record Operations

```python
# BAD -- DMF is designed for batch operations, not real-time
# This creates massive overhead for single record updates
def update_single_customer(customer_data):
    package = create_package_for_one_record(customer_data)
    upload_to_blob(package)
    import_from_package(package)
    poll_until_complete()
```

### Correct: Use OData for Real-Time, DMF for Batch

```python
# GOOD -- use OData for single-record real-time operations
def update_single_customer(customer_data):
    requests.patch(
        f"{D365_URL}/data/CustomersV3('{customer_data['id']}')",
        headers=headers, json=customer_data)

# Use DMF for bulk/batch operations
def import_bulk_customers(file_path):
    package = create_package(file_path)
    import_from_package(package)
```

## Common Pitfalls

- **Not pre-creating the data project**: Both ImportFromPackage and ExportToPackage require a pre-existing data project in the Data Management workspace. API calls fail if the project doesn't exist. Fix: `Create the data project via the D365 F&O UI before calling the REST API`. [src2]
- **Ignoring entity sequence dependencies**: Importing sales tax groups before sales tax codes fails due to referential dependencies. Fix: `Set correct execution unit, level, and sequence numbers; use Microsoft-provided data packages from LCS as reference`. [src1]
- **Not using change tracking for delta exports**: Without change tracking enabled, every export retrieves the full dataset, wasting bandwidth and processing time. Fix: `Enable change tracking per entity before the first export; select incremental push in the recurring job configuration`. [src3]
- **Skipping staging for complex entities**: Disabling staging ("Skip staging" option) bypasses validation and error recovery capabilities. Fix: `Only skip staging for simple, well-validated data. Keep staging enabled for complex entities to allow error inspection and correction`. [src1]
- **Hardcoding SAS token lifetimes**: SAS tokens from GetAzureWriteUrl have an expiry window. Caching URLs between requests risks upload failures. Fix: `Always request a fresh SAS URL immediately before each upload operation`. [src2]
- **Mixing entity names and labels**: DMF uses entity names internally (e.g., "CustCustomerV3Entity") but the UI shows labels (e.g., "Customers V3"). API calls require the correct name format. Fix: `Use the entity label for enqueue API's entity parameter; use the data project's definitionGroupId for Package API`. [src1, src3]

## Diagnostic Commands

```bash
# Check execution status for a specific job
curl -X POST "https://{d365-env}.operations.dynamics.com/data/DataManagementDefinitionGroups/Microsoft.Dynamics.DataEntities.GetExecutionSummaryStatus" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"executionId":"{executionId}"}'

# Get error details for a failed import
curl -X POST "https://{d365-env}.operations.dynamics.com/data/DataManagementDefinitionGroups/Microsoft.Dynamics.DataEntities.GetExecutionErrors" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"executionId":"{executionId}"}'

# Get staging error file URL for a specific entity
curl -X POST "https://{d365-env}.operations.dynamics.com/data/DataManagementDefinitionGroups/Microsoft.Dynamics.DataEntities.GetImportStagingErrorFileUrl" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"executionId":"{executionId}","entityName":"{entityName}"}'

# Check message status for recurring integration
curl -X POST "https://{d365-env}.operations.dynamics.com/data/DataManagementDefinitionGroups/Microsoft.Dynamics.DataEntities.GetMessageStatus" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"messageId":"{messageId}"}'

# Get execution ID from enqueued message ID
curl -X POST "https://{d365-env}.operations.dynamics.com/data/DataManagementDefinitionGroups/Microsoft.Dynamics.DataEntities.GetExecutionIdByMessageId" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"_messageId":"{messageId}"}'
```

## Version History & Compatibility

| Platform Update | Release | Status | Key Changes | Notes |
|---|---|---|---|---|
| PU64+ | 2025-2026 | Current | Automatic retry for recurring data jobs during batch node restarts; SysIntegrationActivityBatch redesign (child job pattern) | Custom code using SysIntegrationActivityBatch must update to new child job pattern [src3] |
| 10.0.36 | 2024 | Supported | User-based service protection API limits disabled on all environments; option to enable removed | Resource-based limits remain active [src4] |
| 10.0.35 | 2024 | Supported | User-based API limits disabled by default but optionally enabled | [src4] |
| 10.0.33 | 2023 | Supported | User-based service protection API limits originally planned as mandatory; later reversed | [src4] |
| 10.0.19 | 2021 | EOL | Resource-based service protection API limits introduced | First throttling layer for F&O [src4] |
| PU12 | 2018 | EOL | GetMessageStatus API added; Prevent upload when zero records | [src3] |
| PU5 | 2017 | EOL | Data Management Package REST API introduced | Initial DMF REST API [src2] |

### Deprecation Policy

Microsoft follows a continuous release model for D365 F&O with monthly updates. Platform features may be deprecated with a minimum 12-month notice via the "Removed or deprecated features" documentation. DMF/DIXF has been exempt from service protection API limits since introduction — any change to this exemption would be announced in advance. [src4]

## When to Use / When Not to Use

| Use When | Don't Use When | Use Instead |
|---|---|---|
| Bulk data migration (thousands to millions of records) | Real-time individual record CRUD with <1s latency | OData v4 REST API |
| Configuration copy between environments | Bidirectional real-time sync with Dataverse | Dual Write |
| Recurring scheduled file-based integrations | Event-driven notifications on record changes | Business Events |
| Initial data load for new implementations | Power Platform apps querying F&O data | Virtual Entities |
| Multi-entity data packages with sequencing | Simple single-record lookups | OData $filter queries |
| XSLT transformation required on inbound data | Sub-second integration response times | Custom OData actions |

## Important Caveats

- DMF and DIXF recurring integrations are currently **exempt from service protection API limits**, but Microsoft has stated that exemptions may be removed with advance notice. Monitor the official documentation for changes. [src4]
- The continuous release model means DMF behavior can change with any monthly update. Always test after platform updates, especially custom code that extends SysIntegrationActivityBatch. [src3]
- On-premises deployments do NOT support recurring integration REST endpoints (enqueue/dequeue/ack). Only the Package REST API (ImportFromPackage/ExportToPackage) works on-premises. [src3]
- The PU64 redesign of SysIntegrationActivityBatch (child job pattern) is a **breaking change for custom extensions**. Custom batch tasks must now be added to the child job (Job2), not the parent job (Job1). [src3]
- File format support: DMF supports 14 different formats for export, but CSV and XML are the most reliable for programmatic integrations. Excel format requires OLEDB driver installation and has column type inference issues. [src1]

## Related Units

- [Dynamics 365 authentication flows (OAuth 2.0, Entra ID)](/business/erp-integration/dynamics-365-authentication/2026)
- [D365 F&O OData/REST API capabilities](/business/erp-integration/dynamics-365-web-api-capabilities/2026)
- [Dual Write for bidirectional F&O-Dataverse sync](/business/erp-integration/dynamics-365-dual-write-capabilities/2026)
- [Dataverse Web API capabilities](/business/erp-integration/dynamics-365-dataverse-api-capabilities/2026)
