# Microsoft Dynamics Business Central connector

Source: /docs/connectors/microsoft-dynamics-business-central.md

Use this as an implementation starting point: adapt the worked example to the requested dataset and the source documentation. See [Custom API](/docs/connectors/custom-api) for the shared SDK pattern and document-upload workflow.

## What this connector is for [#what-this-connector-is-for]

ERP records for financials, purchasing, inventory, sales orders, and operations.

Use this guide to choose the resources and row meanings for a Vortexify source integration. Connection ownership belongs to a connector; each dataset gets its own sync, configuration, and extraction behavior.

## Data and tables you can pull [#data-and-tables-you-can-pull]

The following table families are a starting point for source selection. They describe possible datasets to implement using the [vendor reference](https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/api-reference/v2.0/endpoints-apis-for-dynamics), not a guarantee that the example implements every table. Actual availability depends on the product edition, deployment, account permissions, and API/schema version.

| Suggested table | One row represents |
| --- | --- |
| `companies` | a company |
| `customers` | a customer |
| `vendors` | a vendor |
| `items` | a item |
| `sales_invoices` | a sales invoice |
| `general_ledger_entries` | a general ledger entry |

### Relationships and extraction considerations [#relationships-and-extraction-considerations]

These are proposed dataset names, not a universal schema guaranteed by the vendor. Preserve source object IDs and relationship references, and split nested child collections into separate tables when appropriate. Choose the concrete endpoint/report and row meaning from the vendor reference before implementing a sync.

## Connecting to Microsoft Dynamics Business Central [#connecting-to-microsoft-dynamics-business-central]

Use an authorized Microsoft Entra application, tenant/environment, company, and the Business Central API endpoint. API permission sets and company-level access must match the selected resources.

For HTTP reads, configure the connector client with the concrete API origin and source-authorized headers or authentication object. Actual credentials belong in platform secret configuration, not in this document or committed source.

### requirements.in [#requirementsin]

Declare these packages in the resource's `requirements.in`. Use the published `vortexify` package for the SDK and the source-specific driver/client shown below. Choose compatible dependency versions for your runtime; the [connector and sync reference](/docs/reference/python/connectors-and-syncs) explains where each file belongs.

```text
vortexify==0.1.1
pandas>=2,<3
httpx
```

This HTTP starting point needs no native database driver. Add the source-specific SDK, signer, or XML parser if the selected interface requires it.

## Worked example: customers [#worked-example-customers]

This read function demonstrates the request and row mapping for one resource. Pass the owning connector's configured `httpx.Client` and dataset settings as `config`. Use the API origin as the client base URL; the function supplies the resource path. Token acquisition, renewal, signing, or session login belongs in the connector. This example reads one response; extend its continuation rule for a full dataset.

### Source read [#source-read]

```python
import pandas as pd


def read_page(client, config):
    response = client.get(config["customers_path"], params={"$top": 100})
    response.raise_for_status()
    payload = response.json()
    if isinstance(payload, dict):
        if (
            payload.get("errors")
            or payload.get("success") is False
            or payload.get("ok") is False
            or payload.get("result_ok") is False
        ):
            raise ValueError("Source returned an application error")
    rows = payload["value"]
    if not isinstance(rows, list) or any(not isinstance(row, dict) for row in rows):
        raise ValueError("Expected the documented record array")
    return pd.json_normalize(rows)
```

### What to adapt [#what-to-adapt]

Set customers_path to /v2.0/{tenant}/{environment}/api/v2.0/companies({company_id})/customers at api.businesscentral.dynamics.com. Use Entra OAuth with the required company permissions. Follow @odata.nextLink.

Use the [custom API SDK starting point](/docs/connectors/custom-api#worked-example-cursor-paginated-json-records) to connect the read operation to `Connector` and `Sync`. For a source with its own driver, retain that client in `Connector.client()` and replace the HTTP request with the driver read. An `extract(*, avg_row_size_bytes=None)` implementation yields bounded DataFrames. An independent `preview()` uses a fresh connector and a small read; it must not call extraction or advance real state.

Choose explicit output columns and stable IDs for the requested table. The examples use `json_normalize` where useful to illustrate row shaping; nested arrays still need deliberate child tables and a stable declared output schema. A first-page sample is useful for development, while a full sync must follow all relevant continuation/parent-resource paths. Design incremental watermarks, update/deletion behavior, and rate-limit handling for the actual source before enabling incremental mode.

The purpose is to give a coding agent a concrete pattern to adapt, including for similar sources. These snippets are examples rather than a claim of complete vendor coverage. Check the [source operation reference](https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/api-reference/v2.0/api/dynamics_customer_get) and representative responses before running with a customer's account; live vendor execution has not been verified here.

## Sources and further reading [#sources-and-further-reading]

- [Vendor connection and resource reference](https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/api-reference/v2.0/api/dynamics_customer_get) — The interface/access prerequisites underlying this connection path; follow the selected resource's documentation for fields, queries, and pagination.
- [Vortexify connectors and syncs](/docs/reference/python/connectors-and-syncs) — Connector ownership, schemas, preview isolation, extraction, and checkpoint contracts.
- [Vortexify CLI workflow](/docs/reference/cli/overview) — Registering resources, committing source, and providing credential configuration.
