{"id":13096,"library":"dynamics-web-api","title":"DynamicsWebApi for Microsoft Dataverse","description":"DynamicsWebApi is a comprehensive helper library designed for interacting with the Microsoft Dataverse Web API, including Microsoft Dynamics 365 Customer Engagement and Power Pages. Currently stable at v2.4.0, it receives regular updates, typically with patch and minor releases addressing fixes and introducing new features every few weeks or months. Key differentiators include robust support for Microsoft Dataverse Search API v2.0 (query, suggest, autocomplete), automated batch request management, handling of large file uploads/downloads in chunks, and automated conversion of long URLs into batch requests. The library supports standard CRUD operations, Fetch XML queries, Actions, Functions, and intricate table definition (metadata) queries. It is compatible with both Node.js environments (v17+) and modern browsers, offering features like `AbortSignal` for request cancellation and proxy configuration. It explicitly notes its scope does *not* include Microsoft Dynamics 365 Finance and Operations. This package is ideal for developers building integrations or client-side applications that need to communicate with Dataverse reliably and efficiently.","status":"active","version":"2.4.0","language":"javascript","source_language":"en","source_url":"https://github.com/AleksandrRogov/DynamicsWebApi","tags":["javascript","dataverse","d365","dynamics-365","web-api","helper","crm","dynamics-crm","cds","typescript"],"install":[{"cmd":"npm install dynamics-web-api","lang":"bash","label":"npm"},{"cmd":"yarn add dynamics-web-api","lang":"bash","label":"yarn"},{"cmd":"pnpm add dynamics-web-api","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The library primarily uses ES Modules syntax. For older CommonJS environments, a dynamic import or transpilation is typically required.","wrong":"const DynamicsWebApi = require('dynamics-web-api');","symbol":"DynamicsWebApi","correct":"import { DynamicsWebApi } from 'dynamics-web-api';"},{"note":"Utility functions, such as those for handling URL formatting (e.g., related to the @odata.id fix in v2.4.0), are typically accessed as properties of an initialized DynamicsWebApi instance rather than direct named exports.","wrong":"import { Utility } from 'dynamics-web-api';","symbol":"Utility functions (via instance)","correct":"const dynamicsWebApi = new DynamicsWebApi(); dynamicsWebApi.Utility.someFunction();"},{"note":"TypeScript types are shipped with the package. Specific interfaces like `DynamicsWebApiOptions` or `WebApiRequest` are commonly imported for type hinting and enhanced development experience.","symbol":"Types","correct":"import type { DynamicsWebApiOptions, WebApiRequest } from 'dynamics-web-api';"}],"quickstart":{"code":"import { DynamicsWebApi } from 'dynamics-web-api';\n\n// This example is primarily for a browser context within Dynamics 365 (Web Resource).\n// If running in Node.js, you would need to configure `onTokenRefresh` to provide\n// an Authorization header, typically by acquiring a token from Azure AD.\n// Example for Node.js token setup:\n// const dynamicsWebApi = new DynamicsWebApi({\n//   url: 'https://yourorg.crm.dynamics.com/api/data/v9.2/',\n//   onTokenRefresh: async (callback) => {\n//     // Implement your AAD token acquisition logic here\n//     const token = await fetchAADToken();\n//     callback(token);\n//   }\n// });\n\n// For Dynamics 365 Web Resource usage:\n// By default, DynamicsWebApi makes calls to Web API v9.2.\n// No explicit URL or token refresh is typically needed if running inside Dynamics 365\n// as it leverages the existing authenticated context.\nconst dynamicsWebApi = new DynamicsWebApi();\n\nasync function executeWhoAmI() {\n  try {\n    console.log('Calling WhoAmI function...');\n    const response = await dynamicsWebApi.callFunction('WhoAmI');\n    console.log(`Successfully called WhoAmI. User ID: ${response.UserId}`);\n\n    // If Xrm object is available (e.g., in a Dynamics 365 form script),\n    // display an alert dialog.\n    if (typeof Xrm !== 'undefined' && Xrm.Navigation && Xrm.Navigation.openAlertDialog) {\n      Xrm.Navigation.openAlertDialog({ text: `Hello Dynamics 365! My ID is: ${response.UserId}` });\n    } else {\n      // Fallback for environments where Xrm is not present\n      alert(`Hello Dynamics 365! My ID is: ${response.UserId}`);\n    }\n  } catch (error: any) {\n    console.error('Error calling WhoAmI:', error.message || error);\n    // Optionally, show an alert in Dynamics 365 for errors\n    if (typeof Xrm !== 'undefined' && Xrm.Navigation && Xrm.Navigation.openAlertDialog) {\n        Xrm.Navigation.openAlertDialog({ text: `Error: ${error.message || 'Unknown error occurred.'}` });\n    } else {\n        alert(`Error: ${error.message || 'Unknown error occurred.'}`);\n    }\n  }\n}\n\nexecuteWhoAmI();\n","lang":"typescript","description":"This quickstart demonstrates how to initialize `DynamicsWebApi` and execute a basic `WhoAmI` function call to retrieve the current user's ID, showing both console output and an alert dialog in a Dynamics 365 Web Resource context."},"warnings":[{"fix":"If an absolute URL for `@odata.id` is explicitly required in a non-`/$ref` POST request body, use the new utility function (e.g., `dynamicsWebApi.Utility.getAbsoluteIdUrl()`) to construct it manually before making the request.","message":"In v2.4.0, the library no longer forces an absolute URL for `@odata.id` when present in the body of non-POST requests to `/$ref`. This behavior was previously applied broadly but was only intended for `POST` requests to `/$ref`. This change may be breaking if your application relied on the implicit absolute URL formatting of `@odata.id` in other request types (an undocumented usage).","severity":"breaking","affected_versions":">=2.4.0"},{"fix":"Upgrade your Node.js environment to v17 or newer to ensure continued compatibility and access to support and future updates.","message":"Official support for Node.js v16 has been dropped since v2.2.0. The library might not function correctly or receive guarantees for future compatibility on Node.js v16 environments due to changes in development and testing pipelines.","severity":"breaking","affected_versions":">=2.2.0"},{"fix":"Ensure your application is served over HTTPS when deploying DynamicsWebApi in a browser context. For older browsers, consider polyfills for `Crypto.randomUUID` or using an earlier version of the library if HTTPS is not feasible.","message":"Since v2.2.0, DynamicsWebApi utilizes the Crypto API's `randomUUID` function for UUID generation. When used in a browser environment, this change requires the library to run in a 'Secure Context' (HTTPS). Older browsers might also experience compatibility issues with this API.","severity":"gotcha","affected_versions":">=2.2.0"},{"fix":"Review the official documentation for Search API v2.0 and migrate to the new properties for `query`, `suggest`, and `autocomplete` functions to leverage full features and avoid potential future breaking changes.","message":"With the introduction of Search API v2.0 in v2.3.0, some previously used properties for search queries are now marked as deprecated. While they might still function, their use is discouraged in favor of the new v2.0 properties.","severity":"deprecated","affected_versions":">=2.3.0"},{"fix":"Replace `fieldName` with `property` in your request objects when performing file operations (e.g., `uploadFile({ property: 'my_file_field', ... })`).","message":"The `fieldName` property in request properties for `deleteRecord`, `uploadFile`, and `downloadFile` methods has been deprecated since v2.1.6. Developers should transition to using the `property` field instead.","severity":"deprecated","affected_versions":">=2.1.6"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"This issue was a bug fixed in v2.2.1. Upgrade to DynamicsWebApi v2.2.1 or newer to resolve this problem with batch requests.","cause":"Incorrect line endings in batch requests when the `inChangeSet` option was set to `false`, leading to malformed multipart requests.","error":"InnerException : System.ArgumentException: Stream was not readable"},{"fix":"This specific issue was addressed and fixed in DynamicsWebApi v2.1.5. Ensure you are using version v2.1.5 or a newer release to prevent this problem.","cause":"A bug existed where the authorization token was not correctly preserved and applied when a long URL request was automatically converted into a batch request, leading to authentication failures.","error":"Missing authorization token when request with a long URL is converted into a Batch request."}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":""}