Platform
Chatbot Builder Bulk Messaging Team Inbox Mini CRM API & Webhooks AI Integration WhatsApp Flows
Industries
E-commerce & D2C Real Estate Education Healthcare Finance & BFSI Logistics Hospitality Retail
Integrations
Learn
Learning Hub Help & Docs Connect Guides Automation Codex Blog Message Templates
Pricing Get Started →
HomeConnect › Connect Dynamics 365 to WhatsApp
Microsoft Dynamics 365 Guide · CRM / Enterprise

Connect Dynamics 365 to WhatsApp

Query live contact data from Microsoft Dynamics 365 into a WhatsApp chatbot using the Dataverse Web API v9.2 and OData queries. When a customer messages you, look up their CRM record by mobile number and reply with their account context.

Published 22 June 2026  ·  12 min read  ·  CRM / Enterprise

Before following this guide, read the External API Request step foundation guide. It covers every field in the step interface so this guide can focus on Dynamics 365-specific values.

This guide requires IT admin involvement

Connecting Dynamics 365 to any external system requires registering an app in Microsoft Entra ID (Azure AD). This needs Global Administrator or Application Administrator permission in your Microsoft tenant. If you are not the IT admin, share this guide with them. The app registration is a one-time task, after which the WA.Expert steps are self-serve.

How Dynamics 365 API authentication works

Dynamics 365 uses Microsoft Entra ID (formerly Azure AD) for authentication. Unlike other CRMs with a simple API key, Dynamics uses the OAuth 2.0 client credentials flow, in two steps each time the token expires:

StepWhat happensResult
1. Register appCreate an app registration in Azure portal with Dynamics CRM permissionGet Tenant ID, Client ID, Client Secret
2. Get tokenPOST to Microsoft identity platform token endpointGet access_token (valid ~1 hour)
3. Call APIGET to your Dynamics org Web API endpoint with Bearer token + OData headersGet contact data in JSON

Access tokens expire after approximately 1 hour. For a production WhatsApp bot, set up a refresh step that re-requests the token before it expires, similar to the Zoho CRM approach in our Zoho guide.

Step 1: Register an app in Microsoft Entra ID

This is the one-time IT admin task. All steps happen in the Azure portal.

1
In Azure portal, go to Microsoft Entra ID (formerly Azure Active Directory) → App registrationsNew registration.
2
Name the app (e.g. "WA.Expert WhatsApp Bot"). Leave Redirect URI blank for client credentials flow. Click Register.
3
Note the Application (client) ID and Directory (tenant) ID from the Overview page.
4
Go to Certificates and secretsNew client secret. Give it a description and expiry. Click Add. Copy the Value immediately.
5
Go to API permissionsAdd a permissionDynamics CRM → select user_impersonation → click Add permissions.
6
Click Grant admin consent for your organisation. A tick confirms it is granted.
7
In Dynamics 365, go to Settings → Security → Users. Create an Application User. Set the Application ID to the Client ID from Step 3. Assign a security role (e.g. a custom read-only role).
Find your Dynamics org URL

Go to Dynamics 365 Settings > Customisation > Developer Resources. Your Web API URL is shown there, for example https://YOUR_ORG.api.crm.dynamics.com/api/data/v9.2. Note the exact URL including the region suffix (crm, crm4, crm7, etc.).

Step 2: Get an access token

With the Tenant ID, Client ID, and Client Secret from Step 1, request an access token. This is an External API Request step in WA.Expert, set up as a separate step before the contact lookup:

Step 2 — Get access token (POST, run before each contact lookup)
POST https://login.microsoftonline.com/YOUR_TENANT_ID/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded

Body (form fields):
  grant_type    = client_credentials
  client_id     = YOUR_CLIENT_ID
  client_secret = YOUR_CLIENT_SECRET
  scope         = https://YOUR_ORG.crm.dynamics.com/.default

Response:
{
  "token_type": "Bearer",
  "expires_in": 3599,
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6..."
}

Store access_token as {{dynamics_token}}.
It is valid for ~1 hour. Refresh before it expires.

Step 3: Fill in the contact lookup step

With the token stored as {{dynamics_token}} and the customer's phone as {{customer_phone}}, add a second External API Request step for the contact lookup:

External API Request Step — WA.Expert
Select Method
GET
Request URL
https://YOUR_ORG.api.crm.dynamics.com/api/data/v9.2/contacts?$select=fullname,firstname,lastname,emailaddress1,mobilephone,jobtitle&$filter=mobilephone eq '{{{{customer_phone}}}}'
Select Auth Type
No Auth (Bearer token in header below)
Header Parameters
AuthorizationBearer {{{{dynamics_token}}}}
OData-MaxVersion4.0
OData-Version4.0
Acceptapplication/json
Select Body Type
None (GET requests carry no body)
Choose Response Type
JSON

Field-by-field breakdown

FieldValueNotes
Select MethodGETQuerying contact records.
Request URLhttps://YOUR_ORG.api.crm.dynamics.com/api/data/v9.2/contacts?$select=...&$filter=mobilephone eq '{{{customer_phone}}}'Replace YOUR_ORG with your Dynamics organisation name. $select lists the fields to return. $filter applies the OData condition.
AuthorizationBearer {{{dynamics_token}}}The token from Step 2. Include 'Bearer ' prefix. The token is stored in the chatbot variable {{dynamics_token}}.
OData-MaxVersion4.0Required by Dynamics 365 Web API. Without this, the request may fail.
OData-Version4.0Required pair with OData-MaxVersion. Both headers are mandatory.
Acceptapplication/jsonRequest JSON response format.
Select Body TypeNoneGET requests carry no body.
Choose Response TypeJSONDynamics returns structured JSON.
OData headers are mandatory: unique to Dynamics 365

Microsoft's Dataverse Web API requires OData-MaxVersion: 4.0 and OData-Version: 4.0 on every request. No other CRM in this series requires these headers. Omitting them may return a 400 error or unpredictable behaviour.

OData filter patterns for contact lookup

What you wantOData $filter value
Contact by mobile phonemobilephone eq '9820000001'
Contact by business phonetelephone1 eq '9820000001'
Contact by emailemailaddress1 eq 'priya@example.com'
Contact by full namefullname eq 'Priya Sharma'
Phone or mobilemobilephone eq '9820000001' or telephone1 eq '9820000001'

Dynamics 365 stores phone numbers in three fields: mobilephone (Mobile Phone), telephone1 (Business Phone), telephone2 (Home Phone). Match the field where your sales team stores WhatsApp numbers.

Step 4: Map the response to WhatsApp variables

A successful Dynamics 365 contact response looks like this:

Dynamics 365 Web API v9.2 — GET /contacts response
{
  "@odata.context": "https://YOUR_ORG.api.crm.dynamics.com/api/data/v9.2/$metadata#contacts(...)",
  "value": [
    {
      "fullname": "Priya Sharma",
      "firstname": "Priya",
      "lastname": "Sharma",
      "emailaddress1": "priya@example.com",
      "mobilephone": "9820000001",
      "jobtitle": "Procurement Manager",
      "contactid": "81716234-9628-ed11-9db1-000d3a320482",
      "@odata.etag": "W/\"1146759\""
    }
  ]
}
Results are in a value array

Dynamics wraps all results in a 'value' array, even for a single match. Map variables using value[0].fieldname. If the value array is empty, no contact matched the phone number. Add a conditions branch for that case.

Map these response paths to variables in the External API Request step:

Variable nameResponse pathExample value
full_namevalue[0].fullnamePriya Sharma
first_namevalue[0].firstnamePriya
emailvalue[0].emailaddress1priya@example.com
job_titlevalue[0].jobtitleProcurement Manager
contact_idvalue[0].contactid81716234-9628-ed11-9db1-000d3a320482

@odata.context and @odata.etag are Dynamics metadata fields. Ignore them. Your contact data is in the named fields alongside them.

Keep the WhatsApp reply in the free service window

If the contact messaged you first within the last 24 hours, your reply is a free service conversation. For proactive outbound messages from Dynamics data, use an approved Utility or Marketing template.

Worked example: enterprise contact context bot

Chatbot flow — Dynamics 365 contact lookup
Customer messages your WhatsApp number.
WA.Expert captures their phone as {{customer_phone}} = "9820000001".

Step 1 — Get token:
POST https://login.microsoftonline.com/YOUR_TENANT_ID/oauth2/v2.0/token
Body: grant_type=client_credentials&client_id=...&client_secret=...
     &scope=https://YOUR_ORG.crm.dynamics.com/.default

Store: dynamics_token = "eyJ0eXAiOiJKV1Qi..."

Step 2 — Look up contact:
GET https://YOUR_ORG.api.crm.dynamics.com/api/data/v9.2/contacts
  ?$select=fullname,jobtitle,emailaddress1
  &$filter=mobilephone eq '9820000001'
Authorization: Bearer {{dynamics_token}}
OData-MaxVersion: 4.0
OData-Version: 4.0

Response mapped:
full_name = "Priya Sharma"
job_title = "Procurement Manager"
email     = "priya@example.com"

Conditions: if value is empty → "We could not find your record."

Bot replies (if found):
"Hi Priya Sharma, welcome.
Role: Procurement Manager
Account manager will be in touch shortly.

Reply URGENT for immediate attention."

Troubleshooting

SymptomLikely causeFix
AADSTS error on token requestWrong tenant ID, client ID, or client secretCopy values exactly from the Azure portal App registrations page. Check for trailing spaces or line breaks in the client secret.
401 Unauthorized on API callToken expired or Application User not set upRe-request the token (Step 2). Also ensure you created an Application User in Dynamics 365 Settings > Security > Users linked to the same Client ID.
403 ForbiddenApplication User lacks the required security roleIn Dynamics 365 admin, assign a security role to the Application User that grants read access to the Contact entity.
Empty value arrayPhone number format mismatchCheck exactly how phone numbers are stored in Dynamics (with country code, with spaces, etc.). Try telephone1 instead of mobilephone. Or use contains(mobilephone,'9820000001').
OData headers errorMissing OData-MaxVersion or OData-Version headersAdd both OData-MaxVersion: 4.0 and OData-Version: 4.0 to the header parameters. Both are required by the Dynamics Web API.
scope parameter wrongScope must end with /.defaultThe scope must be the full Dynamics org URL plus /.default, for example https://YOUR_ORG.crm.dynamics.com/.default. Do not use other scope values.

Common questions

Do I need to involve my IT team?
+
Most likely yes. Registering an app in Microsoft Entra ID requires Global Administrator or Application Administrator rights. Share this guide with your IT admin. The app registration is a one-time task. After that, WA.Expert steps are self-serve.
What is the Dynamics 365 Web API endpoint format?
+
https://YOUR_ORG.api.crm.dynamics.com/api/data/v9.2/ (find YOUR_ORG in Dynamics 365 Settings > Customisation > Developer Resources > Web API URL.
What are OData headers and why are they required?
+
OData-MaxVersion: 4.0 and OData-Version: 4.0 are required by Microsoft's Dataverse Web API on every request. No other CRM in this series requires these. Without them, requests may fail.
How do I search contacts by phone number?
+
$filter=mobilephone eq '9820000001'. Also try telephone1 for Business Phone. Use 'or' to search both: $filter=mobilephone eq '9820000001' or telephone1 eq '9820000001'.
What is the API rate limit?
+
6,000 requests per user per 5-minute window (Service Protection API limits). For a WhatsApp bot doing single lookups, this is extremely generous.
Does this incur extra WA.Expert charges?
+
The External API Request step counts as one automation action per call. On the Complete plan this is included. On Starter, extra action packs apply from Rs. 49 per 1,000 actions.

Connect Dynamics 365 to WhatsApp today

Free trial, no credit card required. And if you ever get stuck, we are the only platform in India that answers you live on WhatsApp.

Start Free Trial → Book a Demo
1