๐Ÿ”ท Overview of Web API in Dynamics 365 CE

Dynamics 365 Web API provides a RESTful web service interface for interacting with data in Dynamics 365 CE using JavaScript or other languages.

  • Base URL Format:
https://<your-org>.crm.dynamics.com/api/data/v9.2/

๐Ÿ”ท Why Use JavaScript with Web API?

โœ… Works natively within Model-Driven Apps (forms, ribbons, commands)
โœ… Asynchronous and faster than older XrmServiceToolkit or SOAP
โœ… Enables client-side interactivity with business logic


๐Ÿ”ท Authentication

  • JavaScript running in forms/ribbons inside Dynamics is already authenticated.
  • If you use JS externally (e.g., React app), you must authenticate using OAuth 2.0 and MSAL.

๐Ÿ”ท Setup in Dynamics Form

  1. Go to Form Editor
  2. Add a new JavaScript web resource
  3. Register the function on events like OnLoad, OnChange, or OnSave

๐Ÿ”ท Basic CRUD Operations

All operations use Xrm.WebApi namespace.


๐Ÿ”น 1. Create Record

var account = {
    "name": "Contoso Ltd",
    "telephone1": "1234567890"
};

Xrm.WebApi.createRecord("account", account).then(
    function success(result) {
        console.log("Account created with ID: " + result.id);
    },
    function (error) {
        console.log("Error: " + error.message);
    }
);

๐Ÿ”น 2. Retrieve Record by ID

var accountId = "GUID";
Xrm.WebApi.retrieveRecord("account", accountId, "?$select=name,telephone1").then(
    function success(result) {
        console.log("Account Name: " + result.name);
    },
    function (error) {
        console.log("Error: " + error.message);
    }
);

๐Ÿ”น 3. Update Record

var accountId = "GUID";
var updatedFields = {
    "telephone1": "9876543210"
};

Xrm.WebApi.updateRecord("account", accountId, updatedFields).then(
    function success(result) {
        console.log("Record updated");
    },
    function (error) {
        console.log("Error: " + error.message);
    }
);

๐Ÿ”น 4. Delete Record

var accountId = "GUID";
Xrm.WebApi.deleteRecord("account", accountId).then(
    function success(result) {
        console.log("Record deleted");
    },
    function (error) {
        console.log("Error: " + error.message);
    }
);

๐Ÿ”ท Query with Filters (Fetch / OData)

Xrm.WebApi.retrieveMultipleRecords("contact", "?$select=fullname,emailaddress1&$filter=contains(fullname,'John')").then(
    function success(result) {
        result.entities.forEach(function (contact) {
            console.log(contact.fullname);
        });
    },
    function (error) {
        console.log(error.message);
    }
);

๐Ÿ”ท Associate/Disassociate Records

Associate Contact with Account:

Xrm.WebApi.associateRecord("contact", "CONTACT_ID", "account_primary_contact", "account", "ACCOUNT_ID").then(
    function success(result) {
        console.log("Associated successfully");
    },
    function (error) {
        console.log("Error: " + error.message);
    }
);

Disassociate:

Xrm.WebApi.disassociateRecord("contact", "CONTACT_ID", "account_primary_contact", "account", "ACCOUNT_ID").then(
    function success(result) {
        console.log("Disassociated");
    },
    function (error) {
        console.log("Error: " + error.message);
    }
);

๐Ÿ”ท Execute Custom Actions

var parameters = {
    "InputParameter": "Hello"
};

Xrm.WebApi.executeCustomAction("new_CustomActionName", parameters).then(
    function success(result) {
        if (result.ok) {
            result.json().then(function (data) {
                console.log(data.OutputParameter);
            });
        }
    },
    function (error) {
        console.log("Error: " + error.message);
    }
);

๐Ÿ”ท Execute Functions (Bound or Unbound)

Xrm.WebApi.online.execute({
    entityName: "account",
    entityId: "GUID",
    functionName: "Microsoft.Dynamics.CRM.RetrievePrincipalAccess",
    getMetadata: function () {
        return {
            boundParameter: "entity",
            operationType: 0,
            operationName: "RetrievePrincipalAccess",
            parameterTypes: {}
        };
    }
}).then(function success(response) {
    response.json().then(console.log);
});

๐Ÿ”ท Error Handling

Use .catch or function (error) {} callbacks.
Inspect error.message or error.details.


๐Ÿ”ท Best Practices

โœ… Use async/await when possible
โœ… Always check for nulls
โœ… Use $select and $filter to limit data
โœ… Avoid synchronous code
โœ… Log errors using console.log() or show notifications using Xrm.Navigation.openAlertDialog


๐Ÿ”ท Bonus: Utility Methods

Show Notification:

Xrm.Page.ui.setFormNotification("This is a notification", "INFO", "notifId");

Get Current User:

var userId = Xrm.Utility.getGlobalContext().userSettings.userId;

Open Entity Form:

Xrm.Navigation.openForm({
    entityName: "account",
    entityId: "GUID"
});

๐Ÿ”ท Sample Use Case: Auto-populate Fields

function setParentAccount(executionContext) {
    var formContext = executionContext.getFormContext();
    var contactId = formContext.data.entity.getId();

    Xrm.WebApi.retrieveRecord("contact", contactId, "?$select=parentcustomerid_account").then(
        function success(result) {
            if (result.parentcustomerid_account) {
                formContext.getAttribute("description").setValue("Parent: " + result.parentcustomerid_account.name);
            }
        }
    );
}

Leave a comment

Copyright ยฉ 2025 Dynamics Services Group