> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreflux.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Dynamics 365 Dataverse Web API

> Client-mode REST API connector for a curated Dataverse Web API subset: WhoAmI, accounts, contacts, and entity metadata

Technical Preview

## Overview

A client-mode connector for a **curated eight-operation** slice of the [Dataverse Web API](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/webapi/overview) used by Dynamics 365 / Power Platform: WhoAmI, account CRUD helpers, contacts, and EntityDefinitions. It is meant for ERP/CRM edge bridges, not the full Dynamics surface. Set `BASE_ADDRESS` to the **customer org** URL (for example `https://contoso.crm.dynamics.com`, or `.crm4.dynamics.com` for many EU tenants).

> [!NOTE]
>
> Dataverse requires an Azure AD Bearer access token for the org resource. A placeholder org host does not resolve. Unauthenticated global discovery returns HTTP 400 without a tenant. This template has not been verified with a real org token.

## Basic Syntax

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
# Coreflux REST_API template — Dynamics 365 (Dataverse Web API)
# Generated from curated OpenAPI; credentials are placeholders only.
# Docs: https://docs.coreflux.org/latest/lot-language/routes/rest-api-routes
# Auth: Azure AD Bearer via {value.json.api_token}. Prefer Hub secrets / GET SECRET.
# BASE_ADDRESS: replace YOUR_ORG (and region: .crm / .crm4 / etc.) with the customer org URL.

DEFINE ROUTE Dynamics365RestApi WITH TYPE REST_API
    ADD REST_API_CONFIG
        WITH BASE_ADDRESS "https://YOUR_ORG.crm.dynamics.com"
        WITH ENABLE_CLIENT "true"
        WITH USE_SSL "true"
        WITH REQUEST_TIMEOUT '30'
        WITH DEFAULT_CONTENT_TYPE "application/json"
        # Auth: Azure AD access token for the Dataverse org resource as Bearer.
        # Prefer Hub secrets / GET SECRET upstream — never commit real tokens.
        # EU orgs often use https://YOUR_ORG.crm4.dynamics.com (set BASE_ADDRESS to match).
    ADD EVENT Whoami
        WITH SOURCE_TOPIC "integrations/dynamics365/request/Whoami"
        WITH DESTINATION_TOPIC "integrations/dynamics365/response/Whoami"
        WITH METHOD "GET"
        WITH ENDPOINT "/api/data/v9.2/WhoAmI"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "OData-MaxVersion" "4.0"
            ADD "OData-Version" "4.0"
            ADD "Prefer" "odata.include-annotations=\"*\""
            ADD "Authorization" "Bearer {value.json.api_token}"
    ADD EVENT Listaccounts
        WITH SOURCE_TOPIC "integrations/dynamics365/request/Listaccounts"
        WITH DESTINATION_TOPIC "integrations/dynamics365/response/Listaccounts"
        WITH METHOD "GET"
        WITH ENDPOINT "/api/data/v9.2/accounts"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "OData-MaxVersion" "4.0"
            ADD "OData-Version" "4.0"
            ADD "Prefer" "odata.include-annotations=\"*\""
            ADD "Authorization" "Bearer {value.json.api_token}"
    ADD EVENT Createaccount
        WITH SOURCE_TOPIC "integrations/dynamics365/request/Createaccount"
        WITH DESTINATION_TOPIC "integrations/dynamics365/response/Createaccount"
        WITH METHOD "POST"
        WITH ENDPOINT "/api/data/v9.2/accounts"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Content-Type" "application/json"
            ADD "OData-MaxVersion" "4.0"
            ADD "OData-Version" "4.0"
            ADD "Prefer" "odata.include-annotations=\"*\""
            ADD "Authorization" "Bearer {value.json.api_token}"
        WITH BODY "{payload}"
    ADD EVENT Getaccount
        WITH SOURCE_TOPIC "integrations/dynamics365/request/Getaccount"
        WITH DESTINATION_TOPIC "integrations/dynamics365/response/Getaccount"
        WITH METHOD "GET"
        WITH ENDPOINT "/api/data/v9.2/accounts({value.json.accountid})"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "OData-MaxVersion" "4.0"
            ADD "OData-Version" "4.0"
            ADD "Prefer" "odata.include-annotations=\"*\""
            ADD "Authorization" "Bearer {value.json.api_token}"
    ADD EVENT Updateaccount
        WITH SOURCE_TOPIC "integrations/dynamics365/request/Updateaccount"
        WITH DESTINATION_TOPIC "integrations/dynamics365/response/Updateaccount"
        WITH METHOD "PATCH"
        WITH ENDPOINT "/api/data/v9.2/accounts({value.json.accountid})"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Content-Type" "application/json"
            ADD "OData-MaxVersion" "4.0"
            ADD "OData-Version" "4.0"
            ADD "Prefer" "odata.include-annotations=\"*\""
            ADD "Authorization" "Bearer {value.json.api_token}"
        WITH BODY "{payload}"
    ADD EVENT Listcontacts
        WITH SOURCE_TOPIC "integrations/dynamics365/request/Listcontacts"
        WITH DESTINATION_TOPIC "integrations/dynamics365/response/Listcontacts"
        WITH METHOD "GET"
        WITH ENDPOINT "/api/data/v9.2/contacts"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "OData-MaxVersion" "4.0"
            ADD "OData-Version" "4.0"
            ADD "Prefer" "odata.include-annotations=\"*\""
            ADD "Authorization" "Bearer {value.json.api_token}"
    ADD EVENT Getcontact
        WITH SOURCE_TOPIC "integrations/dynamics365/request/Getcontact"
        WITH DESTINATION_TOPIC "integrations/dynamics365/response/Getcontact"
        WITH METHOD "GET"
        WITH ENDPOINT "/api/data/v9.2/contacts({value.json.contactid})"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "OData-MaxVersion" "4.0"
            ADD "OData-Version" "4.0"
            ADD "Prefer" "odata.include-annotations=\"*\""
            ADD "Authorization" "Bearer {value.json.api_token}"
    ADD EVENT Listentitydefinitions
        WITH SOURCE_TOPIC "integrations/dynamics365/request/Listentitydefinitions"
        WITH DESTINATION_TOPIC "integrations/dynamics365/response/Listentitydefinitions"
        WITH METHOD "GET"
        WITH ENDPOINT "/api/data/v9.2/EntityDefinitions"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "OData-MaxVersion" "4.0"
            ADD "OData-Version" "4.0"
            ADD "Prefer" "odata.include-annotations=\"*\""
            ADD "Authorization" "Bearer {value.json.api_token}"
```

## Events

| Event | Method | Endpoint | Request topic | Response topic |
| - | - | - | - | - |
| Whoami | GET | `/api/data/v9.2/WhoAmI` | `integrations/dynamics365/request/Whoami` | `integrations/dynamics365/response/Whoami` |
| Listaccounts | GET | `/api/data/v9.2/accounts` | `integrations/dynamics365/request/Listaccounts` | `integrations/dynamics365/response/Listaccounts` |
| Createaccount | POST | `/api/data/v9.2/accounts` | `integrations/dynamics365/request/Createaccount` | `integrations/dynamics365/response/Createaccount` |
| Getaccount | GET | `/api/data/v9.2/accounts({value.json.accountid})` | `integrations/dynamics365/request/Getaccount` | `integrations/dynamics365/response/Getaccount` |
| Updateaccount | PATCH | `/api/data/v9.2/accounts({value.json.accountid})` | `integrations/dynamics365/request/Updateaccount` | `integrations/dynamics365/response/Updateaccount` |
| Listcontacts | GET | `/api/data/v9.2/contacts` | `integrations/dynamics365/request/Listcontacts` | `integrations/dynamics365/response/Listcontacts` |
| Getcontact | GET | `/api/data/v9.2/contacts({value.json.contactid})` | `integrations/dynamics365/request/Getcontact` | `integrations/dynamics365/response/Getcontact` |
| Listentitydefinitions | GET | `/api/data/v9.2/EntityDefinitions` | `integrations/dynamics365/request/Listentitydefinitions` | `integrations/dynamics365/response/Listentitydefinitions` |

List endpoints accept OData query options (`$select`, `$filter`, `$top`, `$orderby`) when you extend the `ENDPOINT` or append them in a custom variant.

## Auth

Azure AD Bearer plus Dataverse OData headers:

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
ADD "Accept" "application/json"
ADD "OData-MaxVersion" "4.0"
ADD "OData-Version" "4.0"
ADD "Prefer" "odata.include-annotations=\"*\""
ADD "Authorization" "Bearer {value.json.api_token}"
```

**api\_token** `string` *required*

Azure AD access token for the Dataverse org resource (audience = org URL). Obtain via client credentials or a delegated OAuth 2.0 flow. Prefer a Hub secret. Never commit the token.

**accountid** `string`

Account GUID. Required on Getaccount and Updateaccount.

**contactid** `string`

Contact GUID. Required on Getcontact.

High-level token flow (no secrets in the template):

1. Register an Entra ID app with permission to the Dynamics / Dataverse API (or use an existing app registration).
2. Acquire a token with **client credentials** (app-only) or a **delegated** user flow against the org resource URL.
3. Publish the access token as `api_token` on the MQTT request payload (or inject from Hub secret upstream).

WhoAmI smoke:

```json theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
{"api_token": "YOUR_AZURE_AD_ACCESS_TOKEN"}
```

Get account:

```json theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
{"api_token": "YOUR_AZURE_AD_ACCESS_TOKEN", "accountid": "00000000-0000-0000-0000-000000000000"}
```

Create account (connector body is `{payload}`; include `name`):

```json theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
{"api_token": "YOUR_AZURE_AD_ACCESS_TOKEN", "name": "Contoso Plant"}
```

## Try it

1. Set `BASE_ADDRESS` to your org URL and add the connector on a lab broker.
2. Publish token JSON to `integrations/dynamics365/request/Whoami`.
3. Subscribe to `integrations/dynamics365/response/Whoami`.
4. Accounts / contacts: include `accountid` or `contactid` as needed.

> [!NOTE]
>
> Recorded factory probes without a usable org token: placeholder org DNS fail (curl 6), Microsoft Learn Web API overview HTTP 200, Dataverse global discovery HTTP 400 (`TenantIdInvalid`), Azure AD common OIDC metadata HTTP 200. `lot_lint` reported no findings on `Dynamics365RestApi`.

## Related

* [REST API Connectors](/latest/lot-language/routes/rest-api-routes)
* [REST API Apps](/latest/lot-language/routes/rest-api-apps)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.