|
Voiced by Amazon Polly |
Overview
Modern Dynamics 365 and Power Apps applications rely heavily on real‑time interactions, automation, and custom business logic. While low‑code tools like Power Automate and business rules cover many scenarios, advanced implementations often require direct programmatic access to Dataverse data, especially when you need fast, synchronous, UI‑driven operations. The Dataverse Web API provides a RESTful, OData v4–compliant interface that enables secure Create, Read, Update, and Delete (CRUD) operations from JavaScript within model‑driven apps.
When JavaScript runs inside a model‑driven app (form scripts, ribbon commands, HTML web resources, PCF), the platform handles authentication for you. You can call the Web API securely without implementing token acquisition, a major productivity win for client‑side customization.
Pioneers in Cloud Consulting & Migration Services
- Reduced infrastructural costs
- Accelerated application deployment
Why JavaScript + Web API inside model‑driven apps?
- Authentication is handled by the platform; use Xrm.Utility.getGlobalContext().getClientUrl() to resolve the base org URL.
- The Xrm.WebApi namespace exposes first‑class helpers for CRUD, queries, and actions, while raw fetch gives you fine‑grained control.
- OData v4 query options ($select, $filter, $expand, $orderby, $top) keep payloads small and responses fast.
Architecture in a nutshell
- Endpoint: https://<org>.crm.dynamics.com/api/data/v9.2/ (service root).
- Service document lists entity sets; confirm plural names before calling.
- In‑app scripts piggyback on the user’s session; outside the app, you must attach Azure AD tokens (not covered here).
READ: Querying data with OData
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
async function getTopAccounts() { const base = Xrm.Utility.getGlobalContext().getClientUrl(); const url = `${base}/api/data/v9.2/accounts?$select=name,accountnumber&$top=10`; const res = await fetch(url, { headers: { "Accept": "application/json", "OData-Version": "4.0", "OData-MaxVersion": "4.0" } }); if (!res.ok) throw new Error(await res.text()); const data = await res.json(); return data.value; } |
Use $select to limit columns, $filter for server‑side filtering, $orderby for sorting, and $expand to bring related rows in a single call.
CREATE: POST rows
|
1 2 3 4 5 6 7 8 9 10 11 12 |
async function createAccount(name, phone) { const base = Xrm.Utility.getGlobalContext().getClientUrl(); const url = `${base}/api/data/v9.2/accounts`; const body = { name, telephone1: phone }; const res = await fetch(url, { method: "POST", headers: { "Accept": "application/json", "Content-Type": "application/json" }, body: JSON.stringify(body) }); if (res.status !== 204) throw new Error(await res.text()); return res.headers.get("OData-EntityId"); } |
UPDATE: PATCH changed fields
|
1 2 3 4 5 6 7 8 9 10 |
async function updateAccount(id, updates) { const base = Xrm.Utility.getGlobalContext().getClientUrl(); const url = `${base}/api/data/v9.2/accounts(${id})`; const res = await fetch(url, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify(updates) }); if (!res.ok) throw new Error(await res.text()); } |
DELETE: Remove rows
|
1 2 3 4 5 6 |
async function deleteAccount(id) { const base = Xrm.Utility.getGlobalContext().getClientUrl(); const url = `${base}/api/data/v9.2/accounts(${id})`; const res = await fetch(url, { method: "DELETE" }); if (!res.ok) throw new Error(await res.text()); } |
Relationships: lookups with @odata.bind
|
1 2 3 4 |
const updates = { "parentcustomerid_account@odata.bind": "/accounts(ce9eaaef-f718-ed11-b83e-00224837179f)" }; // PATCH /contacts(<contactId>) with updates above |
Batch, functions & actions
- Use $batch to combine up to 1000 requests; wrap writes in a change set to ensure all‑or‑
- Execute bound/unbound functions and actions via Xrm.WebApi.execute/executeMultiple for non‑CRUD platform messages.
Security & performance best practices
- Rely on Dataverse security roles, client code cannot elevate privileges.
- Prefer Xrm.WebApi for supportability; fall back to fetch when you need low‑level control (e.g., hand‑crafted $batch).
- Minimize payloads with $select and server‑side filters; paginate when necessary.
- Add error handling (check response.ok, log response text).
Practical scenario: instant enrichment on Opportunity
On a change of parent account, call the Web API with $select/$expand to pull key account attributes (credit status, SLA), and set the Opportunity fields immediately before save. Sellers see accurate data, BPF branches evaluate correctly, and you skip the latency of after‑save flows.
Conclusion
Secure, high‑performance client‑side development in model‑driven apps is best achieved through the Dataverse Web API. By leveraging platform‑handled authentication, rich OData querying, and the Xrm.WebApi helpers, developers can implement fast, synchronous CRUD operations directly from JavaScript without external dependencies.
In short, JavaScript + Dataverse Web API empowers you to build smarter, reactive model‑driven apps that enhance user experience while staying fully aligned with platform standards.
Drop a query if you have any questions regarding CRUD and we will get back to you quickly.
Empowering organizations to become ‘data driven’ enterprises with our Cloud experts.
- Reduced infrastructure costs
- Timely data-driven decisions
About CloudThat
CloudThat is an award-winning company and the first in India to offer cloud training and consulting services worldwide. As a Microsoft Solutions Partner, AWS Advanced Tier Training Partner, and Google Cloud Platform Partner, CloudThat has empowered over 850,000 professionals through 600+ cloud certifications winning global recognition for its training excellence including 20 MCT Trainers in Microsoft’s Global Top 100 and an impressive 12 awards in the last 8 years. CloudThat specializes in Cloud Migration, Data Platforms, DevOps, IoT, and cutting-edge technologies like Gen AI & AI/ML. It has delivered over 500 consulting projects for 250+ organizations in 30+ countries as it continues to empower professionals and enterprises to thrive in the digital-first world.
FAQs
1. Do I need to handle OAuth tokens in scripts inside model‑driven apps?
ANS: – No. In‑app JavaScript uses the existing user session. Outside the app (e.g., a standalone SPA), you must obtain and attach Azure AD tokens.
2. Should I use Xrm.WebApi or raw fetch?
ANS: – Use Xrm.WebApi for CRUD and common operations. Use fetch when you need custom control over headers or multipart $batch payloads.
3. How do I associate records via Web API?
ANS: – For single‑valued lookups, PATCH with navigationproperty@odata.bind. For collection‑valued (N:N), use $ref endpoints.
WRITTEN BY Kavitha Mandala
Kavitha Mandala works as a Dynamics Developer and is a passionate Dynamics Developer. She is a tech enthusiast with a love for innovation and learning. Adventure seeker, always exploring new horizons. Driven by curiosity and a zeal for challenges.
Login

March 18, 2026
PREV
Comments