Microsoft Dynamics Solutions Blog

Microsoft Dynamics 365 Web API Guide: Auth, OData & CRUD

Written by Alex Marzban | Sep 9, 2026, 2:00:00 PM

Quick Answer

For Dynamics 365 applications that use Microsoft Dataverse, the “Dynamics 365 Web API” is the Dataverse Web API, an OData v4 REST endpoint that lets authenticated applications read and modify business data over HTTPS. Current Microsoft examples use the /api/data/v9.2/ endpoint. You authenticate with Microsoft Entra ID using OAuth, then call table endpoints with standard HTTP methods such as GET, POST, PATCH, and DELETE. For server-to-server integrations, the Microsoft Entra application should also be represented by an application user in the Dataverse environment with an appropriate security role.

Key Takeaways

  • The Microsoft Dynamics 365 Web API discussed in this guide is the Microsoft Dataverse Web API used by Dataverse-based Dynamics 365 applications.
  • The API implements OData v4 and is available through the /api/data/v9.2/ path used throughout Microsoft’s current documentation and samples.
  • Authentication uses OAuth with Microsoft Entra ID. App-only integrations also need a Dataverse application user and security role inside the target environment.
  • Use GET, POST, PATCH, and DELETE for common CRUD operations, and use OData query options such as $select, $filter, $orderby, $top, and $expand to shape results.
  • For large result sets, use OData paging with Prefer: odata.maxpagesize and follow @odata.nextLink rather than trying to page with $skip.
  • Production integrations should use least privilege, protect credentials, handle concurrency, log errors, and honor Retry-After when Dataverse returns HTTP 429.

What Is the Microsoft Dynamics 365 Web API?

The Microsoft Dataverse Web API is a RESTful interface for working with Dataverse data and metadata. It implements OData v4, which means developers can use standard HTTP requests and familiar query conventions from virtually any language or platform that can send authenticated HTTPS requests.

For Dynamics 365 products built on Dataverse, including common customer-engagement workloads, developers often refer to this as the D365 Web API or Dynamics CRM API. The distinction is important because Dynamics 365 refers to a family of products. Not every Dynamics 365 ERP application exposes all of its data through this same Dataverse endpoint, so integration teams should confirm the Microsoft Dynamics API surface for the specific Dynamics 365 product they are connecting.

Microsoft’s current Dataverse Web API examples use an organization endpoint in this form:

https://{organization}.api.crm.dynamics.com/api/data/v9.2/{resource}

Version 9.2 is the endpoint version used across current Microsoft Dataverse Web API documentation and samples. If you are maintaining older code that uses an earlier v8.x path, review Microsoft’s current documentation before extending that integration.

Why Use the Dynamics 365 Web API?

Integrate Dynamics 365 With Other Applications

The Web API is useful when an external application needs direct, programmatic access to Dataverse records. Common scenarios include:

  • Synchronizing customer or lead data
  • Connecting proprietary line-of-business systems
  • Feeding custom reporting pipelines
  • Coordinating processes across Microsoft and non-Microsoft platforms

For lower-code scenarios, Power Automate or a supported connector may be easier to maintain. The Web API becomes especially useful when you need precise request control, custom code, a language-neutral HTTP interface, or integration logic that does not fit an existing connector.

Automate Business Processes

Scheduled jobs and event-driven services can use the Web API to create or update rows, synchronize data between systems, and trigger downstream business logic. For production use, focus not only on making API calls but also on managing authentication, retries, idempotency, concurrency, and service-protection limits over time.

Build Custom Applications

Custom web applications, internal dashboards, mobile tools, and middleware services can use the Web API to surface Dataverse data without reproducing the full Dynamics 365 user interface. Microsoft also provides platform-specific options such as Xrm.WebApi for model-driven app JavaScript and SDK choices for .NET and Python, so the right interface depends on where your code runs.

Access Data Securely Through OAuth

Dataverse uses OAuth with Microsoft Entra ID. Authentication establishes the identity making the call, while Dataverse security roles and privileges determine which tables, rows, and operations that identity is authorized to use. This distinction is important because receiving an access token does not automatically provide broad access to the environment.

Microsoft Dynamics 365 API Prerequisites

Before sending your first request, confirm the following:

  • A Dataverse environment and its organization URL.
  • Access to the Microsoft Entra tenant associated with the environment.
  • An authentication approach appropriate to the application: delegated user authentication for interactive apps, or app-only authentication for unattended services.
  • For app-only server-to-server access, an application registration plus an application user in the Dataverse environment with a least-privilege security role.
  • An HTTP client or development environment such as Postman, Insomnia, curl, PowerShell, JavaScript, C#, or Python.

How to Authenticate to the Dynamics 365 Web API

Microsoft’s authentication guidance varies by where the code runs, but external clients generally authenticate through Microsoft Entra ID using OAuth. The steps below focus on an app-only server-to-server pattern because it is common for Microsoft Dynamics integrations and background services.

1. Register an App in Microsoft Entra ID

Create an application registration in Microsoft Entra ID and record the Application (client) ID and Directory (tenant) ID. For a single-tenant internal integration, a single-tenant registration is usually appropriate. The exact registration settings should match your organization’s identity and security requirements.

2. Choose a Credential

While a client secret can support server-to-server authentication, it is not the only approach. For production workloads, use the strongest credential model that fits your architecture, such as a certificate or managed identity where supported. If you use a client secret, keep it in a secure secrets store and never commit it to source control or expose it in browser-side code.

3. Create the Dataverse Application User and Assign a Security Role

For app-only access, create an application user in the target Dataverse environment that corresponds to the Microsoft Entra application, then assign only the security roles and privileges the integration needs. Microsoft specifically recommends using a custom security role for real-world server-to-server applications.

4. Obtain an OAuth Access Token

A client-credentials token request uses the Microsoft identity platform token endpoint and the Dataverse organization URL as the resource scope:

POST https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded

client_id={your-client-id}
client_secret={your-client-secret}
scope=https://{your-org}.api.crm.dynamics.com/.default
grant_type=client_credentials

Use the access_token value returned by Microsoft Entra ID as a bearer token. In application code, prefer a supported authentication library such as MSAL when appropriate, and use the token response expiration information or library token cache instead of relying on a fixed lifetime assumption.

5. Add the Bearer Token to API Requests

Authorization: Bearer {access_token}

Your Dataverse security role still controls what the authenticated application can read or change. A 403 response after successful Dynamics 365 web API authentication often points to an authorization or privilege problem rather than a token problem.

Making Your First Dynamics 365 Web API Request

Test the Microsoft Dynamics API Using Postman, Insomnia, or curl

An HTTP client is useful for validating the environment URL, OAuth configuration, headers, table names, and OData query syntax before you move the request into application code. Although Microsoft’s getting-started documentation uses tools like Insomnia and PowerShell, the underlying Microsoft Dynamics API request pattern is the same.

Example GET Request

The following request retrieves account names from the first three rows returned by the query:

GET https://{org}.api.crm.dynamics.com/api/data/v9.2/accounts?$select=name&$top=3
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
Authorization: Bearer {access_token}

Understanding the Response

A successful retrieval returns HTTP 200 and a JSON payload. Dataverse responses can include annotations such as @odata.context, record-level @odata.etag values, and @odata.nextLink when more pages of results are available. ETags can be used for conditional operations so an update does not silently overwrite a newer version of a row.

HTTP/1.1 200 OK
Content-Type: application/json
OData-Version: 4.0

{
"@odata.context": "https://{org}.api.crm.dynamics.com/api/data/v9.2/$metadata#accounts(name)",
"value": [
{
"@odata.etag": "W/\"502000\"",
"name": "Contoso Ltd",
"accountid": "89390c24-9c72-e511-80d4-00155d2a68d1"
}
]
}

HTTP Methods Used in the Dynamics 365 API

Method

Purpose

Common use

GET

Retrieve rows or metadata

Read accounts, contacts, leads, opportunities, or custom tables

POST

Create a row or invoke applicable operations

Create a new account or other table row

PATCH

Update a row; can also participate in upsert patterns

Change selected column values without replacing the whole row

DELETE

Delete a row or clear a supported property

Remove an existing row

PUT

Set or replace specific resources in supported scenarios

Less common for basic table CRUD; follow operation-specific documentation

 

For requests that send JSON, include the appropriate Content-Type header. Microsoft samples also commonly send Accept: application/json, OData-MaxVersion: 4.0, and OData-Version: 4.0.

Querying Data with OData

OData query options let you choose columns, filter rows, sort results, limit the returned set, and expand related data. Combine only the options you need, and keep queries as simple and selective as the use case allows.

Using $select

Use $select to request only the columns your application needs. This reduces payload size and avoids retrieving unnecessary data.

GET /api/data/v9.2/contacts?$select=firstname,lastname,emailaddress1

Using $filter

Use $filter to return only rows that match a condition. Dataverse supports standard OData comparison operators such as eq, ne, gt, ge, lt, and le, along with logical operators and supported query functions.

GET /api/data/v9.2/accounts?$select=name,revenue&$filter=revenue gt 1000000

GET /api/data/v9.2/accounts?$select=name&$filter=contains(name,'Contoso')

Using $orderby

Use $orderby to sort results. When paging through a changing data set, deterministic ordering matters. Microsoft recommends including a unique or near-unique value, such as the table primary key, so rows do not unexpectedly overlap between pages.

GET /api/data/v9.2/contacts?$select=lastname,firstname,contactid&$orderby=lastname asc,firstname asc,contactid asc

Using $top

Use $top when you want only the first N rows from a result set:

GET /api/data/v9.2/accounts?$select=name&$top=10

Do not use $top as a substitute for paging through an entire result set. For OData paging, use the Prefer: odata.maxpagesize request header and follow the @odata.nextLink returned by Dataverse. Dataverse does not support $skip as a paging strategy.

GET /api/data/v9.2/accounts?$select=name,accountid&$orderby=accountid asc
Prefer: odata.maxpagesize=500

Using $expand

Use $expand to retrieve related data through navigation properties defined by the Dataverse data model. Keep expanded projections selective to avoid returning more related data than the application needs.

GET /api/data/v9.2/accounts?$select=name&$expand=primarycontactid($select=fullname,emailaddress1)

Create, Update, and Delete Records

Create Records with POST

Send a POST request to the table’s entity-set endpoint with a JSON body containing the columns you want to populate. If you need the created representation in the response, use Prefer: return=representation.

POST /api/data/v9.2/accounts HTTP/1.1
Content-Type: application/json; charset=utf-8
OData-MaxVersion: 4.0
OData-Version: 4.0
Accept: application/json

{
"name": "Contoso Ltd",
"creditonhold": false,
"revenue": 5000000,
"description": "New account created via Web API"
}

Update Records with PATCH

PATCH updates the columns included in the request body. Target the row by its ID, and use conditional headers when you need concurrency protection.

PATCH /api/data/v9.2/accounts(7eb682f1-ca75-e511-80d4-00155d2a68d1) HTTP/1.1
Content-Type: application/json; charset=utf-8
If-Match: W/"502000"

{
"revenue": 7500000,
"description": "Updated via Web API"
}

If the ETag no longer matches because another process changed the row, Dataverse can return HTTP 412 Precondition Failed. Conditional requests are especially useful when multiple systems may update the same business record.

Delete Records with DELETE

Send DELETE to the row URI when the application is authorized to remove that row:

DELETE /api/data/v9.2/accounts(7eb682f1-ca75-e511-80d4-00155d2a68d1) HTTP/1.1
OData-MaxVersion: 4.0
OData-Version: 4.0

For production integrations, make deletes deliberate and auditable. If the business requirement is to deactivate or close a record rather than physically delete it, use the table’s supported state/status behavior instead.

Common Dynamics 365 Web API Errors and Solutions

Status

Likely issue

Recommended response

401 Unauthorized

Authentication failed or token is invalid/expired

Acquire a valid token; verify tenant, client, scope/resource, and credential configuration.

403 Forbidden

Identity is authenticated but not authorized

Check the Dataverse application user and security-role privileges for the requested table/operation.

404 Not Found

Wrong environment URL, entity-set name, route, or row ID

Verify the organization URL, API path, entity-set name, and record identifier.

412 Precondition Failed

Conditional request failed because the ETag or precondition no longer matches

Retrieve the current row/ETag and decide whether to retry, merge, or surface a conflict.

429 Too Many Requests

Dataverse service-protection limit was exceeded

Honor the Retry-After response header before retrying and reduce sustained or burst load. [5]

5xx Server Error

Transient service or platform failure may have occurred

Log the full response and request correlation details; retry only when the operation is safe/idempotent and your retry policy allows it.

Always capture the response body and relevant request/correlation information when troubleshooting. Avoid logging access tokens, client secrets, or sensitive business data.

Best Practices for Using the Dynamics 365 Web API

Limit Returned Fields

Use $select to retrieve only the columns the application actually consumes. This is one of the simplest ways to reduce response size and avoid unnecessary work.

Use Pagination Correctly

Assume that large result sets will be paged. Use Prefer: odata.maxpagesize, follow @odata.nextLink exactly as returned, and use deterministic ordering when consistency across pages matters. Microsoft documents that a request can return up to 5,000 standard-table rows by default, while other table types and environment behavior can differ, so code should be written to page rather than depend on a single-response assumption.

Secure Credentials and Use Least Privilege

Never place client secrets in source code, browser JavaScript, or a public repository. Use a managed secret store, rotate credentials according to organizational policy, and assign the Dataverse application user the minimum privileges needed for its integration tasks. If the architecture permits, favor certificate-based or managed identity authentication over long-lived shared secrets.

Implement Retry Logic That Honors Retry-After

Dataverse uses service-protection limits to keep the platform responsive. When the Web API returns HTTP 429, Microsoft includes a Retry-After value. Wait for that interval before retrying. Do not use batching or parallelism as a way to bypass limits because Dataverse also evaluates execution time and concurrent requests.

Design for Idempotency and Concurrency

Retries can create duplicate work if an operation is not idempotent. For integration jobs, decide how you will recognize already-processed messages, use alternate keys or upsert patterns where appropriate, and use ETags or conditional headers when concurrent updates are possible.

Monitor the Integration, Not Just the Endpoint

Track request latency, error rates, 429 frequency, Dynamics 365 API authentication failures, retries, and business-level reconciliation failures in your application telemetry. The goal is to detect a data-sync problem before it becomes a user-visible Dynamics 365 issue.

Dynamics 365 Web API vs. Dataverse Web API: What Is the Difference?

In the context of Dynamics 365 applications that store their business data in Microsoft Dataverse, “Dynamics 365 Web API” and “Dataverse Web API” generally refer to the same Dataverse OData endpoint. Microsoft’s current documentation uses the Dataverse name.

However, it is too broad to say that every Dynamics 365 product uses one identical API. Dynamics 365 includes multiple applications and workloads. If you are integrating with Finance, Supply Chain Management, Business Central, or another product-specific service, verify that product’s current MS Dynamics API documentation before assuming the Dataverse endpoint is the right integration surface.

Harness the Full Power of Dynamics 365

The Microsoft Dataverse Web API gives development and Dynamics 365 API integration teams a standards-based way to connect Dataverse-backed Dynamics 365 applications with the rest of the technology stack. The basic mechanics of a successful proof of concept are simple: authenticate, access the correct entity set, and handle JSON data. Production quality depends on the details around identity, authorization, query design, paging, retries, concurrency, observability, and data governance.

IES helps organizations plan, implement, and support Microsoft Dynamics 365 integrations. If you are deciding between the Dataverse Web API, Power Platform connectors, Azure integration services, or a product-specific integration approach, contact IES to discuss the architecture that best fits your environment.

Dynamics 365 Web API: FAQs