The Microsoft Dynamics CRM Client Credentials Component connects to the Microsoft Dynamics CRM / Dataverse Web API using the OAuth 2.0 Client Credentials Grant (server-to-server / machine-to-machine authentication without interactive user login).
The component automatically manages OAuth 2.0 token acquisition and refresh via Microsoft Entra ID (Azure AD), deriving the resource scope directly from your Dynamics instance Base URL (${origin}/.default).
Please Note:
1. Application User in Dynamics 365 (Required): Microsoft Dynamics CRM / Dataverse will reject requests with
401 Unauthorizedor403 Forbidden(0x80072560 - The user is not a member of the organization) unless the Azure App Registration is added as an Application User (see Manage application users in the Power Platform admin center):
- Go to the Power Platform Admin Center.
- In the left menu, select Environments -> select your Dynamics 365 environment.
- In the top bar, click Settings -> expand Users + permissions -> click Application users.
- Click + New app user.
- Click + Add an app, search for and select your Azure App Registration (by Client ID or Name).
- Select the appropriate Business unit.
- Under Security roles, assign the required roles (e.g., System Administrator or a custom security role with read/write access to target entities).
- Click Create.
2. Azure App Registration & API Permissions: Refer to Microsoft Entra ID: Client credentials grant flow and Use Multi-Tenant Server-to-Server Authentication:
- In the Azure Portal under App registrations, select your application.
- Under Overview, copy your Application (Client) ID and Directory (Tenant) ID.
- Go to API permissions -> click Add a permission -> select Dynamics CRM -> check
user_impersonation.- Click **Grant admin consent for
** and verify green checkmarks. - Under Certificates & secrets, generate a New client secret and copy its Value.
| Field Name | Mandatory | Description |
|---|---|---|
| Application (Client) ID | Yes | Azure App Registration Application (Client) ID (GUID). |
| Client Secret | Yes | Azure App Registration Client Secret Value. |
| Directory (Tenant) ID | Yes | Azure Directory (Tenant) ID (GUID). |
| Base URL | Yes | Your Dynamics CRM Web API URL, e.g. https://org1.crm4.dynamics.com/api/data/v9.2 or https://org1.crm4.dynamics.com. |
| API version | No | Web API version to use (e.g. v9.2). Defaults to v9.2 if omitted. |
To complete setup:
/WhoAmI endpoint.Retry-After response header (supporting both integer seconds and HTTP-Date format) up to 3 retry attempts.Performs a lookup of multiple objects based on configurable filter criteria, pagination, and projection parameters.
accounts, contacts.Emit individually):
Emit individually: Emits each matching record as a separate message.Emit page: Emits all records from the page in a single message with an array named results.false): Enables writing raw OData $filter expressions directly into the Filter Expression input field.100): Maximum records to fetch per page (1 to 1000).name,telephone1,accountnumber.primarycontactid,createdby.$filter expression (without $filter= prefix).{
"filterExpression": "startswith(name,'Fabrikam') and statecode eq 0"
}
Input is dynamically constructed based on Number of search terms:
{
"sTerm_1": {
"fieldName": "address1_city",
"condition": "eq",
"fieldValue": "'Seattle'"
},
"link_1_2": "and",
"sTerm_2": {
"fieldName": "statuscode",
"condition": "eq",
"fieldValue": "1"
}
}
Emit individually:Each matching record is emitted as its own message:
{
"accountid": "88cea450-cb0c-ea11-a813-000d3a1b1223",
"name": "Fabrikam, Inc.",
"accountnumber": "ACC-10042",
"telephone1": "423-555-0103",
"address1_city": "Seattle",
"createdon": "2024-08-28T14:27:43Z"
}
Emit page:Emits an array under results:
{
"results": [
{
"accountid": "88cea450-cb0c-ea11-a813-000d3a1b1223",
"name": "Fabrikam, Inc.",
"accountnumber": "ACC-10042",
"telephone1": "423-555-0103"
},
{
"accountid": "99dfb561-db1d-ea11-a813-000d3a1b1224",
"name": "Contoso Pharmaceuticals",
"accountnumber": "ACC-10043",
"telephone1": "206-555-0199"
}
]
}
Looks up a single record by a selected unique or identifier field. If more than one record matches, execution fails with "More than one object found".
accounts, contacts.AccountId (Primary Key)Name (Primary Name)AccountNumber (Alternate Key)EMailAddress1, Telephone1, Address1_City.Lookup Criteria Value is not provided.{} instead of throwing an error when no matching record is found.Allow criteria to be omitted is checked): The value to search for.
00000000-0000-0000-0000-000000000000).O'Connor) are automatically escaped.{
"lookupCriteriaValue": "88cea450-cb0c-ea11-a813-000d3a1b1223"
}
{
"lookupCriteriaValue": "Fabrikam, Inc."
}
Returns the matched object:
{
"accountid": "88cea450-cb0c-ea11-a813-000d3a1b1223",
"name": "Fabrikam, Inc.",
"accountnumber": "ACC-10042",
"telephone1": "423-555-0103",
"address1_city": "Lynnwood",
"createdon": "2024-08-28T14:27:43Z",
"modifiedon": "2024-08-28T14:30:19Z"
}
Creates a new record or updates an existing record based on a unique identifier or Alternate Key.
accounts, contacts.Entity ID: Matches on the record’s primary GUID.accountnumber).Entity ID): The primary GUID of the record.@odata.bind): For foreign key lookup fields (e.g. primarycontactid), provide the navigation path format: /<EntitySetName>(<GUID>).{
"id": "88cea450-cb0c-ea11-a813-000d3a1b1223",
"name": "Fabrikam International, Inc.",
"telephone1": "423-555-0199",
"revenue": 9500000,
"primarycontactid@odata.bind": "/contacts(cdd6a450-cb0c-ea11-a813-000d3a1b1223)"
}
{
"name": "Contoso Retailers",
"telephone1": "206-555-0100",
"address1_city": "Bellevue",
"address1_line1": "100 Main St."
}
Returns the created or updated object from Dynamics 365:
{
"accountid": "88cea450-cb0c-ea11-a813-000d3a1b1223",
"name": "Fabrikam International, Inc.",
"telephone1": "423-555-0199",
"revenue": 9500000,
"modifiedon": "2024-11-04T12:30:00Z"
}
Deletes a single record by its primary ID.
accounts.ID Value): The primary GUID of the record to delete.{
"id": "88cea450-cb0c-ea11-a813-000d3a1b1223"
}
{
"id": "88cea450-cb0c-ea11-a813-000d3a1b1223"
}
Executes an arbitrary HTTP request against the Microsoft Dynamics CRM Web API using the authenticated client.
false): When checked, 404 HTTP responses are returned in responseBody rather than throwing an error.GET, POST, PUT, PATCH, or DELETE./accounts?$select=name&$top=5.{ "Prefer": "odata.maxpagesize=50" }.Request Body): Request payload for POST, PUT, or PATCH.{
"method": "GET",
"url": "/accounts?$select=name,accountnumber&$top=2",
"headers": {
"Prefer": "odata.include-annotations=\"*\""
}
}
{
"method": "PATCH",
"url": "/accounts(88cea450-cb0c-ea11-a813-000d3a1b1223)",
"headers": {
"If-Match": "*"
},
"data": {
"telephone1": "423-555-0155"
}
}
{
"statusCode": 200,
"headers": {
"content-type": "application/json; odata.metadata=minimal",
"odata-version": "4.0"
},
"responseBody": {
"value": [
{
"accountid": "88cea450-cb0c-ea11-a813-000d3a1b1223",
"name": "Fabrikam, Inc.",
"accountnumber": "ACC-10042"
}
]
}
}
Periodically polls for newly created or modified records within a sliding time window.
accounts, contacts.Emit individually: Emits each changed record as a separate message.Emit page: Emits all records from the page under results.5000): Maximum records to fetch per polling request.2024-01-01T00:00:00Z. Defaults to all existing records.Last Modified):
Last Modified: Polls on modifiedon.Created: Polls on createdon.None.
Emit individually:{
"accountid": "88cea450-cb0c-ea11-a813-000d3a1b1223",
"name": "Fabrikam, Inc.",
"modifiedon": "2024-11-04T13:45:00Z",
"createdon": "2024-08-28T14:27:43Z"
}
Emit page:{
"results": [
{
"accountid": "88cea450-cb0c-ea11-a813-000d3a1b1223",
"name": "Fabrikam, Inc.",
"modifiedon": "2024-11-04T13:45:00Z"
}
]
}
Memo) and Complex Attributes in Filters:
Microsoft Dataverse does not support OData $filter queries on Memo (multiline text, e.g. description), virtual attributes, or file/image properties. These are excluded from single-record lookup criteria._<field>_value column name (e.g. _primarycontactid_value eq <GUID>).Upsert Object), Dataverse requires @odata.bind notation (e.g. "primarycontactid@odata.bind": "/contacts(<GUID>)").$filter, $select, $expand, and OData query syntax.Click here to learn more about the elastic.io iPaaS