In MS CRM 2016, Web API introduced to perform operations on MS CRM using JavaScript. 
You can use web API in HTML web resources, form scripts or in ribbon commands. 
Web API uses JSON to send and receive data from CRM. 

When you are using Web API within CRM application, then we don't need to authenticate. but if using web API outside of CRM, then you need to authenticate. 

With On-premise deployments, you can use user's network credentials to authenticate CRM web API. 

For Online or internet facing deployments (IFD), you must use OAuth for Authentication. 

For more details about authenticate to MS CRM with Web API, check 
https://msdn.microsoft.com/en-us/library/mt595798.aspx


Web API Operations 

1. Retrieve Single record
     - When retrieving single record  using Web API, you must need record ID. 
     - You can specify list of attributes you want to retrieve from that entity, as  $select=accountrolecode,fullname,gendercode
     - With request you can specify this data retrieval you want synchronous or Asynchronous, as well as you can specify do you want formatted values to be retrieved or not. 

Formatted values - mainly used for option sets, entity reference, status reason, state code etc, When getting formatted values, you will get Text values also. 

e.g. StateCode =0 and Formatted State Code = Active
  
Using XMLHttpRequest


var contactId = Xrm.Page.data.entity.getId();
var req = new XMLHttpRequest();
req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v8.1/contacts("+contactId +")?$select=accountrolecode,fullname,gendercode", true);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function() {
    if (this.readyState === 4) {
        req.onreadystatechange = null;
        if (this.status === 200) {
            var result = JSON.parse(this.response);
            var accountrolecode = result["accountrolecode"];
            var fullname = result["fullname"];
            var gendercode = result["gendercode"];
        }
        else {
            alert(this.statusText);
        }
    }
};
req.send();

When XMLHttpRequest open, at that time we can specify, how to retrieve data - synchronous or Asynchronous
req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v8.0/contacts(B2DF0F4F-737A-E611-80DB-C4346BAC4B78)?$select=accountrolecode,fullname,gendercode"true);

If it is True, then Asynchronous request, and when false then synchronous request. 

Also if you want formatted values to be included, then you need to set request header
req.setRequestHeader("Prefer", "odata.include-annotations=\"OData.Community.Display.V1.FormattedValue\"");

and to get value of formatted attribute 
var gendercode_formatted = result["gendercode@OData.Community.Display.V1.FormattedValue"];

Using Jquery 
When using Jquery, you need to add Jquery libraries in form librarians. 


var contactId = Xrm.Page.data.entity.getId();
$.ajax({
    type: "GET",
    contentType: "application/json; charset=utf-8",
    datatype: "json",
    url: Xrm.Page.context.getClientUrl() + "/api/data/v8.1/contacts("+contactId+")?$select=accountrolecode,fullname,gendercode",
    beforeSend: function (XMLHttpRequest) {
        XMLHttpRequest.setRequestHeader("OData-MaxVersion", "4.0");
        XMLHttpRequest.setRequestHeader("OData-Version", "4.0");
        XMLHttpRequest.setRequestHeader("Accept", "application/json");
        XMLHttpRequest.setRequestHeader("Prefer", "odata.include-annotations=\"OData.Community.Display.V1.FormattedValue\"");
    },
    async: false,
    success: function (data, textStatus, xhr) {
        var result = data;
        var accountrolecode = result["accountrolecode"];
        var accountrolecode_formatted = result["accountrolecode@OData.Community.Display.V1.FormattedValue"];
        var fullname = result["fullname"];
        var gendercode = result["gendercode"];
        var gendercode_formatted = result["gendercode@OData.Community.Display.V1.FormattedValue"];
    },
    error: function (xhr, textStatus, errorThrown) {
        alert(textStatus + " " + errorThrown);
    }
});


2. Retrieve Multiple records

When retrieving multiple records, request will be more similar to single record request.
When retrieving multiple records, we need to specify filter criteria using $filter=

function retireveAllChildContacts() {
    var parentAccountId = Xrm.Page.getAttribute('parentcustomerid').getValue();
    var req = new XMLHttpRequest();
    req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v8.0/contacts?$select=accountrolecode,firstname,fullname,gendercode,lastname,middlename,_ownerid_value&$filter=_accountid_value eq " + parentAccountId + "", false);
    req.setRequestHeader("OData-MaxVersion", "4.0");
    req.setRequestHeader("OData-Version", "4.0");
    req.setRequestHeader("Accept", "application/json");
    req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
    req.setRequestHeader("Prefer", "odata.include-annotations=\"OData.Community.Display.V1.FormattedValue\"");
    req.setRequestHeader("Prefer", "odata.maxpagesize=10");
    req.onreadystatechange = function () {
        if (this.readyState === 4) {
            req.onreadystatechange = null;
            if (this.status === 200) {
                var results = JSON.parse(this.response);
                for (var i = 0; i < results.value.length; i++) {
                    var accountrolecode = results.value[i]["accountrolecode"];
                    var accountrolecode_formatted = results.value[i]["accountrolecode@OData.Community.Display.V1.FormattedValue"];
                    var firstname = results.value[i]["firstname"];
                    var fullname = results.value[i]["fullname"];
                    var gendercode = results.value[i]["gendercode"];
                    var gendercode_formatted = results.value[i]["gendercode@OData.Community.Display.V1.FormattedValue"];
                    var lastname = results.value[i]["lastname"];
                    var middlename = results.value[i]["middlename"];
                    var _ownerid_value = results.value[i]["_ownerid_value"];
                    var _ownerid_value_formatted = results.value[i]["_ownerid_value@OData.Community.Display.V1.FormattedValue"];
                }
            }
            else {
                alert(this.statusText);
            }
        }
    };
    req.send();
}

With multiple record request if want to retrieve count also, then you can specify count in request as 
req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v8.0/contacts?$select=accountrolecode&$filter=_accountid_value eq 95A043CF-0CAF-E511-80EC-0050568C6C1C&$count=true", false);

you will get count after request successful
var recordCount = results["@odata.count"];


With API you can impersonate request, You can specify user Id when sending request. Retrieval operation will be performed  based on user security permission. 
If impersonated user does not exists in CRM or not enabled, then request will through error. 

To impersonate request, you need to add request header as 
req.setRequestHeader("MSCRMCallerID", "0EB938AA-7395-E611-80DF-C4346BAD17C4");